こんにちは!ぐちです。
先日ご紹介しました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リクエストができるようになりました。
では今回はこの辺で。