Botkitから外部のAPIをリクエストする方法

こんにちは!ぐちです。

先日ご紹介しました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リクエストができるようになりました。

では今回はこの辺で。