Intelligent Technology's Technical Blog

株式会社インテリジェントテクノロジーの技術情報ブログです。

LINE BOT API + Heroku + PHP でうどん屋案内 bot

こんにちは。中山です。

先着 1万名で公開されていた、LINE BOT API Trial Account に、私も申し込んでみました。
この LINE BOT API と、Heroku、PHP を使って、とりあえずお金をかけずに、「うどん屋さんをご案内する bot」を作ってみました。

LINE BOT API Trial Account 登録

LINE BOT API Trial Account は、こちら のページから申し込みを行いました。すでに募集は終了しているようなのですが、

BOT API が利用開始になる前に、その一部の機能をお試しいただけます。

との説明もありましたので、近いうちに正式公開されるものと想像しています。
※追記:Trial Account、募集再開したとのこと。

LINE BOT API とは、公式の情報によりますと、

BOT API Trial AccountではあなたのサービスとLINEユーザーの 双方向コミュニケーションを可能にするAPI開発をお試しいただけます。

とのこと。

https://scdn.line-apps.com/n/_5/partner-center/img/lp/bottrial-fig1.png

この図で示されているとおり、LINE アプリユーザから送信されたメッセージは、「BOT API」経由で、今回作成するプログラムに渡されます。ユーザからのメッセージに応じて、何らかのレスポンス(JSON形式のデータ)を、また「BOT API」経由でユーザに返す、という仕組みです。
今回プログラムを作成するのは、この図の「YOUR SYSTEM」の内部の部分。これを、実際にスマートフォンの LINE アプリから利用してみることにします。

アカウントの登録が完了すると、以下のように LINE developers の「Channels > Basic information」画面でアカウントの情報を確認することができます。

f:id:IntelligentTechnology:20160425163847p:plain:w480

この中の「Channel ID」「Channel Secret」「MID」の値は、のちほど作成するプログラムの中で利用することになります。

Heroku を利用する

とにかく無料で使うため、プログラムを実装するサーバは Heroku を使うことにしました。
無料アカウント作成後、「PHP Get Started」を選択して、チュートリアルにしたがって、新しく PHP のサンプルアプリケーションをデプロイ・実行します。

f:id:IntelligentTechnology:20160425164955p:plain:w480

まずは、Heroku のコマンドラインインタフェースにアクセスするための「Heroku Toolbelt」をインストールする必要があります。
今回、Mac を使って操作を行いましたが、この「Heroku Toolbelt」をインストールしておくことで、Mac の「ターミナル」アプリから、Heroku の操作を行うことができるようになります。

以降の操作は、主に Mac のターミナルで行っています。詳細については、Heroku 公式の説明をご覧いただくのがいちばん確実だとは思いますが、実行する操作だけを列挙していくと、以下のような感じ。

# 作成したアカウントでログイン。
$ heroku login

# サンプル PHP アプリを GitHub から取得
$ git clone https://github.com/heroku/php-getting-started.git
$ cd php-getting-started

# Heroku 用アプリ(環境)を作成
$ heroku create

# GitHub から取得したサンプル PHP アプリを Heroku サーバにプッシュ
$ git push heroku master

# Heroku のサーバインスタンスを1つだけ起動
$ heroku ps:scale web=1

# アプリを起動
$ heroku open

これでとりあえずは PHP サンプルアプリにブラウザからアクセスできるようになりました。

ちなみに Heroku サーバのログを確認するのはこんな感じで。

$ heroku logs --tail

callback.php の作成

今回は、このサンプルアプリのフォルダを間借りして、LINE BOT 用のプログラム(LINE アプリからユーザが送信したメッセージを受け取り、何らかのレスポンスを返すプログラム)を作成します。
サンプルアプリの「php-getting-started/web/」フォルダ内に、以下の「callback.php」を作成します。

<?php
  // アカウント情報を設定します。
  // LINE developers サイトの Channels > Basic informationに
  // 記載されている情報を設定します。
  $channelId = "************"; // Channel ID
  $channelSecret = "********************************"; // Channel Secret
  $mid = "********************************"; // MID

  // LINEから送信されたメッセージ(POSTリクエストのボディ部分)を取得します。
  // 以下のようなJSONフォーマットの文字列が送信されます。
  // {"result":[
  //   {
  //     ・・・
  //     "content": {
  //       "contentType":1,
  //       "from":"uff2aec188e58752ee1fb0f9507c6529a",
  //       "text":"Hello, BOT API Server!"
  //       ・・・
  //     }
  //   },
  //   ・・・
  // ]}
  $requestBodyString = file_get_contents('php://input');
  $requestBodyObject = json_decode($requestBodyString);
  $requestContent = $requestBodyObject->result{0}->content;
  $requestText = $requestContent->text; // ユーザから送信されたテキスト
  $requestFrom = $requestContent->from; // 送信ユーザのMID
  $contentType = $requestContent->contentType; // データ種別(1はテキスト)

  // LINE BOT API へのリクエストのヘッダ
  $headers = array(
    "Content-Type: application/json; charset=UTF-8",
    "X-Line-ChannelID: {$channelId}", // Channel ID
    "X-Line-ChannelSecret: {$channelSecret}", // Channel Secret
    "X-Line-Trusted-User-With-ACL: {$mid}", // MID
  );

  // ユーザに返すテキスト。
  // 必ず山越の釜玉うどんを勧める。
  $responseText = <<< EOM
「{$requestText}」ですね。わかりました。そんなときには山越の釜玉うどん。http://yamagoeudon.com
EOM;

  // LINE BOT API 経由でユーザに渡すことになるJSONデータを作成。
  // to にはレスポンス先ユーザの MID を配列の形で指定。
  // toChannel、eventTypeは固定の数値・文字列を指定。
  // contentType は、テキストを返す場合は 1。
  // toType は、ユーザへのレスポンスの場合は 1。
  // text には、ユーザに返すテキストを指定。
  $responseMessage = <<< EOM
    {
      "to":["{$requestFrom}"],
      "toChannel":1383378250,
      "eventType":"138311608800106203",
      "content":{
        "contentType":1,
        "toType":1,
        "text":"{$responseText}"
      }
    }
EOM;

  // LINE BOT API へのリクエストを作成して実行
  $curl = curl_init('https://trialbot-api.line.me/v1/events');
  curl_setopt($curl, CURLOPT_POST, true);
  curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($curl, CURLOPT_POSTFIELDS, $responseMessage);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  // Heroku Addon の Fixie のプロキシURLを指定。詳細は後述。 
  curl_setopt($curl, CURLOPT_HTTPPROXYTUNNEL, 1);
  curl_setopt($curl, CURLOPT_PROXY, getenv('FIXIE_URL'));
  $output = curl_exec($curl);
?>

callback.php 作成後、Git に変更をコミットして、再度 Heroku サーバにプッシュします。

# 変更をコミット
$ git commit -a -m "Adds callback.php"

# コミットした内容を Heroku サーバにプッシュ
$ git push heroku master

# アプリを起動
$ heroku open

「callback.php」にアクセスする URL は、以下のようになります。

https://{Herokuの割り当てられたドメイン名}/callback.php

この URL を、先ほどの LINE developers ページの「Callback URL」欄に指定します。(ポート番号は明示的に 443 を指定するのがよいそうです。)

f:id:IntelligentTechnology:20160425182022p:plain

Heroku サーバに、固定 IP でアクセスするために

ここでひとつ問題が。
LINE BOT API を利用するためには、前述の「Callback URL」でアクセスするサーバの IP アドレスを「ホワイトリスト」に登録しておく必要があるそうです。
しかし、Heroku の場合、サーバの IP アドレスは、通常は動的に割り当てられている、とのこと。

これを解決するために、「Fixie」という Heroku で固定 IP アクセスを実現するためのアドオンを利用しました。
Heroku の設定画面から、クレジットカード情報を入力する必要はありましたが、とりあえずこれで、1ヶ月に 500 リクエストまでであれば、無料で固定 IP でのアクセスが可能になります。

「Fixie」アドオンのインストール後、「Fixie」管理画面に表示されている固定 IP アドレスの情報を、LINE developers ページの「Channels > Server IP Whitelist」に指定します。

f:id:IntelligentTechnology:20160425183352p:plain:w480

bot を試す

ようやく、LINE BOT API を試す環境が整いました。
LINE developers ページに QR コードが表示されていますので、それをスマートフォンで読み取ると、今回作成した bot が、LINE に「友だち」として自動的に追加されます。
いつもと同じようにメッセージを送ると、

f:id:IntelligentTechnology:20160425190246j:plain

なんと、山越の釜玉うどんを(どんなときでも)お勧めしてくれるではありませんか!

bot の可能性

「bot」関連は、最近でもいろいろ気になるニュースを見かけるようになりました。

jp.techcrunch.com

www.itmedia.co.jp

「会話」という、より人間にとって扱いやすいインタフェースで、コンピュータを操作する、というのは、考えてみるとごくごく自然な流れなのかもしれません。
今後も目が離せなくなる分野のひとつなのかなと思いました。