curl コマンドと kintone.proxy() の対応

目次

caution
警告

2020 年 8 月改訂のセキュアコーディングガイドライン に抵触する内容が含まれています。認証情報が漏洩した場合の影響を考慮して慎重に検討してください。
該当箇所:JavaScript プログラムの 7 行目。

はじめに

Web サービスのいち機能として提供されることが当たり前になってきた Web-API ですが、これを kintone でマッシュアップしたいと思った時に役立つ豆知識をひとつ紹介します。

ドキュメントで API へのアクセス方法としてサンプルでよく使われる curl コマンドと、kintone JavaScript カスタマイズで外部の API へアクセスできる kintone.proxy() の対応関係を整理します。
さらにサンプルを通して kintone.proxy() による外部 Web サービスとの連携方法について理解を深めたいと思います。

なお、kintone.proxy() に関する内容は現時点で確認したもので、今後拡張・変更されることがあるかもしれませんので、ご注意ください。

curl コマンドと kintone.proxy() の対応関係

API ドキュメントのページで curl コマンドの例が与えられたときに、kintone.proxy() でどのように読み替えたらよいか、対応関係をまとめたいと思います。

curlコマンド
(オプションと値)
kintone.proxy(url, method, headers, data, callback, errback)
リクエスト URL http://xxx.xxx.xxx 記載箇所:第1引数 url
記載例:'http://xxx.xxx.xxx'
リクエストメソッド -X {method} 記載箇所:第2引数 method
記載例:'{method}'
リクエストヘッダー -H "{headerKey}:{headerValue}" 記載箇所:第3引数 headers
記載例:{"{headerKey}":"{headerValue}"}
リクエストデータ(フォーム形式) -d "{key}={value}" 記載箇所:第4引数 date
記載例:' "{key}={value}" '
リクエストデータ(JSON形式) -d 'JSON文字列' 記載箇所:第4引数 date
記載例:'JSON文字列'もしくはJSONオブジェクト
Basic 認証 -u "{id}:{password}" 記載箇所:第3引数 headers
記載例:'{"Authorization" : "Basic {basicToken}"}'

各項目の補足説明は次のとおりです。

リクエスト URL

  • curl コマンドでは正味の引数になりますので、コマンドオプションはありません。

リクエストメソッド

  • GET POST PUT DELETE のいずれかを指定できます。

リクエストヘッダー

  • 複数指定する必要があるときには、curl コマンドでは -H "{headerKey}:{headerValue}" をセットとして、必要数書き並べられます。kintone.proxy() では 「{"{headerKey1}":"{headerValue1}", "{headerKey2}":"{headerValue2}", ・・・}」 といったようにカンマで必要数を連結してください。

リクエストデータ(フォーム形式)

  • curl コマンドで -d のオプションでは通常フォーム形式データです。対応する Content-Type は application/x-www-form-urlencoded として処理されています(-H での明示不要)ので、kintone.proxy() ではこれをヘッダーに追加しておくとよいです。
  • 複数指定する必要があるときには、curl コマンドでは -d {key}:{value} をセットとして、必要数書き並べられます。kintone.proxy() では、'{key1}={value1}&{key2}={value2}&・・・' といったように & で必要数連結してください。
  • curl コマンドでは {value} 部分を URL エンコード化する --data-urlencode というオプションが使われます。これに対応するためには kintone.proxy()では、JavaScript 中で encodeURIComponent({value}) を経由させておくとよいです。

リクエストデータ(JSON 形式)

  • curl コマンドで -d のオプションは JSON 形式のデータにも対応しています。ただ、先ほどのフォーム形式と異なり、対応する Content-Type の application/json は curl コマンドでも -H によって明示されることになります。一方、kintone.proxy() でもこれをヘッダーに追加しておく必要があります。
  • curl コマンドでは「JSON 文字列」でしか指定のしようがありませんが、kintone.proxy() では、「JSON 文字列」でも「JSON オブジェクト」でも大丈夫です。

Basic 認証

  • curl コマンドで -u のオプションは Basic 認証に用いられています。これを kintone.proxy() で対応させるには、ヘッダーの方に "Authorization":"Basic {BasicToken}" と追加してあげることで解決されます。なお、{BasicToken}{id}:{password} を BASE64 エンコードしたものとなります(kintone REST API と同じですね)

さて、予備知識を確認したところで、実践に移っていきたいと思います。kintone に触れられている方なら JSON 形式データの取扱には慣れているかと思いますので、今回は用例も少ないフォーム形式データの例をお届けしたいと思います。

連携サンプル(Twilio /電話:フォーム形式データ)

kintone API をはじめとして、フォーム形式データの API を提供しているサービスはいくつかあります。次はその一例です(著者自身で kintone.proxy() からのアクセスをそれぞれ確認しました)。

今回はその中から「Twilio」の「電話(Call)」を例に進めていきたいと思います。

kintone アプリとしては、kintone に登録された電話番号とメッセージをもとに Twilio API 経由で音声通知するというものになります。

Twilio にはトライアルアカウントもありますので、実際に Twilio で試してみたいという方は次のページでアカウントを取得できます。
Try Twilio Free (External link) を参考にされるとよいかと思います。

API ドキュメント(Twilio)で示される curl コマンドによる API リクエスト例

(「 https://www.twilio.com/en-us/voice/api (External link) 」より)

トライアルアカウント作成後にもこれと同じようなページが出現しますが、この情報を参考に、kintone アプリとカスタマイズ用の JavaScript を準備していきましょう。

認証情報

パラメーター
説明
{AccountSid}
アカウント取得時に与えられるID
{AuthToken}
アカウント取得時に与えられるパスワード

リクエストデータ

パラメーター
説明
To='{To}'
{To}は宛先番号。「+819012345678」のようにハイフンなしの国際電話表記
From='{From}'
{To}は宛先番号(アカウント取得後指定される)。「+819012345678」のようにハイフンなしの国際電話表記
Url='{twiMlUrl}'
{twiMlUrl}は、TwiML(TwilioのXML)をホストしているURL。Twimletsを利用することで、動的に設定可能

詳しい Twilio API のドキュメントは Twilio Doc (External link) を確認してください。

kintoneアプリの準備

次のフィールドを含むアプリをご準備ください。

フィールド名(例)
フィールドコード
フィールドタイプ
宛先番号
To
リンク(電話番号)もしくは、文字列1行
メッセージ
Body
文字列複数行

JavaScriptソースコード

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*
 * Twilio x kintone
 * Copyright (c) 2014 Cybozu
 *
 * Licensed under the MIT License
 * https://opensource.org/license/mit/
 */
(function() {

  'use strict';

  // パラメータの初期化
  const ACCOUNT_SID = '{AccountSid}';
  const BASIC_TOKEN = '「{AccountSid}:{AuthToken}」をBASE64エンコードしたもの';
  const FROM = '{(アカウント取得後指定される)発信番号}';

  // kintoneに登録されたメッセージを電話発信する関数
  function dial(event) {
    // レコード情報を取得
    const rec = event.record;
    // 必要なTwiML(TwilioのXML)を記述
    const twiMl = '<Response><Say voice="woman" language="ja-jp">' + rec.Body.value + '</Say></Response>';
    // 上のTwiMLのアクセスヘージURLを与えてくれるTwimletsを利用
    const twiMlUrl = 'http://twimlets.com/echo?Twiml=' + encodeURIComponent(twiMl);
    // Twilio API(Call)のリクエストURL
    const url = 'https://api.twilio.com/2010-04-01/Accounts/' + ACCOUNT_SID + '/Calls.json';
    // リクエストヘッダ
    const headers = {
      'Content-Type': 'application/x-www-form-urlencoded',
      Authorization: 'Basic ' + BASIC_TOKEN
    };
    // リクエストデータ
    const contents = 'From=' + encodeURIComponent(FROM) +
                             '&To=' + encodeURIComponent(rec.To.value) +
                             '&Url=' + encodeURIComponent(twiMlUrl);
    // kintone.proxy()による外部APIアクセス
    kintone.proxy(url, 'POST', headers, contents, (body, status, _headers) => {
      console.log(status, body);
      if (status === 201) {
        alert('電話をかけました!');
      } else {
        alert('発信出来ませんでした!');
      }
    });
    return event;
  }

  // レコード詳細画面に電話発信用のダイヤルボタンを追加
  kintone.events.on('app.record.detail.show', (event) =>{
    const check = document.getElementsByName('dial');
    if (check.length === 0) {
      const button = document.createElement('button');
      button.appendChild(document.createTextNode('ダイヤル'));
      button.setAttribute('name', 'dial');

      const span = document.createElement('span');
      span.appendChild(button);

      const elButtonSpace = kintone.app.record.getHeaderMenuSpaceElement();
      elButtonSpace.appendChild(span);

      button.addEventListener('click', () => {
        dial(event);
      });
    }
    return event;
  });
})();

動作確認

「ダイヤル」ボタンを押して、「電話をかけました!」とメッセージが出れば発信成功です。そして、宛先の電話で着信するとメッセージが流れます。
トライアルでは、登録した番号のみへ発信可能で、案内メッセージが流れます。

注意事項

今回の kintone アプリ周辺の注意点は次のとおりです。

  • 筆者は macOS の Google Chrome で kintone アプリの動作確認を行いました。cybozu.com の対応 Web ブラウザーは 動作環境 (External link) を参照してください。
  • JavaScript 中に認証情報を含んでいますので、必要に応じて都度入力にしたり、アクセス権を制限する等設定してください。
  • 冒頭でも述べましたとおり、kintone.proxy() に関する内容は現時点で確認したもので、今後拡張・変更になることがあるかもしれませんので、ご注意ください。
  • 今回例に挙げた Twilio API の取扱いを含め、サンプルの利用に際しては自己責任でお願いします。

おわりに

今回は、外部サービスで提供される API を kintone.proxy()でアクセスするための豆知識として curl コマンドとの対応関係について触れ、サンプルを紹介しました。

kintone.proxy() は、今回のサンプルのように組み合わせ次第では本来サーバーを必要となるような開発がサーバーレスでできてしまう優れ機能です。
この機能を使った事例は 「kintone Café 東京 Vol.1」発表レポート (External link) で紹介されました。( 資料 (External link)

外部サービスとの API 連携が必要になった際には kintone と kintone.proxy() でのマッシュアップを検討されてはいかがでしょうか?

information

この Tips は、2014 年 9 月版 kintone で動作を確認しています。