ごきげんよう。スパゲティはスプーンの上で巻かない派、mです!(何
先日は『LINE Loginを実装』しました。
今日はLINE BOT API Trial Accountの実装のお話ですw
例えば、LINEでお天気を聞いたらお天気を返してくれるとか、喫茶店を聞くと近くの喫茶店を教えてくれるアカウントです。
私はお仕事でよく英単語を調べたりしますので、今回はLINE BOT APIで英単語を聞いたら英語を教えてくれるBOTを作ってみましたw
そんなわけで『教えて!英単語!』リリースです!
英語→日本語のみです。
英語の語尾変換にもある程度対応しています。
↓こんな感じ
画像は描き下ろしましたw あ!中学校の英語の教科書『New Horizon』よりエレン先生ですw
How to draw an anime character 180【アニメ絵の描き方】
ではでは!
LINE BOT API Trial Accountを実装した
まずはBusiness Centerにアカウントを作らなければなりません。
作り方は、先日の私の『LINE Loginを実装してみた - Traffic Jam』の記事が参考になるかと思います。
- ログイン
- Business Centerの認証メールを完了させる
- アカウント、企業情報を入力する
- ビジネスアカウントを作成する(ここの画像と名前がBOTのそれになります)
- ビジネスセンター作成後にBOT API Trial accountを作成する
簡単に書くとこうなりますw
作るとこんな感じになっています。
この設定で大大大苦戦しましたっ(滝涙
LINE BOT APIを設定しよう
BOT APIの「使う」をクリックすると設定画面に移動できます。
こんな感じになります。
ビジネスアカウントの画像と名前が設定されています。
そして恐らく最大の難所!!
Callback URLです!!
私の周り、何人が個々で阿鼻叫喚のうめきをあげたことでしょうか……
LINE BOTのCallback URLを設定しよう
LINE BOTのCallback URLの第一の難所
『https』でなければなりません!
なのでhttpsを使える場所がないといけません。
そして……『FreeSSLは蹴られる』
ここが阿鼻叫喚ポイントですね……。
Lets encryptなどはアウトだったとのことです(^-^;
こちら、OKになったようです。(2016/4/26現在)
以下プレスリリースより
4月15日より、LINE BOT API Trial Accountで利用できる SSL 認証局に StartSSL と Let's Encrypt を追加しております。詳細情報は、以下URLにて、公開しております。
https://developers.line.me/bot-api/getting-started-with-bot-api-trial#register_callback_url
もしお手軽に試すのでしたら、フリーでhttpsが使えるwebscript.ioが良いかもしれません。
私も試しましたがwebscript.ioで簡単にオウム返しbotが作れました。
この方のページが参考となるでしょう。
LINE BOTのCallback URLの第ニの難所
https://milk0824.sakura.ne.jp:443/linebot
なぜかポート番号を書かないといけません(^-^;
マニュアルに目を通す方だと書いているので気づきますが、「httpsだろぅ」で進めてしまう人は混乱しますw
……そしてエラーメッセージで「specified」を「sepcified」とスペルミスしていることに気づいてしまうmだったのでしたw(ここ、何回も見ることになったので…)
LINE BOTのCallback URLの第三の難所にして最大の難所!
LINE BOTを作ったのは良いんだけど、反応がない!
ログを見てもアクセスされている様子がない!
レスポンスが全く帰ってこない!!
今日、mも体験しましたし、私の周りも「私のワンちゃんボットから反応がないっ」とか「独り言いってるだけなんだけど」といった感じになっていました。
私も苦戦してたのですが……
Callback URLを設定してから反映されるまでとても遅いのです!!
これでした(^-^;
少し放っておいて30分後くらいに「こんにちは」といったら反応が返ってきましたw
プログラマーの皆さんは基本一秒単位でコールしちゃいますので、設定後は珈琲を飲んでアニメを見てから話しかけてみましょう。
Server IP WhitelistにCallback URLのIPを設定しよう
あと、ボットが呼び出すプログラム(Callback urlで設定した場所)のIPをwhite listに登録しなければなりません。
white listとは、決められたIPにしかアクセス出来ない仕組みです。
左側のメニューから『Server IP Whitelist』を選んでください。
ここに、Callbackで使用するサーバーのIPアドレスを追加しましょう。
最後の「24」はサブネットマスクと呼ばれるものです。
24の場合は先頭から3箇所は固定で、最後の場所が0~254まで使用できます。
まぁ、最低24から設定してくれ、と書いていますのでおとなしく24にしておきましょうw
使うサーバーのアドレスがわからない場合は、ネットで調べることも出来ますし、コマンドプロンプトで「nslookup ドメイン名」で検索できるかと思います。
これで難しい設定は終わりです!
callback urlの件がありますので、設定後はお茶でも飲んでくつろいでいれば良さそうです。
callbackをphpで実装しました
実装は大体こんな感じです。
- メッセージを取得する。
- メッセージから送り主とテキストを取得する
- 送信データを設定する
- ヘッダを設定する
- 送信する
みなさん苦戦するのはSSLとCallbackで、そこを抜けたら何とかなりますw
では私がかいた『教えて!英単語!』のプログラムをベッタリ貼り付けておきますw
アマチュアですのでコードの汚さはちょっとだけ勘弁して下さいねっ(ぉ
require("english12000.php"); function searchWord($word, $englishDB){ $word = mb_strtolower($word); $changedWord = exchangeWord($word); //完全一致で検索 $returnValue = findWord($word, $englishDB); //なかったら変更後のワードで検索 if(!$returnValue){ $returnValue = findWord($changedWord, $englishDB); } //それでも無かったら部分一致 if(!$returnValue){ $returnValue = stristrWord($changedWord, $englishDB); } //それでも無かったら謝る if(!$returnValue){ $returnValue = cantFind(); } return $returnValue; } //語句判定 function findWord($word, $englishDB){ if(isset($englishDB[$word])){ return makeFindTalk($word, $englishDB[$word]); } return null; } //見つけた時のトーク作成 function makeFindTalk($word, $value){ $serifu = array( $word . "ね\n" . $value, $word . "かしら\n" . $value, $word . "ですね\n" . $value, $word . "…" . $word . "と\n" . $value, $word . "かぁ…たしか…\n" . $value, $word . "はこんな感じね\n" . $value ); return $serifu[rand(0, count($serifu) - 1)]; } //部分一致検索 function stristrWord($word, $englishDB){ $returnValue = null; while(list($key,$value) = each($englishDB)){ if(stristr($key, $word)){ $returnValue = makeFindTalk($key, $value); break; } } return $returnValue; } //いじめられた時の先生の反応 function cantFind(){ $serifu = array( "ごめんなさい、先生その英語がわからないの…\n勉強不足かしら…", "どういう意味かしら……\nちょっとわからないわね", "えと、えと、調べてるけど出てこなくて……", "わ、わたしの辞書にその字はないかも……", "な、なにかしらね、その単語……\nごめんなさい、パソコンで調べて><", "え!?\nええと……ちょっとわからないわね……", "うーん、これでもないし…それでもないし…な、なんでしょうね。あは、あはは……ごめんね><", "その単語は昔聞いたんだけど……ごめんなさい……。", "あうう……わたしの辞書に載ってなくて……ごめんなさい", "えと、えと、調べてるけど出てこなくて……" ); return $serifu[rand(0, count($serifu) - 1)]; } //単語をルールにそって変更 function exchangeWord($word){ if(preg_match('/ies\z/', $word)){ return str_replace('ies', 'y', $word); } else if(preg_match('/es\z/', $word)){ return str_replace('es', '', $word); } else if(preg_match('/ed\z/', $word)){ return str_replace('ed', '', $word); } else if(preg_match('/ing\z/', $word)){ return str_replace('ing', '', $word); } } ////////////////////////////////////ここから本体 //ユーザーからのメッセージ取得 $json_string = file_get_contents('php://input'); $jsonObj = json_decode($json_string); //送ってきた相手のmid取得 $to = $jsonObj->{"result"}[0]->{"content"}->{"from"}; //メッセージ取得 $text = $jsonObj->{"result"}[0]->{"content"}->{"text"}; //辞書検索 $text = searchWord($text, $englishDB); //返信データ作成 $response_format_text = [ 'contentType' => 1, "toType" => 1, "text" => $text ]; //このへんは固定データです。 //toは配列型じゃないとうまくいきません>< $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: ご自分のチャンネルID', 'X-Line-ChannelSecret: ご自分のチャンネルシークレット', 'X-Line-Trusted-User-With-ACL: ご自分のmid' )); $result = curl_exec($ch); curl_close($ch);
こんな感じです。
メッセージの受信と送信本体は下のちょっとした部分だけですw
データの受信
$json_string = file_get_contents('php://input');
$jsonObj = json_decode($json_string);
$to = $jsonObj->{"result"}[0]->{"content"}->{"from"};
$text = $jsonObj->{"result"}[0]->{"content"}->{"text"};
***
file_get_contentsで取得です。
そこからfromでメッセージを送ってきた人のmidを取得します。
またtextで送信されたメッセージを取得します。
相手に送るメッセージを作成
$response_format_text = [
'contentType' => 1,
"toType" => 1,
"text" => $text
];
$post_data = [
"to" => [$to],
"toChannel" => "1383378250",
"eventType" => "138311608800106203",
"content" => $response_format_text
];
***
どの値も固定なのであまり気にする必要はありませんw
まずは上の部分。
LINEにメッセージを送信するときは……
contentTypeは1
toTypeもuserですので1
textは送信したいテキストです。
公式マニュアルをぺたり。
https://developers.line.me/bot-api/api-reference
***
続いて下の方。送る相手についての設定です。
toの部分は送る相手のmidです。
ここ、ただの"to" => $toにするとコケます><
配列の形(最大は150人みたい)でなければダメそうです。
"toChannel" => "1383378250",
"eventType" => "138311608800106203",
ここも固定の数字です。
contentに関しては上の方で設定したメッセージを使いましょう。
メッセージの送信
$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: ご自分のチャンネルID',
'X-Line-ChannelSecret: ご自分のチャンネルシークレット',
'X-Line-Trusted-User-With-ACL: ご自分のmid'
));
$result = curl_exec($ch);
curl_close($ch);
***
この辺は色々なページを参照して作成していますので悪しからずです(^-^;
皆さんの真似でcurlを使用します。
curlは……ヘッダとか色々つけてhttpで色々できるよ!という代物……だと思います!
たぶん!(ぉ
さて。送る先はこのAPIです。
URL
https://trialbot-api.line.me/v1/events
POST
ヘッダ
- Content-Type: application/json; charser=UTF-8
- X-Line-ChannelID: ご自分のチャンネルID
- X-Line-ChannelSecret: ご自分のチャンネルシークレット
- X-Line-Trusted-User-With-ACL: ご自分のmid
これらを設定しましょう。
全部LINE BOT APIの設定部分に書かれている情報です。
これで無事、メッセージを送ったら先生がお言葉を返してくれるBOTの出来上がりですw
デバッグが面倒くさいけれどどうすればいいの?
エラーログなどがないので、デバッグがつらいです……。
なので私は、まず自分のLINEのmidの取得をしました。
これは先日の『LINE Loginを実装』の副産物ですw
ログインすることでmidがとれましたのでw
それを送信の際の「to」に設定して、直接phpを実行しました。
callbackで呼ばず直接プログラムを叩く場合、whitelistも関係なしに呼び出すことができます。
叩くだけで「ぴろろん」とLINEが飛んできますw
実際にcallbackが反応するのはサーバーのログが取れなかったので、webscript.ioでcallbackが呼ばれているか確認していました。
ぜんぜん呼ばれず悪戦苦闘してました><