まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:line

(この記事は IBM Cloud アドベントカレンダー 2018 に参加しています。2日目の記事です)

先日、以下のブログエントリを公開しました。本エントリはその技術的な補足と、試験的な意味も含めてアプリ URL を一般公開する内容になっています。
お絵かき LIFF アプリを作ってみた

2018112200


技術的な説明の前に、まずは一度使ってみていただきたく、このアプリを(一時的に?)公開することにしました。少し面倒ではありますが、以下の手順で実行できるようにしたので、まずは一度使ってみてください。

①スマホに LINE アプリをインストール(お絵かきアプリは PC 版 LINE からは使えません)

②LINE を開いて誰かとのメッセージ画面(グループ LINE 可)の中に以下の文字を入力してリンクメッセージとして送信する(この作業だけは PC の LINE アプリから行ってもよい)
line://app/1624220123-mbERyVgb

2018120101


③スマホの LINE 画面内から②で送信したリンクメッセージをタップ
2018120102


④LINE 内でお絵かきアプリが起動します。ペンの色と太さを変えながら指でお絵かきします。
2018120103


⑤間違えたら reset か、一度終了してから再度リンクメッセージをタップしてやり直し。
2018120104



⑥描き終わったら post でお絵かきが画像として LINE にメッセージ送信されます(右上の×を押してアプリを終了する)
2018120105


・・・というものです。LINE はスタンプ文化が有名ですが、スタンプを持っていなくてもその場でお絵かきして送るとか、他には地図を書いて送るとか、いろいろな使い方が考えられると思っています。現状、上記のリンクを LINE のメッセージとして一度送っておく必要があり、そのリンクをタップした時に起動する、という使い方になってしまいます。技術的に興味がある人もない人も是非お試しいただきたいと思っています。


以下、このアプリの技術的な解説になります。

このアプリは LINE の新しい開発フレームワークである LIFF(LIne Front-end Framework) を使って開発しています:
https://developers.line.biz/ja/docs/liff/overview/


LIFF は LINE 内で動作するウェブアプリケーションのプラットフォームです。「LINE 内で動作する」という点と「ウェブアプリケーション」であることがキーワードです。上記のように LINE 内で特定リンクをタップすることで起動し、その中身は HTML5 と JavaScript で記述されたウェブアプリケーションです。LIFF の詳しい仕様等は上記の開発者向けページを参照いただきたいのですが、要するにパブリックインターネット上に HTML5 ベースのウェブアプリを作って、そこを参照するような LINE リンクを作っておくことで LINE アプリ内でその HTML5 ページを起動することができます。また LIFF SDK の JavaScript API を使うことで、その HTML5 アプリの情報を起動元である LINE 側に(メッセージとして)送信することも可能です。

今回作ったアプリの場合は HTML5 の Canvas を使ってお絵かきアプリを作成し、その中に描かれた絵を動的に画像に変換して、画像を貼り付ける形でメッセージを送ったことにしています。その結果、HTML5 Canvas 内に描かれた絵を LINE 上で画像添付したかのように送信させることを実現しています。

この仕組の HTML5 ウェブアプリケーション部分と、画像添付部分を IBM Cloud 上の Node.js ランタイムと IBM Cloudant を使って実現しています。HTML5 Canvas 内に描いた画像を動的に PNG 画像へ変換し、Node.js ランタイム上の REST API を使って取得し、(LIFF の場合、画像はオリジナル以外にサムネイルが必要なので)サムネイル画像を生成して IBM Cloudant データベース内に添付ファイルとして保存します:

2018120106


画像が添付できたら、今度はその画像を外部から参照できる URL を用意します。具体的には Node.js ランタイム内に Cloudant 内に格納した画像ファイルを参照できるような URL(REST API) を用意します。そして HTML5 内の LIFF SDK を使って、画像ファイルの URL をメッセージとして送信して、添付画像を付与したメッセージ送信と同じ処理を行います。これでお絵かきで作成した画像が添付されたかのような振る舞いを実現できます:
2018120107


という形で現在は実現しています。 つまり現在はこのアプリを使って作成した画像は IBM Cloudant 内に保存されるように実装されています。現在の運用環境では、このデータベースの容量にも制約があるので、しばらくはデータベースをリセットしながら運用することになります。もしうまく送信できない場合は僕がデータベースのメンテナンスを忘れていて、容量オーバーになっている可能性があることをお伝えしておきます(気付いたタイミングでリセットするようにします)。

また、この公開アプリのソースコードはこちらで(MIT ライセンスで)公開しています。IBM Cloud を使う前提で記述されたコードですが、自分なりに改良したい人がいればうまく活用してください:
https://github.com/dotnsf/line_liff_doodle


これまで LINE の API といえば Messaging API で、bot のようなバックエンド側を操作するアプリを作るには有用だったのですが、やっとフロントエンド側を操作できる API(というかフレームワーク)が出てきてくれました。公開ページ上で HTML5 アプリを置いて運用することになるので、実質的にクラウドを活用する形態が多くなると思います。そんな時に IBM Cloud の上記構成程度であれば無料のライトアカウントでも運用できるので、公開したソースコードを是非色んな人に使ってみたり改良してみてほしいです。

LINE の新しい開発フレームワークである LIFF(LIne Front-end Framework)の存在を教えていただいたので、試しに使ってみました。

この LIFF 最大の特徴はスマホの LINE アプリ内で HTML5 の Web アプリケーションを動かすことができる、という点です。この Web アプリケーション内で LIFF の SDK を併用すると、アプリケーションからLINE にメッセージや画像(やスタンプ)を送ることも可能です。

この LIFF を使って指で画面にお絵かきをするような HTML5 アプリを作り、その絵を LINE アプリに送信する、というアプリケーションを作ってみました。LINE はスタンプを送信する文化がメジャーですが、その延長で自分でその場でお絵かきした画像を送る、という使い方を想定したアプリケーションです。ソースコードは github で公開したので、興味ある方は実際に試してみてください:
2018112200



なお、今回提供しているソースコードでは IBM Cloud の NoSQL マネージド・データベースである Cloudant を使っているので、IBM Cloud のアカウントも必要です。無料のライトアカウントもあるので IBM Cloud のアカウントをお持ちでない場合はあわせて取得してください。


【IBM Cloudant の準備】
今回紹介するアプリケーションでは IBM Cloundant のインスタンスが必要です。IBM Cloud にログインし、インスタンスを1つ作成して、あらかじめ画像格納用のデータベースを用意しておきます。なお無料のライトプランの場合、Cloudant には 1GB までのデータしか格納することができないという点をご了承ください。

まず IBM Cloud にログインし、「リソースの作成」から IBM Cloudant を追加します。IBM Cloudant は「データベース」カテゴリ内に存在しています:
2018112201


作成時のロケーションはどこでも構いません(下図では「シドニー」を使っています)。ただ認証方法は従来の方式が利用できる方("Use both legacy credentials and IAM")を選択しておく必要があります:
2018112202


また価格プランも任意で構いませんが、Lite プランの場合は無料です。ただし 1GB までしかデータを格納することはできません。最後に「作成」をクリックしてインスタンスを作成します:
2018112203


Cloudant インスタンス作成直後の画面です。まずここから目的の(画像格納用の)データベースを作成するため、Cloudant のダッシュボードに移動します。下図の緑のボタンをクリック:
2018112204


Cloudant のダッシュボード画面に移動しました。データベース一覧が表示されていますが、作成直後の場合は何も存在してません。ここで「Create Database」をクリックして、データベースを作成します:
2018112205


作成するデータベースの名前を指定します。デフォルトでは "doodledb" を使います(後述の settings.js 内で指定されている名称と一致している必要があります)ので、とりあえず doodledb と入力して「Create」します:
2018112206


doodledb データベースが作成され、doodledb データベース内の文書一覧画面に移動しました(当然中身はありません)。左上の "<" 印をクリックしてデータベース一覧に戻ります:
2018112207


データベース一覧に戻りました。先程とは変わって、"doodledb" が一覧に含まれているはずです。これでデータベースの準備ができました:
2018112208


次にこのデータベースへ接続するための情報を確認します。IBM Cloud の画面に戻り、「サービス資格情報」タブを選択します。サービス資格情報は(この時点では)存在していないはずなので、「新規資格情報」ボタンをクリックして作成します:
2018112201


設定項目は変更せずに「追加」します:
2018112202


資格情報が追加されると先程の画面内に「資格情報の表示」メニューが追加されているはずです。ここをクリックして内容を確認します:
2018112203


資格情報の内容が JSON テキストで表示されます。今回必要なのは "username" と "password" の値です。これらの情報を後で利用するので、メモしておくか、コピペできるようにしておきます:
2018112204


これで IBM Cloudant の準備はできました。


【ランタイム(Web アプリケーション・サーバー)の準備】
次に LIFF が参照する Web アプリケーションサーバーを作成します。このサンプルは Node.js 上で動作するサンプルですが、今回は IBM Cloud 上にアプリケーション・サーバーを作成することにします(これもライトプランの無料枠内で作成することができます)。

Cloudant の時と同様に IBM Cloud にログイン後にリソース作成で「コンピュート」カテゴリの「SDK for Node.js」を選択します:
2018112201


ロケーションは「ダラス」を選択します(するとドメインは "mybluemix.net" となります)。そして「アプリ名」にアプリケーション名称を指定します。下図の例では "linedoodle" というアプリケーション名称としており、この場合のエンドポイント URL は https://linedoodle.mybluemix.net/ となります。なおアプリ名は他で使われていないものを指定する必要があります。自分の名前や日付を指定するなどして、ユニークなアプリケーション名称を指定してください。最後に「作成」をクリックします:
2018112202


しばらく待つとアプリケーションサーバーが起動します。これで LIFF アプリからアクセスできるパブリッククラウド上にアプリケーションサーバーが用意できました:
2018112203


【LINE Developers の準備】
LINE の LIFF アプリを作成するには LINE Developers でのチャネル登録が必要です。LINE Developer において新規にチャネルを作成します:
2018112204


チャネルの種類は「Messaging API」を選択します:
2018112205


アプリ名とプラン(Developer Trial)を選択し、作成します:
2018112206


作成すると、このチャネルにアクセストークンが割り当てられます。「アクセストークン(ロングターム)」と書かれた項目の値をこの後で使うことになるのでメモするか、コピペできるようにしておきます:
2018112207


また、ここで LIFF アプリとしてのアプリ URL を作成しておきましょう。LIFF タブを選んで「追加」ボタンをクリックします:
2018112209


名称、サイズ(Full または Tall のいずれかを選択)、そしてエンドポイント URL(上述の Node.js アプリケーションのエンドポイント URL)を入力して「保存する」をクリックします:
2018112210


すると LIFF アプリが登録され、LIFF URL が確認できるようになります。この LIFF URL は実際に LINE からアプリケーションを起動する際に利用します:
2018112208


これで LIFF アプリの登録も完了しました。あと少し。


【アプリケーションの準備】
上記で作成したアプリケーション・サーバーに HTML5 アプリケーションをデプロイします。まずはソースコードを入手します。github のリポジトリからソースコードをダウンロードまたは git clone して入手します:
https://github.com/dotnsf/line_liff_doodle

ソースコードがダウンロードできたら settings.js ファイルを環境にあわせて編集して保存します:
exports.db_username = '(Cloudant の username)';
exports.db_password = '(Cloudant の password)';
exports.db_name = 'doodledb';
exports.app_port = 0;

exports.base_url = 'https://(アプリケーション名).(ドメイン)/';

exports.line_access_token = '(LINE Developer で取得したロングタームアクセストークン)';

  :
  :

最後にこのアプリを上記で作成したアプリケーションサーバーにデプロイします。IBM Cloud では cf コマンドを使ってデプロイするので、未導入の場合は cf コマンドをダウンロード&インストールしてください:
https://github.com/cloudfoundry/cli/releases


そして cf コマンドを使って IBM Cloud へ IBM ID でログインし、アプリケーションをプッシュ(デプロイ)します:
$ cd (ソースコードのあるフォルダ)
$ cf login -a https://api.ng.bluemix.net/ -u (IBM ID)
$ cf push (アプリケーション名)

ここまでの作業が全て成功すると LIFF アプリが IBM Cloud 上にデプロイされ、LINE のチャット上で LIFF URL をクリックすると、LINE 上で同アプリケーションを呼び出すことができるようになります。


【LINE で動作確認】
では実際に LINE を使って動作確認してみます。上述で取得した LIFF URL ("line://app/" で始める文字列)をコピー&ペーストするなどして LINE のメッセージとして表示させます:
2018112201


この LIFF URL 部分をタップすると画面下部から LIFF アプリである HTML5 の Web アプリケーションの画面が表れます。今回の Web アプリはお絵かきアプリとなっていて、指でキャンバス上をドラッグして絵を描くアプリとなっています。色やフォントの太さを変えたり、失敗したら "reset" ではじめからやり直すこともできます:
2018112202


たとえばこんな絵を描いてみました。書き終わったら "post" をタップします:
2018112203


描いた絵が LINE の会話内に画像として表れます。その場でステッカーを作って送るような感覚です:
2018112204


・・・というアプリを作ってみたのでした。いかがでしょう? ちなみに iPhone 版の LINE でのみ動作確認しています。Android 版 LINE でうまく動かなかったらごめんなさい。


以前から似たようなアプリを Twitter 向けに作ってみたりしていて、同じようなのを LINE 向けにも作れたらいいなあ、と思っていました。が、LINE にはクライアント側を操作できる API が提供されておらず作ることができずに諦めていました。 が、今回 LIFF の存在を教えていただいて、「これならできるかも・・」と期待してがんばってみたら、なんとか実現できた、という経緯です。アプリ実装の詳細についてはまた別の機会にでも。

ある意味で LINE のステッカービジネスを根底から否定(苦笑)するアプリなので、あまり LINE 受けはよくないかもしれません。(^^; でも教えていただいたおかげで実現することができました。この場をお借りしてお礼申し上げます。


そうそう。繰り返しになりますが、IBM Cloud の(無料の)ライトアカウントを使って作成した場合、データベースには 1GB ぶんの画像しか格納できません。定期的にデータを削除するとか、データベースを消して作り直すとかして対応してください。



(参考)
LIFF API リファレンス


(今回のエントリはこの続編的な内容になっています)
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 開発がより簡単になると思われます。


4月7日に LINE が LINE トークを使った bot 開発用のアカウント "BOT API Trial Account" を先着1万名で提供する、という発表がありました:
http://www.itmedia.co.jp/news/articles/1604/07/news134.html


このニュースはあっという間に広まり、その作り方や実際に作ったボットが早くも多く公開されています。これまでは LINE ビジネスコネクトを通したビジネスアカウントがないと作れなかった LINE のボットが誰でも作れるようになりました。今回の発表で提供されている機能では作ったボットは 50 名のユーザーに対してのみ公開可能(ボットは 50 人までとしか友達になれない)という制限は付きますが、仲間内で使うぶんには充分だし、今後この制約が拡張されることがあればより便利に使えると思っています。 ちなみに昨日友人が試した限りでは、まだアカウントの申し込みが可能でした。

自分も早速 Bot を作って動かしてみました。自分の場合は IBM Bluemix を使って Bot を動かしています。Bot の作り方そのものは Qiita などに数多くの投稿がされているようなので、そちらを参照ください。以下は IBM Bluemix を使って Bot を動かす場合のコツや注意点を中心にまとめたものです。



(1) Bluemix のランタイム作成

まず Bluemix 上に Bot として動くことになるウェブアプリケーションのランタイムを作成します。ちなみに Bluemix のランタイムは標準で SSL が動き、Let's Encrypt 問題のような「この SSL 証明書はダメ」のような現象はおきていません。要するに Bluemix でランタイムを作って動かせばあまり深く考えなくても LINE Bot で使える、ということです。

Bluemix に用意されたランタイムはどの種類を使っても大丈夫だと思います。自分は PHP を使ってコールバック部分を作るつもりなので PHP にしました。Bluemix のサービスは必要に応じて追加してください(なくても動きます):
2016041304
 ↑dotnsf-line.mybluemix.net で PHP サーバーを作成


(2) BOT API Trial Account 作成

次に LINE BUSINESS CENTER へ行き、BOT API Trial Account を作成します:
2016041301


で、Bot を新規に作成して登録します。Channel ID と Channel Secret、MID は後で使うことになるのでメモしておきましょう。App icon は Bot が実際に LINE トーク上に現れる時のアイコンになるので、何か入れておいたほうが面白いと思います:
2016041302


重要な要素が Callback URL です。LINE トーク上でこの Bot に話しかけると、ここで指定した URL が呼ばれて実行されます。ここに指定できる URL は SSL が前提で、かつポート番号 443 を明示指定する必要があります。今回は上記で作成した Bluemix 上のランタイムに callback.php(この下で作ります)をデプロイして動かすので、Callback URL としては https://dotnsf-line.mybluemix.net:443/callback.php という指定になります:
2016041303

White List はこの後で指定します。


(3) Bot 作成&デプロイ

コールバックで動くことになる Bot アプリケーションを作ってデプロイします。ここは Bluemix だから特別に・・・という部分ではありません。自分はこの API を使って、呼びかけた通過ペア(例えば "USDJPY" とか "EURJPY" とか)に対してリアルタイムの為替価格を表示する、という Bot にしてみました:
2016041301
 ↑実際に動いている様子。問いかけた通貨の現在価格を返答してくれます。


ソースコードはこんな感じ。コード内の (Channel ID), (Channel Secret), (MID) の部分には上記で取得した実際の値を指定して書き換えてください:
<?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];

  $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)'
    ));
  $res = curl_exec($ch);
  curl_close($ch);
}
?>

このコードを Bluemix にデプロイすればOK、なのですが、ちょっとまだ足りない部分があるのでデプロイは次の (4) の後にまとめて行うことにします。


(注 この (4) の作業に関してはこちらの作業を行うことで不要にすることもできます)

(4) WhiteList 登録

LINE Bot の、特に Bluemix ランタイムで LINE Bot を動かす上での最大の関所がこの WhiteList 登録だと思ってます。Bot が LINE のサーバーに対して返答の POST を実行する際、あらかじめ許可されたサーバーからのリクエストのみが受け付けられるようなホワイトリストの仕組みが用意されています。つまり LINE Bot を動かすにはどの IP アドレスからリクエストするのかをあらかじめ登録しておく必要があります。

一方で Bluemix のランタイムは再起動や再ステージングを行う度にリクエスト元の IP アドレスが変わる仕様になっています。Bluemix のアプリケーションはデプロイするたびに再ステージングを行うので、要するに作りなおしたアプリをデプロイする度にリクエスト元の IP アドレスを調べてホワイトリストを更新する必要があるのでした。この仕組がちと面倒で、注意する必要があります。

そして更に話がややこしいことに、このリクエスト元の IP アドレスを調べる方法というのがまた面倒だったりします。IaaS のアプリケーションサーバーであれば SSH などでログインして「確認くん」などで調べる方法もありますが、PaaS のランタイムである Bluemix だとそれも簡単ではありません。

方法は何通りかあると思うのですが、基本的な考え方は外部の HTTP サーバーや DB サーバーを用意し、Bluemix からそのサーバーにアクセスを行って、ログを見る(ログのアクセス元の IP アドレスを調べる)という方法です。自宅サーバーなどでダイナミック DNS を使う時のようなテクニックが必要になると思っています。

僕がやってるのはこんな感じ。わざとつながらない DB サーバーに Bluemix ランタイムからアクセスして(アクセスするような PHP アプリを書いて実行して)エラーログを参照する、という方法です。良い子はマネしちゃいけません:
2016041302


というわけで、順序としては (3) で作ったコールバックのアプリケーションに加え、ここでランタイムの IP アドレスをチェックするためのアプリも作り、それらをまとめてデプロイ(プッシュ)する、ということになります。

そして、ランタイムの IP アドレスを取得して LINE Bot の White List IP アドレスに設定します(ネットマスクは 24 を指定して動きました)。この作業はランタイムをステージングするたびに行う必要がある点に注意が必要です:
2016041303


このホワイトリストの反映には数分かかっているようですが、ホワイトリストが正しく反映されていれば自分のボットも動くようになっているはず、たぶん。


Bluemix 環境を活用した LINE Bot は他にも色々作れそうなので、いずれまたブログエントリとして書くつもりです。 上記のようにホワイトリストの所だけちと面倒ではあるのですが、ランタイムが自由に作れて SSL も問題なさそうだし、これにワトソンなどのコグニティブエンジンを組み合わせた Bot を作ると面白いかな、と考えています。



このページのトップヘ