前回の準備編からの続きです。

コードを書いていく時が一番たのしかったりしますよね。

少し細かい記載をしてますが、最後に全てのコードを記載しているので、急いでいる方は最後だけみるのもありです。

初めに

Google Spread Sheetを新規作成します。

スプレッドシートの名前が「無題のスプレッドシート」になっているので、変更しましょう。

名前はなんでも良いですが、「天気予報」とでもつけておきましょうか。

次に、上のタブから「ツール」⇨「スクリプトエディタ」を押します。

するとエディタが開きます。こちらも「無題のプロジェクト」になっているので、名前をつけておきます。

こちらは、それっぽい感じで「weatherForecast」にしておきます。

メインのコードを書いていく

エディタを開くと最初からmyFunctionメソッドがあるので、

そこに今後記載してく予定のメソッドを記載します。

今回は以下の三つだけかな〜と想像して書く。

  • 天気予報データの取得
  • 天気予報データを編集
  • 編集したデータをメールで知らせる
function myFunction() {
  var data    = parseJson();
  var content = createTemplate(data);
  sendMail(content);
}

データの取得

準備編で用意した天気予報APIにアクセスし、

取得する天気の地域のIDを全国の地点定義表から探します。

今回は例なので、与那国島にしときます。

与那国島であれば、IDは「474020」になります。

まず、データの取得処理から書いていきます。メソッド名はparseJson()です。

今回の天気予報APIはJSONデータで提供されている為、HTTPクライアントクラスでAPIに接続します。

HTTPの結果はgetCntentText()でボディを取得します。

function parseJson() {
  // 与那国島のIDを指定してURLを記載
  var feedURL  = "https://weather.tsukumijima.net/api/forecast/city/474020";
  // HTTPクライアントクラスでAPIに接続
  var response = UrlFetchApp.fetch(feedURL);
  return JSON.parse(response.getContentText());
}

これでとりあえずデータの取得は完了です。

取得したデータでHTMLを作成

データはAPIホームページに記載のレスポンスフィールドを確認して、欲しいデータを記載していきます。

また、今回のAPIは3日分の天気予報の情報をもってます。

3日分の表示方法についてはレスポンスフィールドには詳しく書かれていない?というかあまり読んで無い。笑

なので、実際のJSONデータを確認してみると、プロパティのforecastsは3日分の配列になっている事がわかります。

※JSONデータを見る場合はparseJson()メソッド内に記載したURLをクリックすると見れます。

という事で、3日分の天気が欲しい為、data.forecasts.lengthと記載して配列の数を取得します。

以下みたいな感じかな。

function createTemplate(data) {
  // HTMLを作成
  var html  = HtmlService.createTemplateFromFile('mail_template');
  // レスポンスフィールドを定義していく
  html.data = data;
  // 予報日の数
  html.len  = data.forecasts.length;
  // タイトル
  html.title = title;
  // 天気概要文(本文のみ)
  html.bodyText = data.description.bodyText
 
  return html.evaluate().getContent();
}

次に、ファイルの横にある+ボタンを押してHTMLを追加します。

名前は「mail_template」とつけておきます。

先ほど記載した3日分のデータは、

<? for (var i = 0; i < len; i++) { ?> で回して3日分表示させてます。

HTMLの中はこんな感じ。

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <h2><?= title ?></h2>
    <ul style="list-style: none; padding: 0;">
    <p style="display: block;"><?= bodyText ?></p>
      <? for (var i = 0; i < len; i++) { ?>
      <li style="float: left; margin: 0 15px 0 0;">
      <span style="display: block;"><?= data.forecasts[i].dateLabel ?>[<?= data.forecasts[i].date ?>]</span>
      <span style="display: block;"><?= data.forecasts[i].telop ?></span>
      降水確率
      <span style="display: block;">0時~6時:<?= data.forecasts[i].chanceOfRain.T00_06 ?></span>
      <span style="display: block;">6時~12時:<?= data.forecasts[i].chanceOfRain.T06_12 ?></span>
      <span style="display: block;">12時~18時:<?= data.forecasts[i].chanceOfRain.T12_18 ?></span>
      <span style="display: block;">18時~24時:<?= data.forecasts[i].chanceOfRain.T18_24 ?></span>
      <img style="margin: 10px 0" src="<?= data.forecasts[i].image.url ?>" alt="<?= data.forecasts[i].image.title ?>">
      </li>
      <? } ?>
    </ul>
    <hr style="clear: both;">
  </body>
</html>

う〜ん。。試しに実行してみましたが、

src=”<?= data.forecasts[i].image.url ?>”

↑こいつで画像を表示させてますが、GMAILだと認識されてない。。。

少し調べてみるとGMAILだとsgv形式の画像は表示されなんだとか。う〜ん。

よし!削る!!!最後に全体のコードを載せますがその時に削ります。

メール送信

メールを送信する際はこんな感じで記載します。

「to:」の部分はご自身のメールを記載してください。

function sendMail(content) {
  MailApp.sendEmail({
    to: 'xxxxxx@gmail.com',
    subject: '天気予報',
    htmlBody: content
  });
}

スクリプトを実行する

エディタの左ペインにある時計マークのトリガーを押しトリガーと追加します。

以下のように設定してみます。毎日午前7時から8時で天気予報をメールでお知らせしてくれると思います。

実行する関数を選択⇨「myFunction」

実行するデプロイを選択⇨「Head」

イベントのソースを選択⇨「時間主導型」

時間ベースのトリガーのタイプを選択⇨「日付ベースのタイマー」

時刻を選択⇨「午前7時から8時」

トリガーを選択したら保存を押して完了です。

全体的なコード

gsのコード

/**
 * Main Function
 */
function myFunction() {
  var data    = parseJson();
  var content = createTemplate(data);
  sendMail(content);
}

/**
 * Weather Hacks JSON Parse
 * https://weather.tsukumijima.net/api/forecast/city/474020
 * city=474020(与那国島)
 */
function parseJson() {
  // URLを記載
  var feedURL  = "https://weather.tsukumijima.net/api/forecast/city/474020";
  // HTTPクライアントクラスでAPIに接続
  var response = UrlFetchApp.fetch(feedURL);
  return JSON.parse(response.getContentText());
}

/**
 * HTML Template create.
 * ResponseField↓ 
 *   data.forecasts.length
 *   data.description.title
 *   data.description.bodyText
 *   data.forecasts[i].dateLabel
 *   data.forecasts[i].date
 *   data.forecasts[i].telop
 *   data.forecasts[i].chanceOfRain
 */
function createTemplate(data) {
  // HTMLを作成
  var html  = HtmlService.createTemplateFromFile('mail_template');
  // レスポンスフィールドを定義していく
  html.data = data;
  // 予報日の数
  html.len  = data.forecasts.length;
  // タイトル
  html.title = data.description.title;
  // 天気概要文(本文のみ)
  html.bodyText = data.description.bodyText
 
  return html.evaluate().getContent();
}

/**
 * HTML mail send.
 */
function sendMail(content) {
  MailApp.sendEmail({
    to: 'xxxxxx@gmail.com',
    subject: '天気予報',
    htmlBody: content
  });
}

HTMLのコード

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <h2><?= title ?></h2>
    <ul style="list-style: none; padding: 0;">
    <p style="display: block;"><?= bodyText ?></p>
      <? for (var i = 0; i < len; i++) { ?>
      <li style="float: left; margin: 0 15px 0 0;">
      <span style="display: block;"><?= data.forecasts[i].dateLabel ?>[<?= data.forecasts[i].date ?>]</span>
      <span style="display: block;"><?= data.forecasts[i].telop ?></span>
      降水確率
      <span style="display: block;">0時~6時:<?= data.forecasts[i].chanceOfRain.T00_06 ?></span>
      <span style="display: block;">6時~12時:<?= data.forecasts[i].chanceOfRain.T06_12 ?></span>
      <span style="display: block;">12時~18時:<?= data.forecasts[i].chanceOfRain.T12_18 ?></span>
      <span style="display: block;">18時~24時:<?= data.forecasts[i].chanceOfRain.T18_24 ?></span>
      </li>
      <? } ?>
    </ul>
    <hr style="clear: both;">
  </body>
</html>

まとめ

朝起きてすぐスマホを見るので、すぐ天気予報が見れるのは意外と便利かもしれません。

もっといい方法があればこれは廃版になってしまうかもしれませんが…笑

とりあえず、使っていこうと思います。無料だし