ごきげんよう。スパゲティはスプーンの上で巻かない派、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が呼ばれているか確認していました。
ぜんぜん呼ばれず悪戦苦闘してました><






