マイクロソフトやLINE、Facebookが人工知能を使ったBotのプラットフォームを公開しだしたので早速自分も弄くってみました。
今回はFacebookのMessenger上に最新の地震情報を10件取得するBotを作成しました。(本当はLINE BOTでやりたかったんですけど申し込み締め切りで使えませんでした泣)
動作DEMO
今回はどんなメッセージを打ち込んでも最新の地震情報が10件流れてくる仕様にしていますが、「地震」とかメッセージを限定することも可能です。
動作環境
- サーバー:heroku
- 言語:PHP
- 地震API:ガラクタ@P2P地震情報
動作環境は「これからPHPでFacebook Messenger Botづくりを始める人向けの簡易スターターキット」を使って構築しました。環境構築手順はリンク先を参照して下さい。
コード
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
<?php require('../vendor/autoload.php'); use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use GuzzleHttp\Client; $app = new Silex\Application(); $app->register(new Silex\Provider\MonologServiceProvider(), array( 'monolog.logfile' => 'php://stderr', )); $app->before(function (Request $request) use($bot) { // TODO validation }); $app->get('/callback', function (Request $request) use ($app) { $response = ""; if ($request->query->get('hub_verify_token') === getenv('FACEBOOK_PAGE_VERIFY_TOKEN')) { $response = $request->query->get('hub_challenge'); } return $response; }); $app->post('/callback', function (Request $request) use ($app) { // Let's hack from here! $body = json_decode($request->getContent(), true); $client = new Client(['base_uri' => 'https://graph.facebook.com/v2.6/']); foreach ($body['entry'] as $obj) { $app['monolog']->addInfo(sprintf('obj: %s', json_encode($obj))); foreach ($obj['messaging'] as $m) { $app['monolog']->addInfo(sprintf('messaging: %s', json_encode($m))); $from = $m['sender']['id']; $text = $m['message']['text']; if ($text) { $path = sprintf('me/messages?access_token=%s', getenv('FACEBOOK_PAGE_ACCESS_TOKEN')); $eqxml_url = 'http://api.p2pquake.com/v1/human-readable?limit=11'; $json = file_get_contents($eqxml_url); $json = mb_convert_encoding($json, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN'); $eq_data = json_decode($json,true); if($eq_data === NULL){ $eq_out = '地震情報がありませんでした'; } else { foreach( $eq_data as $key => $value ) { $eq_time = $eq_data[$key]['time']; $eq_earthquake = $eq_data[$key]['earthquake']; if ($eq_earthquake === NULL ) { } else { $eq_name = $eq_data[$key]['earthquake']['hypocenter']['name']; if ($eq_name == '') { $eq_name = '不明'; } $eq_scale = $eq_data[$key]['earthquake']['maxScale']; if ($eq_scale == 0) { $eq_scale_out = 'なし'; } elseif ($eq_scale == 10) { $eq_scale_out = '震度1'; } elseif ($eq_scale == 20) { $eq_scale_out = '震度2'; } elseif ($eq_scale == 30) { $eq_scale_out = '震度3'; } elseif ($eq_scale == 40) { $eq_scale_out = '震度4'; } elseif ($eq_scale == 45) { $eq_scale_out = '震度5弱'; } elseif ($eq_scale == 50) { $eq_scale_out = '震度5強'; } elseif ($eq_scale == 55) { $eq_scale_out = '震度6弱'; } elseif ($eq_scale == 60) { $eq_scale_out = '震度6強'; } elseif ($eq_scale == 70) { $eq_scale_out = '震度7'; } $eq_mag = $eq_data[$key]['earthquake']['hypocenter']['magnitude']; $eq_depth = $eq_data[$key]['earthquake']['hypocenter']['depth']; $eq_out = "発生時刻:" . $eq_time . "\n震源地:" . $eq_name . "\n最大震度:" . $eq_scale_out . "\nマグニチュード:" . $eq_mag . "\n深さ:" . $eq_depth; $json = [ 'recipient' => [ 'id' => $from, ], 'message' => [ 'text' => sprintf($eq_out), ], ]; $client->request('POST', $path, ['json' => $json]); } } } } } } return 0; }); $app->run(); |
上記のindex.phpは先程紹介したスターターキットをもとに制作しています。簡単な流れを言うとFacebookのメッセンジャーに接続して地震情報APIから地震情報を引っ張ってきて情報を加工してPOSTしてる感じです。
1 |
$eqxml_url = 'http://api.p2pquake.com/v1/human-readable?limit=11'; |
上の32行目にあるurlの一番後ろの数字を変更すると取得する地震件数が変わります。
ハマったところ
DEMOを見てもらうとわかるのですが、地震1件に対して1POST(投稿)にしています。元々、1POST内に10件の地震情報を詰め込んでいたのですが、どうやら文字数制限?があるようでうまく動作しませんでした。(ドキュメントを読んでいるわけではないのでわかる方いたら教えて下さい。)よってforeachの反復処理ごとにPOSTをしています。
2,3時間で簡単にBotを作れて面白かったです。次回は「形態素解析とマルコフ連鎖」使って言語処理してみたいなと思っております。
(´-`).。oO(このBot分野、仕事になるんだろうか…)