1
0

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 1 year has passed since last update.

LINEAPI・GASを使ってゴミ出し通知・応答Botを作ってみた

Posted at

初めての投稿です。。。

開発動機

燃えるゴミは毎週なので忘れないけど、燃えないごみ等は第Xの木曜日だったりして
いつも忘れてしまうので、対象のゴミ出しの日になったらLINEに通知を送ってくれるBOTがあれば忘れないと思い
作成を始めました。
最初は通知のみの機能を予定していましたが、
メッセージをBOTへ送信したら、ゴミの日を返答してくれる機能もあるといいなと思い
こちらも合わせて開発しました。

なぜGASなのか

  • スプレットとの連携が行いやすい
  • サーバーを自前で建てる必要がない
  • GASのトリガーで定期的に実行できる

上記の理由でGASで作成しました。

準備

LINE@の準備

LINEAPIを使用するには、LINE公式アカウントの準備が必要で
以下情報を参考に設定させていただきました。

スプレットの準備

スプレットの関数IMPORTHTML
を使用して
https://www.city.fukuoka.lg.jp/kankyo/kateigomi/life/007hakata.html
よりゴミ出しの日を取得し、スプレットへ転記

実際のスプレットはこんな感じになります

image.png

A1セルにURLをセットしており
A2セルに上記関数をセットしてます。

実装

実際のコードはGitHubに上げましたので、よろしければご覧下さい。

仕様

  • スプレットのF1セルに明記している町名のゴミの日を通知・応答
  • G2~I2までのセルに入力された文字をユーザーから受け取ると、対象のゴミの日を応答する。

詰まった点

GASからLINEAPIを呼び出しメッセージを送信する

LINE公式アカウントより友だち登録されたユーザIDを取得するには
LINE認証アカウントもしくはプレミアムアカウントが必要らしく

それ以外で取得するには、
友達登録したユーザーよりメッセージを送ってもらい、
送られたWebhookよりIDを取得する必要があるみたいです。

なのでメッセージが送られたら、スプレットへユーザーIDを取得する
仕組みを作成しました。

 // WebHookで取得したJSONデータをオブジェクト化し、取得
  let eventData = JSON.parse(e.postData.contents).events[0];

  //postから受け取ったオブジェクトからユーザーIDとタイムスタンプを取得しスプレットに退避
  let userId = eventData.source.userId;
  let timestamp = eventData.timestamp;
  let sheet = spreadSheetByActive.getSheetByName("シート2")
  let row = sheet.getLastRow()

  //2行目からIDを検索し存在する場合は、追加しない
  let idrange = sheet.getRange(2, 1, row).getValues().flat();

  if (idrange.indexOf(userId) === -1) {
    sheet.getRange(row + 1, 1).setValue(userId)
    sheet.getRange(row + 1, 2).setValue(timestamp)
  }

上記コードでスプレットへユーザーIDを溜め込み
GASからメッセージを送る際はスプレットのユーザーIDへ送信するような
作りにしました。

//メッセージを送る際スプレッドシートからIDを取得して送信する
  let sheet = spreadSheetByActive.getSheetByName("シート2")
  let row = sheet.getLastRow()
  let idrange = sheet.getRange(2, 1, row).getValues().flat();
  idrange = idrange.filter(item => item != "");
  if (idrange.length != 0) {
    idrange.forEach(function (item) {
      var postData = {
        "to": item,
        "messages": [
          {
            'type': 'text',
            'text': text,
          }
        ]
      };

      var options = {
        "method": "post",
        "headers": headers,
        "payload": JSON.stringify(postData)
      };

      UrlFetchApp.fetch(url, options);
    })
  }

完成して

現在運用を行っており
GASのトリガーにより、毎日ゴミの日判定を動くようにし
対象のゴミの日の場合は、LINEAPIにメッセージを投げるようにしてます。

image.png

公式アカウントの機能としてリッチメニューという機能が用意されており
下記サイトにアクセスすることで
このようなトークルームへ変更することが可能です。

Screenshot_20230124-230301.png

各メニューを押下することで、対象のゴミの日を返答してくれるように
しました。

初めてGAS+APIを使った開発を行いましたが、GASからAPIへ応答をする際に
エラーが起こってもログを吐いてくれないなどがあり、なかなか手こずりましたが
(スプレットへログを吐いたりしてデバッグを行ってました・・・

無事完成までたどり着けたので良かったです。
もしご指摘やご意見などありましたら遠慮なくお願いします。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?