休日にBluemixでLINEのBOTを作って遊んでたのですが、固定IP関連でつまづいたので備忘録的に投稿します。
BOT自体の実装はほぼこちらのコピペなので割愛します。
リンク先の記事ではHerokuを使ってます。
そもそも何で固定IPが必要か
LINE BOT作成時にはLINE側のコンソールでどこからのアクセスなら許可するかIPアドレスで指定する必要があります。
知らないサーバから勝手にアクセスされると困りますからね。
LINE BOTに限らず、GoogleのAPIや、確かDropboxあたりも開発用のコンソールで固定IPでどこからアクセスするか予め指定しておく必要があります。
PaaSゆえのめんどくささ
AWSのEC2とかなら簡単にサーバに固定IPを付与できるのですが、BluemixやHerokuではそうはいきません。
Herokuに関しては上記リンク先を参照いただくとして、
Bluemixでは単純に固定IPを付与することはできません(Dockerのコンテナを使えばいけるそうですが、あまり調べられていません)。
この記事にIPの調べ方が記載されていますが、Bluemixで作成したアプリのIPはデプロイの度に変わるので、少なくとも開発段階では現実的とは言えないでしょう。
Staticaを使う
そこで、Bluemixから利用できるStaticaというサービスを使って擬似的に固定IPを付与します。
予め断っておくと、厳密には固定IPを付与しているのではなく、IP固定のサーバを別に用意して、Bluemixからそこをプロキシして外部にアクセスするようにするというイメージです。
使い始めるにはダッシュボードから「サービスまたは APIの追加」を選択すると、利用可能なサービスの一覧が出ますので、その中からStaticaを探して選択するだけです。
Starterプランですと250リクエスト/月かつ帯域100MBまでなら無料です。
個人で趣味で利用する分には問題ないかと思います。
準備が完了するとダッシュボードにStaticaの情報が追加されます。
サイドバーに「サービス」->[Statica]の表示が出ますのでそこからStaticaのダッシュボードを見れます。
「Your Static IPs are XX.XX.XX.XX & YY.YY.YY.YY」と書かれているので、それをコピーしてLINEなりGoogleなりの開発用のコンソールに貼り付けましょう。
LINEに関してはCIDR記法でサブネットマスクを記述する必要がありますが、24で大丈夫そうです。
ex.)52.0.214.38/24
アプリからアクセスする
最後に、アプリからAPIにアクセスする際にStaticaを経由する方法ですが、前述の通り環境変数に入っているのでそれを使います。
LINEのAPIにアクセスするならこんな感じかと
だいぶ端折ってるのでこのままコピペするのは勘弁してください。
var request = require('request'); //requestモジュールを使用
//ヘッダーを定義
var headers = {
    "Content-Type" : 'application/json; charset=UTF-8',
    "X-Line-ChannelID" : channelID,
    "X-Line-ChannelSecret" : channelSecret,
    "X-Line-Trusted-User-With-ACL" : MID
};
var vcap_services = JSON.parse(process.env.VCAP_SERVICES);  //Bluemixのサービス関係の環境変数を取得
var proxyURL = vcap_services['statica'][0].credentials.STATICA_URL; //Staticaの固定アドレスを取得
var data = {
    "to": [to_address],
    "toChannel": 1383378250, //固定
    "eventType":'140177271400161403', //固定
    "content": {
        "messageNotified": 0,
        "messages": []
    }
};
var options = {
    url: 'https://trialbot-api.line.me/v1/events',
    proxy: proxyURL, //Staticaのアドレスをプロキシに設定する
    headers: headers,
    json: true,
    body: data
};
request.post(options, function(error, response, body){
    if (!error && response.statusCode == 200) {
        console.log('success');
    } else {
        console.log('error: '+ JSON.stringify(response));
    }
});
しかしBluemixで便利ですね。
gitのリポジトリにプッシュしたら勝手にデプロイしてくれるところまでこんなに簡単に設定できるだなんて。

