ごきげんよう。スパゲティはスプーンの上で巻かない派、mです!(何
先日は『LINE Loginを実装』しました。
今日はLINE BOT API Trial Accountの実装のお話ですw
【LINE】メッセージングAPIのオープン化に先駆け、先着1万名限定でBOTアカウントを自由に開発できる「BOT API Trial Account」の無償提供を開始 | LINE Corporation | ニュース
LINE BOT APIとは、いわゆるBOTです。
例えば、LINEでお天気を聞いたらお天気を返してくれるとか、喫茶店を聞くと近くの喫茶店を教えてくれるアカウントです。
私はお仕事でよく英単語を調べたりしますので、今回はLINE BOT APIで英単語を聞いたら英語を教えてくれるBOTを作ってみましたw
そんなわけで『教えて!英単語!』リリースです!
英語→日本語のみです。
英語の語尾変換にもある程度対応しています。
QRコード!
↓こんな感じ
画像は描き下ろしましたw あ!中学校の英語の教科書『New Horizon』よりエレン先生ですw
How to draw an anime character 180【アニメ絵の描き方】
ではでは!
早速LINE BOT APIの作り方にいってみましょう!
LINE BOT API Trial Accountを実装した
まずはBusiness Centerにアカウントを作らなければなりません。
作り方は、先日の私の『LINE Loginを実装してみた - Traffic Jam』の記事が参考になるかと思います。
- ログイン
- Business Centerの認証メールを完了させる
- アカウント、企業情報を入力する
- ビジネスアカウントを作成する(ここの画像と名前がBOTのそれになります)
- ビジネスセンター作成後にBOT API Trial accountを作成する
簡単に書くとこうなりますw
BOT APIは先着1万名なので早めが良さそうです。
作るとこんな感じになっています。
では、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が作れました。
この方のページが参考となるでしょう。
yamamotomanabu.hatenablog.com
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が呼ばれているか確認していました。
ぜんぜん呼ばれず悪戦苦闘してました><