Help us understand the problem. What is going on with this article?

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/

mighty-n
株式会社マイティークラフトのテクニカルディレクター兼サーバー管理者のNです。
https://www.m-craft.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away