3
6

More than 5 years have passed since last update.

天気予報を取得してLINEに通知を送る その2

Posted at

はじめに

プログラム初心者です。
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);
}

実行結果

result
天気予報
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形式であるお天気アイコンは不可のようです

ちなみに画像をURLとして送る際はコードを以下のようにしたら動きました。

main
//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

3
6
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
3
6