myThings DevelopersでYahoo!天気の「雨が降りそうなら」をトリガーにして、Herokuで受け付けた後にLINE Botでつぶやいてみた。
つぶやきまでの流れ
myThingsで雨雲検知→ Herokuで対象の地域の緯度、経度 → LINE BotでPush送信 → 雨雲を確認
myThings Developersの設定
トリガー : Yahoo!天気「雨が降りそうなら」を選択
アクション : カスタムトリガーを選択
その他設定 : 任意(テスト時は地域や日時が固定して送信されるので)
カスタムトリガーの設定
アクション名 : 自由に設定
リクエストURL: Herokuを利用したので、https://[app名].herokuapp.com/
シークレット : 未使用
Herokuに実装する処理
利用した言語はPHP。
処理の流れ
- myThingsからのデータを取得
- Yahoo!デベロッパーネットワークのYOLP(地図)を利用して地域の緯度、経度を取得
- LINE BotにURL付きのメッセージをPush送信
1. myThingsからのデータを取得
myThingsから受信するデータ
{"user_id":"[各自のuser_id]","service_id":"[各自のサービスID]","mythings_id":"[各自のmyThings ID]":[{"area":"\uff1c\u30c6\u30b9\u30c8\u5b9f\u884c\uff1e\u6771\u4eac","datetime":"2017-01-01 00:00","time":"00:00","date":"2017-01-01","rainfall":"1"}]}
この中からareaとdatetimeを利用します。areaにユーザーが選択した雨雲をチェックする地域、datetimeに日時が入ります。
2. Yahoo!デベロッパーネットワークのYOLP(地図)を利用して地域の緯度、経度を取得
Yahoo!デベロッパーネットワークのYOLP(地図)の、Yahoo!ジオコーダAPIを利用して、areaの地域名から緯度、経度を取得します。
※このAPIを利用するには、Yahoo!デベロッパーネットワークでアプリケーションを登録して、アプリケーションIDを取得する必要があります。
3. LINE BotにURL付きのメッセージをPush送信
ソースを参照
※ソースでは特定のLINEユーザーのuserid向けにPush送信を実施。useridはBOTがLINEユーザーからメッセージを受けた時のeventから調べることができます。
ソース
<?php
require_once __DIR__ . '/vendor/autoload.php';
// LINE BOTの処理
$httpClient = new \LINE\LINEBot\HTTPClient\CurlHTTPClient(getenv('CHANNEL_ACCESS_TOKEN'));
$bot = new \LINE\LINEBot($httpClient, ['channelSecret' => getenv('CHANNEL_SECRET')]);
$signature = $_SERVER["HTTP_" . \LINE\LINEBot\Constant\HTTPHeader::LINE_SIGNATURE];
# 1. myThingsからのデータを取得
$phpInput = file_get_contents('php://input');
$jsonObj = json_decode($phpInput);
// myThingsの地域の取得
$unicode_escape = $jsonObj->values[0]->area;
$area = preg_replace_callback('|\\\\u([0-9a-f]{4})|i', function($matched){
return mb_convert_encoding(pack('H*', $matched[1]), 'UTF-8', 'UTF-16');
}, $unicode_escape);
// myThingsのテスト実行では、"<テスト実行>東京"となるため、"<テスト実行>"を除去
$area = str_replace("<テスト実行>", "", $area);
$area_urlencode = urlencode($area);
# 2. Yahoo!デベロッパーネットワークのYOLP(地図)を利用して地域の緯度、経度を取得
# myThingsの日時の取得
$datetime = $jsonObj->values[0]->datetime;
// 地域から緯度、経度を求める
$base_url = "https://map.yahooapis.jp/geocode/V1/geoCoder?appid=[取得したアプリケーションID]&output=json&query=";
$curl = curl_init();
$option = [
CURLOPT_URL => $base_url.$area_urlencode,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_RETURNTRANSFER => true
];
curl_setopt_array($curl, $option);
$response = curl_exec($curl);
$area_detail = json_decode($response);
curl_close($curl);
$line_user_id = "[LINEユーザーのuseridを指定]";
$lonlat = $area_detail->Feature[0]->Geometry->Coordinates;
$lonlatArray = explode(",", $lonlat);
$lon = $lonlatArray[0];
$lat = $lonlatArray[1];
// 雨雲の地図を表示するPHPのURLに緯度と経度を設定
$url = "https://[Herokuのapp名].herokuapp.com/map.php?lat=".$lat."&lon=".$lon."&datetime=";
// myThings実行時の日時取得
// datetimeをトリガーを引いた日時と想定
$now = new DateTime($datetime, new DateTimeZone('Asia/Tokyo'));
$nowMsg = "30分後に雨が振ります。今の雨雲はこちら\n".$url.$now->format('YmdHi');
// 30分後の日時取得
$plus30m = clone $now;
$plus30m->add(new DateInterval('PT30M'));
$plus30mMsg = "30分後の雨雲はこちら\n".$url.$plus30m->format('YmdHi');
// 60分後の日時取得
$plus60m = clone $now;
$plus60m->add(new DateInterval('PT60M'));
$plus60mMsg = "60分後の雨雲はこちら\n".$url.$plus60m->format('YmdHi');
# 3. LINE BotにURL付きのメッセージをPush送信
$bot->pushMessage($line_user_id,
(new \LINE\LINEBot\MessageBuilder\MultiMessageBuilder())
->add(new \LINE\LINEBot\MessageBuilder\TextMessageBuilder($nowMsg))
->add(new \LINE\LINEBot\MessageBuilder\TextMessageBuilder($plus30mMsg))
->add(new \LINE\LINEBot\MessageBuilder\TextMessageBuilder($plus60mMsg))
);
?>
myThings Developersでテスト実施
LINEに表示されたメッセージ
雨雲を表示するPHP(map.php)
Yahoo!デベロッパーネットワークのYOLP(地図)の、Yahoo!スタティックマップAPIを利用して、雨雲の地図を表示。
<?php
$lat = $_GET["lat"];
$lon = $_GET["lon"];
$latlon = "lat=".$lat."&lon=".$lon;
$datetime = $_GET["datetime"];
?>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height" />
<title>[LINE Bot]Yahoo! JAPAN スタティックマップAPI 雨雲表示</title>
</head>
<img width="300" height="200" src="https://map.yahooapis.jp/map/V1/static?appid=[取得したアプリケーションID]&<?php echo $latlon;?>&z=15&width=300&height=200&mode=map&overlay=type:rainfall|date:<?php echo $datetime;?>|datelabel:on">
<br>
<p>
<!-- Begin Yahoo! JAPAN Web Services Attribution Snippet -->
<a href="https://developer.yahoo.co.jp/about">
<img src="https://s.yimg.jp/images/yjdn/common/yjdn_attbtn1_250_34.gif" width="250" height="34" title="Webサービス by Yahoo! JAPAN" alt="Webサービス by Yahoo! JAPAN" border="0" style="margin:15px 15px 15px 15px"></a>
<!-- End Yahoo! JAPAN Web Services Attribution Snippet -->
</p>
</body>
</html>
おまけ
LINE BotのReplyの実験をこの前やったので、myThingsIDがリクエストヘッダーに含まれていたらPush、含まれていなかったらユーザーからのメッセージ受信なのでReplyという形で実装してます。
...
// リクエストヘッダー取得
$phpInput = file_get_contents('php://input');
$jsonObj = json_decode($phpInput);
$myThingsId = $jsonObj->mythings_id;
if ($myThingsId == "[自分のmyThingsID]") { // myThingsからデータ受信したのでPush処理
...
}
else { // Reply処理
...
}