10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

LINE API × GASで猛暑日クーポンを自動投稿&設定機能をつくる

Last updated at Posted at 2021-06-25

1624593122625.png

概要

前回おこなった 雨の日セール の第二弾。
前回と同じく気象庁のデータをGASで取得し、対象地域の翌日の最高気温が30℃以上なら、LINE公式アカウント(旧LINE@)で猛暑日クーポンを投稿する。といった流れ。更に今回は投稿の基準となる"しきい値"を設定できるようにする。

前回より

前回の 雨の日セール をテスト運用中、「しきい値を変更できたら有難い」という声を頂いたので、設定機能をつくることに。といっても1からUIをつくる時間も技術も無いのと、GASを使用している事もありスプレッドシートを採用し、しきい値を設定できるようにするのと、ついでに自動投稿を一旦中止する仕組みをつくる。

使用したもの

・LINE Messaging API
・Google Apps Script (GAS)
・気象庁ホームページ
・Google SpreadSheet ←new!

気象データの取得について

取得する方法は前回の 雨の日セール と同じ。

url
https://www.jma.go.jp/bosai/forecast/data/forecast/(area_code).json

(area_code)の所に取得したい地域のコードを入れるとjsonでデータが表示される。

各地域のコード … 気象庁 天気予報より都道府県を指定し遷移後のURL末端にある6ケタの数字

前回と同様に山口県の気象データを取得する。

getForcastData()
  const response = UrlFetchApp.fetch(`https://www.jma.go.jp/bosai/forecast/data/forecast/350000.json`)
  const data = JSON.parse(response)

最高気温30℃以上の判定

元データのサイトを見ると、複数の地域の値があるので前回と同じく中部のデータのみ取得。

上記で取得したデータのうち中部の最高気温の値はここに格納されている。

getForcastData()
data[0].timeSeries[1].areas[1].temps

取得する時間によって格納される値の数が変動する(今日の過ぎた時間帯の値は入らない)ので、今回は格納されている数によって取得する値を変える方法を採用。

getForcastData()
  var maxtemp = getMaxtemp(data); //下の関数を使用

  function getMaxtemp(data){
    var tempArray = data[0].timeSeries[2].areas[1].temps
    if(tempArray.length==4){
      return data[0].timeSeries[2].areas[1].temps[3]
    }else if(tempArray.length ==3){
      return data[0].timeSeries[2].areas[1].temps[2]
    }else if(tempArray.length == 2){
      return data[0].timeSeries[2].areas[1].temps[1]
    }
  }

本題の判定へ。
最高気温が30℃以上なら投稿処理を実行。
下で使っている変数(hotLine)には後で設定するしきい値を格納する。

getForcastData()
/*中略*/
var hotLine = "30" //ここに後述する設定値を格納する

if(maxtemp >= hotLine){
    var tomorrow = new Date();
    tomorrow.setDate(tomorrow.getDate() + 1);
    var tomorrowformat = Utilities.formatDate(tomorrow, 'Asia/Tokyo', 'M/d');
    var title = '【明日は最高気温' + maxtemp + '℃の予報☀ 限定クーポン配信】';
    var header = 'こんばんは\uDBC0\uDC02\n\n'
    var msg = title + '\n\n' + header + '明日' + tomorrowformat + 'の山口は最高気温が' + maxtemp + '℃の予報となっています。お体にお気をつけ下さいませ。\n\n↓猛暑限定クーポンお知らせ↓';
    var imageURL = '販促画像リンク';
    var postData = {
      'messages': [{
      'type': 'text',
      'text': msg
      },{
        "type": "flex",
        "altText": title,
        "contents": {
          "type": "bubble",
          "hero": {
            "type": "image",
            "url": imageURL,
            "size": "full",
            "aspectRatio": "1:1.035",
            "aspectMode": "cover"
          }
        }
      }],
    };
    broadcast_fetch_data(postData);
 }
broadcast_fetch_data()
function broadcast_fetch_data(postData) {
  var options = {
    "method": "post",
    "headers": {
      "Content-Type": "application/json",
      "Authorization": "Bearer " + "LINEのアクセストークン"
    },
    "payload": JSON.stringify(postData)
  };
  UrlFetchApp.fetch("https://api.line.me/v2/bot/message/broadcast", options);
}

あとはGASのトリガーで毎日一定時間に作動させれば無事完了。

設定機能をつくる

前述したようにスプレッドシートでしきい値を設定できるようにするのと、ついでに自動投稿を一旦中止する仕組みをつくる。

仕組みは単純で、
 ・スプレッドシートにしきい値を入力するセルを作成。
 ・GASにてセルの値を取得し、しきい値として使用する。
 ・セルが空白の場合は投稿を中止するようにする。

スプレッドシートに以下の形で作成。
SharedScreenshot.jpg

あと共有して使用するため、値以外のセルは保護&余計な値を入れないよう入力規則を設定。
SharedScreenshot.jpg

念のため(?)100℃まで入力可能に。

しきい値を取得する

GASにてスプレッドシートの値を読み込む。
他の機能の設定値も取得したいので、汎用的な関数を作成。

GetSettingValue()
//値を取得したい項目名を引数に入れる
function GetSettingValue(target) {
  var spreadsheet = SpreadsheetApp.openById("スプレッドシートのId");
  var sheet = spreadsheet.getSheetByName("設定"); //シート名
  var textFinder = sheet.createTextFinder("^" + target + "$").useRegularExpression(true); //検索メソッド。ここでは正規表現で完全一致の条件を指定。
  var ranges = textFinder.findAll();
  
  if(ranges.length >0){
    for (var i = 0; i < ranges.length; i++) {
      // 念のため一致した項目がA列にあるか判定
      if(ranges[i].getColumn() == "1"){
        var index = ranges[i].getRowIndex();
        // セルが空白の場合はnullを返す
        if(sheet.getRange(index, 2).isBlank()) return null
        // セルが空白ではない場合は値を返す
        return sheet.getRange(index, 2).getValue();
      }
    }
  }
}

で、先述した処理に組み込むと以下の形に。
しきい値が空欄の時にはnullを返すので、if文に条件を追加し投稿処理から除外させる。

getForcastData()
/*中略*/
  var hotLine = GetSettingValue("最高気温条件値");

  //明日の最高気温がしきい値以上かつnull以外のとき
  if((maxtemp >= hotLine)&&(hotLine != null)){
    /*前述の投稿処理*/
  }

備考

データの置き場所兼UIとしてスプレッドシートを採用したものの、
最終的には
・UI->LINEのトーク画面(一応完成済)
・データの置き場所-> Firebase
が最適なのかなと日々模索中・・。

10
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
10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?