(今回のエントリはこの続編的な内容になっています)
LINE Bot を IBM Bluemix で作る


IBM Bluemix のサードパーティ製サービスの中に "Statica" というものがあります:
2016041400


このサービスはサーバー間プロクシーを実現するものです。Bluemix 上のランタイムから Bluemix 内外の API を呼び出す際の、リクエスト元 IP アドレスを隠して固定の IP アドレスにすることができるようになります。

例えば Bluemix 上のランタイム IP アドレスをリクエスト先サーバーのホワイトリストにあらかじめ登録しておかないと利用できないような API がある場合、Bluemix ランタイムの IP アドレスは再ステージ毎に変わってしまい、かつ変わった後の IP アドレスを調べるのが面倒でした(参照)。そんな場合にこのサービスを使うことでランタイムサーバーの IP アドレスが固定化されているかのように振る舞うことができるようになります。

実はこのサービスを使うと、LINE Bot API を作る際に非常に便利です。このページで紹介したように LINE Bot API でもコール元の IP アドレスをホワイトリスト登録しておく必要があって非常に面倒だったのですが、この Statica サービスを併用することで解決でき、再ステージング毎のホワイトリスト更新が不要になります。

なお、Statica は有償のサービスですが、IBM Bluemix の Starter プランを選択することで月 250 リクエスト&帯域 100MB までは無料でお使いいただくことが可能です。お試しになる場合はこちらをご利用ください:
2016041406


実際に LINE Bot API で試してみた様子がこちらです。まず Statica サービスをランタイムに追加しました。サービスの「資格情報の表示」をクリックしてクレデンシャル情報を確認します:
2016041401


このような画面が表示されます。モザイクのかかっている "STATICA_URL" の値がプロクシー URL です。この値をメモリしておくか、または実行時に動的に取り出して使うようにします:
2016041402


Statica サービスをクリックすると、作成した Statica サービスインスタンスの管理ダッシュボード画面にアクセスするためのリンクが現れます。これをクリックしてダッシュボードを開きます:
2016041403


Statica のダッシュボード画面が表示されました。この画面内の "Your Static IPs are X.X.X.X and Y.Y.Y.Y" と書かれている部分の X.X.X.X と Y.Y.Y.Y が固定に見せかける IP アドレスです:
2016041404


この2つの IP アドレスを LINE developers サイトのホワイトリストに登録します:
2016041405


後は実際にコールバック API を実行する際に、この Statica サービスインスタンスをプロクシーとして利用すればいいだけです。例えばこのようなコードにしました。変更前と異なる部分を赤く記しておきます:
<?php

$json_string = file_get_contents( 'php://input' );
$jsonObj = json_decode( $json_string );
$results = $jsonObj->{"result"};
$cnt = count($results);
for( $i = 0; $i < $cnt; $i ++ ){
  $result = $results[$i];
  $to = $result->{"content"}->{"from"};


  $cur = "USDJPY";
  $_cur = $result->{"content"}->{"text"};
  if( $_cur ){
    $cur = $_cur;
  }
  $cur = strtoupper( $cur );

  $fx_url = "http://fx.mybluemix.net/";
  $text = file_get_contents( $fx_url );
  $json = json_decode( $text );
  $datetime = $json->datetime;
  
  $rate = $json->rate;
  $r = "(" . $datetime . ")" . $cur . ":" . $rate->{$cur};

  $response_format_text = ['contentType'=>1,"toType"=>1,"text"=>$r];
  $post_data = ["to"=>[$to],"toChannel"=>"1383378250","eventType"=>"138311608800106203","content"=>$response_format_text];


  //. statica をチェック
  $proxy_url = '';
  $proxy_auth = '';
  if( getenv( 'VCAP_SERVICES' ) ){
    $vcap = json_decode( getenv( 'VCAP_SERVICES' ), true );
  
    $credentials1 = $vcap['statica'][0]['credentials'];
    if( $credentials1 != NULL ){
      $statica_url = $credentials1['STATICA_URL'];
      list($v1,$v2) = split( '@', $statica_url );
      list($v3,$v4) = split( '//', $v1 );
      $proxy_url = $v3 . '//' . $v2;
      $proxy_auth = $v4;
    }
  }

  $ch = curl_init("https://trialbot-api.line.me/v1/events");
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
  curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json; charser=UTF-8',
    'X-Line-ChannelID: (Channel ID)',
    'X-Line-ChannelSecret: (Channel Secret)',
    'X-Line-Trusted-User-With-ACL: (MID)'
    ));
  if( $proxy_url && $proxy_auth ){
    curl_setopt( $ch, CURLOPT_PROXY, $proxy_url );
    curl_setopt( $ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC );
    curl_setopt( $ch, CURLOPT_PROXYUSERPWD, $proxy_auth );
  }
  $res = curl_exec($ch);
  curl_close($ch);
}
?>
↑Statica サービスが使われている場合のみプロクシー指定して実行するようなコードにしています


このコールバック PHP ファイルをデプロイすれば動きますし、(前回苦労したような部分が消えるという意味でも) Bluemix 上での LINE Bot 開発がより簡単になると思われます。