Help us understand the problem. What is going on with this article?

ゴミの日も記念日も何でも通知してくれるLINE BotをGASで作ってみよう

LINE Botをリマインダ的に活用して生活に役立てるのが流行っていますね。特に、LINE BotのMessaging APIとGoogle Apps Script(通称GAS)との相性が良くて、とても簡単にBotが作れるみたいです。

本記事では、LINE Messaging APIとGASを使って、何でも通知してくれる便利なLINE Botを作ってみたいと思います。

追記

2019/09/12
プログラミングに馴染みのない人が通知設定シートを編集することをイメージし、以下の機能追加と変更を行いました。

  • 新たに「年」を指定できるようにしました。
  • 毎日、毎時といった指定をしたい場合、「*」を入力するのではなく、セルを空白にすれば良いように変更しました。
  • 列の並びを、より日常生活に馴染みのある「年、月、日~」の並びに変更しました。

2019/09/11
思ったよりもいいねが伸びたので、「本文」が空欄だったり、「発言する場所」に不適切な文字が入っていてエラーとなった場合でも、止まらずに次の行の通知の処理へ進むよう微調整しました。

中身のロジックの理解は後回しに、とりあえず動くものを作ってみて欲しいという思いを込めて「新人プログラマ応援」のタグを追加しました。

関連する記事との比較

ゴミの種類を通知するLINE Botは、既にいくつか作ってみた記事があります。やはり分別は面倒ですね。

これらの記事では、ゴミの種類と曜日をコード内で定義しています。例えば、引っ越しをしてゴミの曜日や分別方法が変わった場合、コードを変更する必要があります。本記事では、通知する内容とコードを切り離し、コードがわからない人でも、通知する日時と内容を編集できることを目指します。

設計

以下の3つを利用して、何でも通知してくれるLINE Botを実装します。

  • LINE Messaging API
  • Google スプレッドシート
  • Google Apps Script

LINE Messaging API の準備

通知する内容を喋ってくれるLINE Botのアカウントを作成します。これに関しては、わかりやすく説明してくれる記事が沢山あるので、それに従ってください。

LINE BOTの作り方を世界一わかりやすく解説(1)【アカウント準備編】

アカウントが準備できたら、「チャネル基本設定」>「メッセージ送受信設定」から、「アクセストークン
(ロングターム)」を発行してください。これを後に利用します。

スプレッドシートの準備

Google スプレッドシートを新規作成し、このような形式の表を作成してください。

image.png

表の構成を見ていただければわかるかと思いますが、以下のことが実現できるようになります。

  • 日時や曜日を指定して、狙ったタイミングで通知ができる
  • 毎分、毎時、毎日のように、定期的な通知をしたい場合はセルを空白にすることで実現可能
  • 第1月曜日、第2火曜日のように、何番目の何曜日という指定も可能(ゴミ分別の通知に役立ちます!!
  • 「発言する場所」を指定することで、通知内容ごとに別々の場所で発言できる

※本記事では、「発言する場所」に入力するIDを調べるためのBotの機能も同時に実装します。

シートのサンプルも用意しました。具体的な設定例をなるべく沢山載せておきますので、細かな通知の設定方法はサンプルをご確認ください。

注意点
- 年、月、日、第n週、曜日、時、分、本文、発言する場所という列の並びを変えないこと
- シート名(スプレッドシートの画面下部)を「alarm」とすること
- いずれも変更する場合は後述するGASのコードを変更する必要があります。

Google Apps Scriptのコード

スプレッドシートの「ツール」>「スクリプトエディタ」で、Google Apps Scriptのエディタを開いてください。
image.png

以下のコードをエディタで記入してください。コードはGithubにも一応公開しています。

ここで、ACCESS_TOKEN変数に、LINE Messaging APIの準備で準備した「アクセストークン(ロングターム)」を記載してください。
SHEET_KEYは、スプレッドシートのURLに含まれている文字列です。
https://docs.google.com/spreadsheets/d/{この部分の文字列です!}/edit#gid=0

Code.gs
// 「メッセージ送受信設定」のアクセストークン(ロングターム)を記入してください。
var ACCESS_TOKEN = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';

// 発言させたい日時と内容が書かれたシートのKeyを記入してください。
// シート名には「alarm」としてください。
var SHEET_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';

function doPost(e) {
  var event = JSON.parse(e.postData.contents).events[0];
  var userMessage = event.message.text;

  var message = "";
  if ( userMessage === "ID" ) {
    message = tellID(event);
  }
  else {
    // 疎通確認が終わったらコメントアウトすると良いです。
    message = "メッセージを受け取ったわよ!";
  }

  replyMessage(event.replyToken, message);
  return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}

function replyMessage(token, message) {
  UrlFetchApp.fetch('https://api.line.me/v2/bot/message/reply', {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + ACCESS_TOKEN,
    },
    'method': 'post',
    'muteHttpExceptions': true,
    'payload': JSON.stringify({
      'replyToken': token,
      'messages': [{
        'type': 'text',
        'text': message,
      }],
    }),
  });
}

function pushMessage(to, message) {
  UrlFetchApp.fetch('https://api.line.me/v2/bot/message/push', {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + ACCESS_TOKEN,
    },
    'method': 'post',
    'muteHttpExceptions': true,
    'payload': JSON.stringify({
      'to': to,
      'messages': [{
        'type': 'text',
        'text': message,
      }],
    }),
  });
}

function tellID(event) {
  // ID
  var userID = event.source.userId;
  var talkID = "";
  if (event.source.type === "group") {
    talkID = event.source.groupId;
  } else if (event.source.type === "room") {
    talkID = event.source.roomId;
  }

  var message = "あなたのID: " + userID;
  if (talkID != "") {
    message += "\nこのチャットのID: " + talkID;
  }

  return message;
}

function notice() {
  var sheet = SpreadsheetApp.openById(SHEET_KEY).getSheetByName('alarm');
  var data  = sheet.getDataRange().getValues();

  var dayStr = ["", "", "", "", "", "", ""];
  var now = new Date();
  for (var i=1; i<data.length; i++) {
    var [year, month, dayOfMonth, weekNum, dayOfWeek, hour, minute, message, to] = data[i];

    // 本文と発言する場所が空の場合はスキップ
    if (message === "" || to === "") { continue; }

    if ( (year       ==  now.getFullYear()               || year       === "")
      && (month      ==  now.getMonth() + 1              || month      === "")
      && (dayOfMonth ==  now.getDate()                   || dayOfMonth === "")
      && (weekNum    ==  parseInt(now.getDate() / 7) + 1 || weekNum    === "")
      && (dayOfWeek  === dayStr[now.getDay()]            || dayOfWeek  === "")
      && (hour       ==  now.getHours()                  || hour       === "")
      && (minute     ==  now.getMinutes()                || minute     === "")
      ) {
        pushMessage(to, message);
      }
  }
}

疎通確認

コードが準備できたら、「ウェブアプリケーションとして導入」をしてください。
image.png

注意点
- 「アプリケーションにアクセスできるユーザ」を、「全員(匿名ユーザーを含む)」にすること
- コードを修正した場合は、「プロジェクトバージョン」を「New」に指定し、更新すること

image.png

完了したら、ウェブアプリケーションのURLを、LINE Developerの「チャンネル基本設定」>「メッセージ送受信設定」>「Webhook URL」に入力します。「Webhook送信」も有効化してください。

image.png

「接続確認」に成功すればOKです。

image.png

この状態でBotに何か話かけてみましょう。

image.png

メッセージが返ってくればOKです。

発言先のIDを調べて通知を設定する

通知内容の発言先「発言する場所」に入力するIDを調べてみましょう。通知をさせたいトークルームにBotを招待して、「ID」と発言すればOKです。

image.png

頭文字がUのものが、個人のID、Rのものが、グループではないトークルームのID、Gのものが、グループのトークルームIDのようです。ここで調べたIDを、スプレッドシートの「発言する場所」に記入します。

image.png

トリガーを設定する

時間になったら通知をするためのトリガーを設定します。Google Apps Scriptのエディタから時計マークをクリックしてください。

image.png

トリガーを追加

image.png

実行する関数: notice
イベントのソース: 時間主導型
トリガーのタイプ: 分ベースのタイマー
時間の間隔: 1分おき
image.png

これで設定は一通り完了です。
シートに設定した通りの通知が来れば成功です!

image.png

最後に

通知する内容、日時、通知先をGoogleスプレッドシートで指定可能なLINE Botを作成してみました。このBotを一度設定すれば、GASのコードがわからない家族や友達であっても、スプレッドシートの編集権限を与えて共有することで、各々が好きな内容の通知を好きなトークルームへ設定できるようになります。どこかで活用してくださる方が現れると嬉しいです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした