ChatWork APIを叩いてメッセージを投稿するだけのbotをPHPで作って遊んでみたので忘備録を記す。
目次
作成に至った経緯
弊社の社員は意識が高いので昼休みになろうが定時になろうが気づくことすらなく作業を続ける者が多い。そのため筆者のような意識の低い者がご飯ですよー定時ですよーなどとお母さんばりに声をかけてあげる必要があった。段々それも面倒になってきた。
そこで、社員全員がコミュニケーションツールとして利用しているChatWorkで自動的に通知を飛ばせば皆気づいてくれるのでは?と思ったわけだ。
使用技術と仕様
調べるとSlack botの作成例は多く出てくるが、ChatWork botの例はそう多くは出てこない。GAS(Google Apps Script)を用いた例が上位に出てきて、スプレッドシートをDBのような形で利用するって発想はなかったので参考にはなったが、GASはどうやら実行日時を分単位で設定することができないっぽい。
私が作成したいのは13時と19時ピッタリに飯食いに行けさっさと帰れってメッセージを飛ばすだけのbotであるため、要件には相応しくないと判断した。
そんなわけでGASの利用は見送り、普通にスクリプト書いてどっかのサーバーに置いといてcronで実行させればいいだろうという結論に至った。やりたいことはChatWork APIにPOSTするだけなのでシェルスクリプトでも書けそうだが今回はPHPで書くことにした。ていうかシェルスクリプト苦手。
また、休日にも送られてくると鬱陶しいので土日祝日は除き平日のみメッセージが飛ぶようにする。
毎日同じメッセージなのも芸がないので複数のメッセージを登録しておきランダムに飛ばそう。
ChatWork API利用の下準備
前置きが長くなったが、ここから実装の話。
とりあえずChatWork APIの利用申請を行う。
http://developer.chatwork.com/ja/
から申請して数時間ほど待てば利用できるようになったよーってメールが来るのでおとなしく待とう。
利用可能になったら、APIトークンを取得しメモっておく。
http://developer.chatwork.com/ja/authenticate.html
で、メッセージを送信するには該当のroom idが必要になるわけだが、そこはブラウザでChatWorkにログインすれば確認できる。
https://www.chatwork.com/#!ridxxxxxxxx
のrid以下の数字がroom id。これで下ごしらえはOK。
ChatWork APIを叩いてみよう
API ドキュメントを読みとりあえず黒い画面から叩いてみる。
http://developer.chatwork.com/ja/endpoints.html
1 |
curl -X POST -H "X-ChatWorkToken: 自分のAPIトークン" -d "body=Hello+ChatWork%21" https://api.chatwork.com/v2/rooms/{room_id}/messages |
リクエストヘッダにAPIトークン書いてボディにメッセージ文字列を書いて送るだけ。試験的にマイチャットにでも飛ばせばよかろう。わーいできたー!
PHPでPOSTするコードを書いてみる
ではこれをPHPで書いてみよう。
そのままcURLを使おうとも思ったが、cURLが動かない環境だったらよろしくないような気がしたのでfile_get_contentsを使うことにした。
file_get_contents関数はその名の通りGET(ダウンロード)するためだけのものだと思っていたのだが、httpメソッドを指定してあげればPOSTでもPUTでもできるらしい。知らなかった、命名に文句を言いたい。
ランダムメッセージは、配列に入れておいてarray_rand関数を使えばよさげ。
あとは適切な形にパースしてPOSTするだけなのだが、祝日の判定ってどうやるんだ?cronでできるのは曜日判定までであって祝日判定なんてできないはずだ。
Google先生に聞いてみると俺のカレンダーAPI叩いて持ってけよって言ってたり内閣府が公表する祝日情報を拾えとかって出てくる。なんとなくパースするのが面倒そうな予感がするので先人の知恵を拝借することにした。
http://s-proj.com/utils/holiday.html
こちらにある平日か祝日かの判定をholiday or elseで返してくれるAPIを利用させていただく。ありがたや。
http://s-proj.com/utils/checkHoliday.php
ちょっと叩いてみたが来年以降の日付を指定するとerrorが返ってくる。年が変わると更新されるのだろうか。ダメだったら暇な時間にちゃんとGoogleから引っ張ってくるように仕様変更するとしてとりあえず実装する。
作者様の言うとおりholiday or elseで条件分岐して実行するだけ。あとは正常に動くことを神に祈る。
できあがったコードはこんな感じ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<?php /*Settings*/ $api_token = "xxxxxxxx";//set API token $room_id = "yyyyyyyy";//set room id $chatwork_api_url = "https://api.chatwork.com/v2/rooms/".$room_id."/messages";//set API URL $check_holiday_url = "http://s-proj.com/utils/checkHoliday.php"; $holiday_flg = file_get_contents($check_holiday_url);//this API will return "holiday" if today is a holiday, if not return "else" $headers = array( "X-ChatWorkToken: ".$api_token, );//set API token on request header $messages = array( "[info][title]お疲れさまです[/title]13時になりました。美味しいご飯を食べてしっかり休んで午後からも頑張りましょう♪[/info]", "[info][title]お疲れさまです[/title]13時になりました。食わずに働け豚![/info]", );//set messages /*post message to ChatWork API function*/ function postMessageToChatWork(){ global $api_token; global $room_id; global $chatwork_api_url; global $headers; global $messages; $headers = implode("\r\n", $headers);//convert array of $headers into strings $key = array_rand($messages);//get random key from array of $messages $contents = array( "body" => $messages[$key], );//set request body $contents = http_build_query($contents);//convert array of $contents into a query string $options = array("http" => array( "method" => "POST", "header" => $headers, "content" => $contents, ));//set http requests $options = stream_context_create($options);//convert array of $options into a stream context file_get_contents($chatwork_api_url, false, $options);//POST data! }; /*if today is not a holiday, execute postMessageToChatWork function*/ if($holiday_flg == "else"){ postMessageToChatWork(); }; |
ウルトラ簡単にできた。便利な世の中である。
cronに登録して運用する
できあがったら適当なサーバーにアップロードし、cronに登録して任意の時間に実行するようにしておけばよい。
1 |
0 13 * * 1-5 /path/to/php /path/to/script/directory/bot.php |
多分こんな感じで月曜から金曜の13時に実行されるはず。前述の通り祝日除外処理はPHP側に任せた。
天使と悪魔のようなメッセージを登録しておいたので、これで今日の昼休みにご飯が食べられるかどうかは運次第という素敵な会社になれる。わーい。
運用していく内にメッセージが溜まっていくと鬱陶しくなりそうなので一つ前に送信したメッセージは削除するようにしたかったのだが、今のところメッセージを削除するエンドポイントは実装されてないっぽい。今後に期待。
おまけ
RESTなAPIがもてはやされている昨今だが、実際に叩いてみるとこれがいかに便利であるか痛感できる。javaScriptでajax使えば自前のChatWorkクライアントなんかも簡単に作れそうだ。
余談だが、実際には昼休みの時間になると通知と共にオススメランチがランダムで出力されるようにした。何を食べるか考えるのすらめんどくさい筆者にとってはたったこれだけでも助かる。もっとカスタマイズして例えば今日の気候をチェックしそれに基づいたサジェストが出るとかそんなところまでやったら楽しそう。
AIに人間が支配されてうんたらなんて警鐘を鳴らす人もいるが、それは一概に悪いこととは言えず機械的に管理できるところは機械に任せてしまえば良いのではないだろうか。