LoginSignup
6
7

More than 5 years have passed since last update.

myThingsの雨雲予測をLINE BotでPushするテスト

Last updated at Posted at 2017-06-03

myThings DevelopersでYahoo!天気の「雨が降りそうなら」をトリガーにして、Herokuで受け付けた後にLINE Botでつぶやいてみた。

つぶやきまでの流れ

myThingsで雨雲検知→ Herokuで対象の地域の緯度、経度 → LINE BotでPush送信 → 雨雲を確認

myThings Developersの設定

トリガー  : Yahoo!天気「雨が降りそうなら」を選択
アクション : カスタムトリガーを選択
その他設定 : 任意(テスト時は地域や日時が固定して送信されるので)

カスタムトリガーの設定

アクション名 : 自由に設定
リクエストURL: Herokuを利用したので、https://[app名].herokuapp.com/
シークレット : 未使用

Herokuに実装する処理

利用した言語はPHP。

処理の流れ

  1. myThingsからのデータを取得
  2. Yahoo!デベロッパーネットワークのYOLP(地図)を利用して地域の緯度、経度を取得
  3. 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から調べることができます。

ソース

index.php
<?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でテスト実施

テスト実行1.png

テスト実行2.png

LINEに表示されたメッセージ

line1.jpg

雨雲を表示するPHP(map.php)

Yahoo!デベロッパーネットワークのYOLP(地図)の、Yahoo!スタティックマップAPIを利用して、雨雲の地図を表示。

map.php
<?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>

line2.jpg

おまけ

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処理
  ...
}

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7