LINEのBOTを組んでみた
お久しぶりです、ひろたんです。
ようやくLINEがBOT用APIを一般公開してくれたと聞いて、飛びついてきました。
LINE Developers - BOT API - Overview
先着1万人らしいですよ!!はよはよ!!
ただこいつ、中々に曲者で……。
Botに対して発言とかのアクションがあったときに、あらかじめ登録しておいたcallback用URLを叩きにきてくれる機能があるのですが、HTTPSじゃないとダメな上、Let'sEncryptの証明書だと叩きに来てくれないんですよね。
なので、こんなスクリプトをherokuにおいて、自前のサーバにバイパスさせて遊んでました。
<?php function heroku_getallheaders(){ $headers = ''; foreach ($_SERVER as $name => $value) { if (substr($name, 0, 5) == 'HTTP_'){ $headers[strtoupper(str_replace(' ', '-', ucwords(str_replace('_', ' ', substr($name, 5)))))] = $value; } } return $headers; } $headers = heroku_getallheaders(); if(isset($headers["X-LINE-CHANNELSIGNATURE"])){ $json_string = file_get_contents('php://input'); $url = "https://urische.me/hogehoge"; $curl = curl_init($url); $options = array( CURLOPT_HTTPHEADER => array( 'Content-type: application/json', 'X-LINE-ChannelSignature: '.$headers["X-LINE-CHANNELSIGNATURE"] ), CURLOPT_POST => true,//POST CURLOPT_POSTFIELDS => $json_string, CURLOPT_SSL_VERIFYPEER => false ); curl_setopt_array($curl, $options); $result = curl_exec($curl); exit(); } else { print "making now...."; }
herokuだとgetallheaders()が使えなかったので、PHP: getallheaders - Manualにあった代替関数を定義して使ってます。
これで何処でも受け取れるようになるので、urische.meでこんなスクリプトを動かしてAPIを叩いてます。
肝心の中身は単に発言された内容をsay:なんちゃら とオウム返しするだけです。
<?php $headers = getallheaders(); if(isset($headers["X-LINE-ChannelSignature"])){ $json_string = file_get_contents('php://input'); if(base64_decode($headers["X-LINE-ChannelSignature"]) === hash_hmac("sha256",$json_string,$LINE_SECRET,true)){ botmain(json_decode($json_string)); } } function botmain($json){ global $LINE_SECRET,$LINE_CHANNEL,$LINE_MID; $results = $json->result; $ret = array(); $sendheaders = array( 'Content-Type: application/json; charset=UTF-8', 'X-Line-ChannelID: '.$LINE_CHANNEL, 'X-Line-ChannelSecret: '.$LINE_SECRET, 'X-Line-Trusted-User-With-ACL: '.$LINE_MID ); for($i=0;$i<count($results);++$i){ $resContent = array( "contentType"=>1, "toType"=>1, "text"=>"say:".$results[$i]->content->text ); $resp = array( 'to' => array($results[$i]->content->from), 'toChannel' => 1383378250, # Fixed value 'eventType' => '138311608800106203', # Fixed value 'content' => $resContent, ); $url = "https://trialbot-api.line.me/v1/events"; $curl = curl_init($url); $options = array( CURLOPT_HTTPHEADER => $sendheaders, CURLOPT_POST => true,//POST CURLOPT_POSTFIELDS => json_encode($resp), CURLOPT_SSL_VERIFYPEER => false, CURLOPT_RETURNTRANSFER => true ); curl_setopt_array($curl, $options); $result = curl_exec($curl); curl_close($curl); } }
Trialということで機能は少ないですが、自分用に色々するには便利そうですね!
ところで巷で公開されてるサンプルの大半が署名検証をはしょってるんですよね。(要出典)
そのままコピペしてそのまま動かしている人が沢山居るだろうな……と思うと何とも言えない気持ちになりますね。
PHPでX-LINE-ChannelSignatureを検証するコード、以下に改めて張っておきます。
<?php base64_decode($headers["X-LINE-ChannelSignature"]) === hash_hmac("sha256",$json_string,$LINE_SECRET,true)
ではでは、そのうち何処かで。