Posted at

Chatworkでbotを作る(2) - php で オウム返しbot

More than 1 year has passed since last update.


Chatwork botへ次のステップ

(1)でChatworkのルームにメッセージが書き込まれたら、設定したweebhookのURLが呼び出されるところまで確認できました。

この書き込まれたメッセージを、オウム返しで書き込んで返すようなbotのプログラムを作成します。

チャットワークAPIはREST形式でメッセージをやりとりし、エンドポイントURLに対してHTTP形式でパラメータを送ります。

データはHTTP形式ですが、エンドポイントURLはhttpsですので暗号化されて送信されます。

難しいことはとばして、出来るだけシンプルにAPIを使ってみます。


会議室の発言で受け取ったメッセージは

発言したメッセージをログファイルに出力しているので、[Webhook_event]のサブ配列は以下のように確認できています。


       [message_id] => 1017313389526647584

[room_id] => 1234567
[account_id] => 1234321
[body] => おはよう!
[send_time] => 1519019750
[update_time] => 0

APIドキュメントでも、Webhookイベントオブジェクトの内容は同じであることも確認できます。

(1)で動作させたphpプログラムでは、


$receive['webhook_event']['body'];


に発言メッセージが入っているので、bot ではこの部分に対応して返信をすればいいのです。


発言と同じ内容を返信するbotプログラム

シンプルにプログラムを記述します。

Chatwork APIを呼び出すには、phpのcurlモジュールを使用しています。


bot.php

<?php

$raw = file_get_contents('php://input');
$receive = json_decode($raw, true);

$message = $receive['webhook_event']['body'];

$reply = array('body' => $message );

header('Content-type: application/json; charset=utf-8');

$cdata = curl_init();
curl_setopt($cdata, CURLOPT_URL, 'https://api.chatwork.com/v2/rooms/1234567/messages');
curl_setopt($cdata, CURLOPT_HTTPHEADER, array('X-ChatWorkToken: 342a5a5a5a5a5a5a5e4e4e4f7d2e'));
curl_setopt($cdata, CURLOPT_POSTFIELDS, http_build_query($reply, '', '&'));
curl_setopt($cdata, CURLOPT_POST, 1);
curl_setopt($cdata, CURLOPT_RETURNTRANSFER, 1);

$ret = curl_exec($cdata);
curl_close($data);


CURLOPT_URLには、webhook で設定したものと同じroomid(1234567)を設定します。

CURLOPT_HTTPHEADERにはAPI設定画面で生成した識別用のToken文字列を設定します。


bot実行!・・・あらら!

WEBサーバーにphpプログラムをアップロードします。

アップロードファイル名は(1)と同じくwebhook先の、chatwork.phpにします。

早速「こんばんは!」と発言しましょう。

Image1.jpg

「送信」ボタンを押して、botから同じメッセージが帰ってくるはずです・・・が、

Image2.jpg

メッセージは帰ってきました!・・・・ですが、bot からの挨拶が止まりません!!・・・緊急事態です!

ループしてメッセージが送出され続けています。

APIのリクエスト数は「5分あたり100回まで」と制限もされていますので、早く何とかしないと規約にも違反しています!


プログラムは正常です

ともかくWEBサーバのプロセスを止めるか、一度プログラム(chatwork.php)を削除してWEBサーバーでエラーを起こさせます。

原因はすぐに予想できました。

そうです、bot が返信したメッセージに対しても webhook が呼び出されるので、永遠にbotがメッセージを返し続けるのでしょう。

webhookで呼び出されたメッセージを返しているのですから、プログラムは正常です。


自分(bot)の発言には返信しない

これがいちばん簡単に実装できそうです。

発言者(account_id)が自分(bot)であれば返信せずプログラム終了させます。


bot.php

<?php

$raw = file_get_contents('php://input');
$receive = json_decode($raw, true);

if ($receive['webhook_event']['account_id'] == 1234567 ) exit();

$message = $receive['webhook_event']['body'];

$reply = array('body' => $message );

header('Content-type: application/json; charset=utf-8');

$cdata = curl_init();
curl_setopt($cdata, CURLOPT_URL, 'https://api.chatwork.com/v2/rooms/1234567/messages');
curl_setopt($cdata, CURLOPT_HTTPHEADER, array('X-ChatWorkToken: 342a5a5a5a5a5a5a5e4e4e4f7d2e'));
curl_setopt($cdata, CURLOPT_POSTFIELDS, http_build_query($reply, '', '&'));
curl_setopt($cdata, CURLOPT_POST, 1);
curl_setopt($cdata, CURLOPT_RETURNTRANSFER, 1);

$ret = curl_exec($cdata);
curl_close($data);


追加したのは1行。if文の部分です。

account_id はチャットワークIDではなく、数字です。

account_id は(1)でログに出力した際のファイルに記録確認しましょう。

コマンドラインのAPIでもaccount_idを確認できます。


curl -X GET -H "X-ChatWorkToken: 342a5a5a5a5a5a5a5e4e4e4f7d2e" "https://api.chatwork.com/v2/me"



完成

Image3.jpg

発言に対してオウム返しされています。

完成です。

あくまでも動作確認のスケルトン(骨組み)ですので、この先はbotとして返すメッセージを生成しないとならないですし、(1)で説明したようにwebhookの認証や各種例外処理も組み込まなくてはならないでしょう。

さらにチャットルームIDや発言者のアカウントID取得など、実運用には考慮しなくてはならない課題もまだまだありそうです。

chatwork API ドキュメント

http://developer.chatwork.com/ja/