こんにちは!ぐちです。
先日ご紹介しましたSlackにBotを簡単に作れるBotkitですが、簡単にできるだろうと思っていたのですが、あれ?となったことがあったので簡単にご紹介します!
BotkitはJavascript
BotkitはJavascriptで作られているので、カスタマイズももちろんJavascriptのコードを追加していくことになるのですが、普段何気なく書いているノリで書いてしまうと、Not findエラーが出まくります。
僕もおかしいなーと思いつつ調べてみるとめちゃくちゃ簡単な理由でした。
XMLHttpRequest
オブジェクトはブラウザ標準
このままなんです。笑
外部サーバーにあるWebAPIにリクエストを投げようとXMLHttpRequest
を使おうとしたのですが、Not findエラーが出まくって、なんでやねーんとなったのですが、調べるとブラウザの標準オブジェクトとのこと。。。そりゃ使えないですよね。。。BotkitはHTML上ではなく、ピュアJSとしてコマンドラインにて動作しています。
そこで調べてみると、さすが!!先日たちは偉人です。笑
Githubに標準のXMLHttpRequestのラッパーを公開されている方がいらっしゃいました。まじで感謝!!!
https://github.com/driverdan/node-XMLHttpRequest
読み込み
上記のREADME.mdにはインポート方法が下記のように書かれていますが、私の環境?では動かなかったので、変更しています。
XMLHttpRequest.jsは対象のslack_bot.jsと同階層に配置しています。
- 変更前
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; var xhr = new XMLHttpRequest();
-
変更後
var XMLHttpRequest = require('./XMLHttpRequest.js').XMLHttpRequest; var xhr = new XMLHttpRequest();
これで無事にXMLHttpRequest
のエラーも解決しましたので、コード全体を載せておきます。今回はPOSTリクエスト版ですが、GETリクエストもほとんど変わりません。
POSTリクエスト
function requestApi(endpoint, data, callback) { var xhr = new XMLHttpRequest(); // Http通信のオブジェクトを作成します xhr.onreadystatechange = function(){ // 通信の状態が変更するたびにコールされます。 var READYSTATE_COMPLETED = 4; var HTTP_STATUS_OK = 200; if(this.readyState == READYSTATE_COMPLETED && this.status == HTTP_STATUS_OK) { // 本来は他の状態も細かく処理するのが適切かも。。 callback(this.responseText); // 引数で受け取ったコールバック関数を呼び出します。 } }; xhr.responseType = 'json'; // APIのレスポンスをjson形式で受け取ります。 xhr.open('POST', endpoint, true); // コネクションを開きます。 xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' ); // POST通信の場合は指定必須です。GETはなくてもOK。 xhr.send(encodeHtmlForm(data)); // パラメータをHtmlForm形式に変換する必要があるそうです。。 }
送信するパラメータをHtmlFormに変換するコードは下記の通りです。
function encodeHtmlForm(data) { var params = []; for(var name in data) { var value = data[name]; var param = encodeURIComponent(name) + '=' + encodeURIComponent(value); params.push(param); } return params.join('&').replace(/%20/g, '+'); }
この時にひとつ注意点があるようで、僕もハマりました。。。
POST通信するために指定する必要があった「application/x-www-form-urlencoded」では、半角スペースが「+」でないといけないそうです。上記コードではエンコード結果の「%20」を「+」に修正しています。
そして最後に呼び出し方法ですが、下記の通りです。
var data = {hoge: '1'}; requestApi("http://hogehoge.com/request/", data, function(response){ console.log(response); });
これで無事にBotkitから外部へのAPIリクエストができるようになりました。
では今回はこの辺で。