天気予報を取得してLINEに通知を送る その2
はじめに
プログラム初心者です。
GoogleAppScriptで書いてます。
前回の記事はこちら
https://qiita.com/taisatol/items/df399b47321bcb1e8d2a
構成
天気予報のWeb APIを取得
Livedoor天気:http://weather.livedoor.com/weather_hacks/webservice
Japan Weather Forecast xml:http://www.drk7.jp/weather/
↓
必要なお天気情報を取り出しテキストを整形
今日明日の天気
最高/最低気温
降水確率
↓
LINE Notifyにテキストを送る
今回の課題
- 天気予報APIから降水確率を取得
- XML形式の読み込みに挑戦
- livedoor天気のAPI内にある天気アイコンをLINEに表示させる
- お天気アイコンの画像URLをLineNotifyに送る
- 表示できませんでした(詳細は後述)
コード
main
//LineNotifyにメッセージを送信
function sendHttpPost(message){
//Linenotify token
var token = " -LineNotify Token- ";
var options =
{
"method" : "post",
"payload" : "message=" + message,
"headers" : {"Authorization" : "Bearer "+ token}
};
UrlFetchApp.fetch("https://notify-api.line.me/api/notify",options);
}
//メインルーチン
function whether_mail_day() {
//Japan Weather Forecast xmlからXML形式のWEBAPIをリクエスト
var response2 = UrlFetchApp.fetch(" -XML URL- ");
var xml = XmlService.parse(response2.getContentText());
//xmlから時間帯ごとの降水確率を取得 (pref.area.info.rainfallchance.period)
var rainfallchance = xml.getRootElement().getChildren('pref')[0].getChildren('area')[1].getChildren('info');
var rainfallchance2 = rainfallchance[0].getChildren('rainfallchance')[0].getChildren('period');
//livedoor天気からjson形式のWEBAPIをリクエスト
var response = UrlFetchApp.fetch(" -Json URL- ");
var json=JSON.parse(response.getContentText());
//jsonから最高/最低気温を取得 (forcasts.temperature.celsius)
//日時(i),最高/最低(j)でforループ
//気温がnullの場合--に変換
var maxMin = ["max","min"];
var Temp = new Array(2);
for(var i = 0; i < 2; i++){
Temp[i] = new Array(2)
for(var j = 0; j < 2; j++){
if(json["forecasts"][i]["temperature"][maxMin[j]] == null){
Temp[i][j] = "--";
}else{
Temp[i][j] = json["forecasts"][i]["temperature"][maxMin[j]]["celsius"];
}
}
}
//送信用文字列の作成
//日時(i)、時間帯(j)でforループ
var strBody = "天気予報";
for(var i = 0;i < 2;i++){
strBody = strBody + "\n" + date[i] + " : " + json["forecasts"][i]["telop"]
+ "\n" + "最低 : " + Temp[i][1] + "℃ 最高 : " + Temp[i][0] + "℃"
+ "\n" + "降水確率";
//降水確率の要素から値を取得
for(var j = 0; j < rainfallchance2.length; j++) {
strBody = strBody + "\n" + rainfallchance[i].getChildren('rainfallchance')[0].getChildren('period')[j].getAttribute("hour").getValue()
+ " : " + rainfallchance[i].getChildren('rainfallchance')[0].getChildren('period')[j].getText() + "%";
}
};
sendHttpPost(strBody);
}
//LineNotifyにメッセージを送信
function sendHttpPost(message){
//Linenotify token
var token = " -LineNotify Token- ";
var options =
{
"method" : "post",
"payload" : "message=" + message,
"headers" : {"Authorization" : "Bearer "+ token}
};
UrlFetchApp.fetch("https://notify-api.line.me/api/notify",options);
}
//メインルーチン
function whether_mail_day() {
//Japan Weather Forecast xmlからXML形式のWEBAPIをリクエスト
var response2 = UrlFetchApp.fetch(" -XML URL- ");
var xml = XmlService.parse(response2.getContentText());
//xmlから時間帯ごとの降水確率を取得 (pref.area.info.rainfallchance.period)
var rainfallchance = xml.getRootElement().getChildren('pref')[0].getChildren('area')[1].getChildren('info');
var rainfallchance2 = rainfallchance[0].getChildren('rainfallchance')[0].getChildren('period');
//livedoor天気からjson形式のWEBAPIをリクエスト
var response = UrlFetchApp.fetch(" -Json URL- ");
var json=JSON.parse(response.getContentText());
//jsonから最高/最低気温を取得 (forcasts.temperature.celsius)
//日時(i),最高/最低(j)でforループ
//気温がnullの場合--に変換
var maxMin = ["max","min"];
var Temp = new Array(2);
for(var i = 0; i < 2; i++){
Temp[i] = new Array(2)
for(var j = 0; j < 2; j++){
if(json["forecasts"][i]["temperature"][maxMin[j]] == null){
Temp[i][j] = "--";
}else{
Temp[i][j] = json["forecasts"][i]["temperature"][maxMin[j]]["celsius"];
}
}
}
//送信用文字列の作成
//日時(i)、時間帯(j)でforループ
var strBody = "天気予報";
for(var i = 0;i < 2;i++){
strBody = strBody + "\n" + date[i] + " : " + json["forecasts"][i]["telop"]
+ "\n" + "最低 : " + Temp[i][1] + "℃ 最高 : " + Temp[i][0] + "℃"
+ "\n" + "降水確率";
//降水確率の要素から値を取得
for(var j = 0; j < rainfallchance2.length; j++) {
strBody = strBody + "\n" + rainfallchance[i].getChildren('rainfallchance')[0].getChildren('period')[j].getAttribute("hour").getValue()
+ " : " + rainfallchance[i].getChildren('rainfallchance')[0].getChildren('period')[j].getText() + "%";
}
};
sendHttpPost(strBody);
}
実行結果
天気予報
mm/dd : 晴れ
最低 : --℃ 最高 : XX℃
降水確率
00-06 : XX%
06-12 : XX%
12-18 : XX%
18-24 : XX%
mm/dd : 晴時々曇
最低 : XX℃ 最高 : XX℃
降水確率
00-06 : XX%
06-12 : XX%
12-18 : XX%
18-24 : XX%
おわりに
わかったこと
- GASにおけるXML形式の読み込み方
- GASではid要素の名前を指定して読み込めないらしい(Javascriptでは
getElementById()
で実装できる?)
- LineNotifyへお天気アイコンの画像を送れなかった
- LineNotifyはjpgとpng形式のみ対応で、gif形式であるお天気アイコンは不可のようです
- GASではid要素の名前を指定して読み込めないらしい(Javascriptでは
getElementById()
で実装できる?)
- LineNotifyはjpgとpng形式のみ対応で、gif形式であるお天気アイコンは不可のようです
ちなみに画像をURLとして送る際はコードを以下のようにしたら動きました。
//LineNotifyにメッセージを送信
function sendHttpPost(message,url){
//Linenotify token
var token = "-LineNotify Token-";
var payload =
{
"message" :message,
"imageThumbnail" : url,
"imageFullsize" :url
};
var options =
{
"method" : "post",
"payload" : payload,
"headers" : {"Authorization" : "Bearer "+ token}
};
- パラメータ
imageThumbnail
は必須 - 画像はメッセージと別投稿になってしまう
課題
- 2つの天気予報APIを使っているので、時間帯によっては日時の整合性が取れない場合が想定される
- 日時を抜き出して比較する?
- 日時が違っていた場合どう合わせるか?
- 絵文字で天気を表示したい
- 絵文字の表示方法
- 取得した天気予報と表示する絵文字を対応させる
- コードを綺麗にしたい
- 特にXMLから要素を拾うときがスマートでない気がする 関数化してみたい
参考サイト様
http://unguis.cre8or.jp/web/6883
https://engineering.linecorp.com/ja/blog/detail/88
https://qiita.com/SKYS/items/39c0d300a6581f831023
Author And Source
この問題について(天気予報を取得してLINEに通知を送る その2), 我々は、より多くの情報をここで見つけました https://qiita.com/taisatol/items/c0fb7d436753345e715e著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .