LINE BOTで登録した予定を通知させる

LINE

今回はLINE Botで予定を登録して、それを通知させてみようと思います。

LINE Messaging API + Google Apps Script (GAS)を使いますが、LINEアカウントとGmailアカウントは保有している前提です。

  1. まずはLINE Developersの登録をします。LINE Developersを活用することで、既存システムにLINEとの連携を組み込んだり、Botを制作できます。

  https://developers.line.biz/ja/

下記のチャネル設定ですが、真ん中のMessaging APIを選択します

チャネル名、チャネル説明、大業種、小業種、メールアドレス の必須項目を入力して規約のチェックボックスにチェックをつけると作成ボタンを押せるようになります。

作成出来ました。

チャネル詳細画面に戻ってチャネルアクセストークンを発行します。GAS側で使用する重要なトークンです。

応答設定は挨拶メッセージと応答メッセージをオフにして、Webhookはオンにしておきます。

2.Google Apps Script(GAS)との連携

Google Driveに接続します。ドライブの中にGASがない場合は【アプリを追加】を選択してGoogle Apps Scriptと入力して追加します。

今回はGoogle Calenderに予定を追加するコードを入力していきます。そのままコピペでOKです。GASでファイルを新規作成してください。チャネルアクセストークンはダブルクォーテーションは残したまま書き換えればOKです。

var CHANNEL_ACCESS_TOKEN = "************";
var dateExp = /(\d+)\/(\d+)\s(\d+):(\d+)/;

//doPost関数(Lineからメッセージを受け取る)
function doPost(e) {
    GetMessage(e);
}

//受け取ったメッセージの処理
function GetMessage(e) {
  var replyToken = JSON.parse(e.postData.contents).events[0].replyToken;
  if (typeof replyToken === 'undefined') {
    return;
  }
  var messageText = JSON.parse(e.postData.contents).events[0].message.text;
  var cache = CacheService.getScriptCache();
  var type = cache.get("type");

  if (type === null) {
    //予定の追加
    if (messageText === "予定の追加") {
      cache.put("type", 1);
    //開始日時の質問
      replyPlans(replyToken, "予定日をいずれかの形式で教えてください。", "12/1\n3:00", "4/1 13:00");
    //今日、7日間の予定の取得
    } else if (messageText.match("今日の予定")) {
      reply(replyToken, getEvents());
    }  else if (messageText.match("今週の予定")) {
      reply(replyToken, notifyWeekly());
    } else {
    //処理方法の返答
      replyPlans(replyToken, "「予定の追加」で予定追加します", "「今日の予定」で今日の予定をお知らせします。", "「今週の予定」で7日間の予定をお知らせします。");
    }
  } else {
    //キャンセル処理
    if (messageText === "キャンセル") {
      cache.remove("type");
      reply(replyToken, "予定追加のキャンセルをしました");
      return;
    } 

    switch(type) {
      case "1":
        // 開始日時の追加
        if ( messageText.match(dateExp)) {
          var [matched, start_month, start_day, start_Hour, start_Min] = messageText.match(dateExp);
          cache.put("type", 2);
          cache.put("start_month", start_month);
          cache.put("start_day", start_day);
          cache.put("start_hour", start_Hour);
          cache.put("start_min", start_Min);
          //終了日時の質問
          var year = new Date().getFullYear();
          //var year = 2020;
          var startDate = new Date(year, cache.get("start_month") - 1, cache.get("start_day"), cache.get("start_hour"), cache.get("start_min"));
          reply(replyToken,"開始日時は\n" + EventFormat(startDate) + "\nですね。\n\n次に予定の終了日時をお知らせください。");
          break;
        }else{
          reply(replyToken, "予定追加処理中です。\n「キャンセル」\nで追加作業をキャンセルします。");
          break;
        }
      case "2":
        // 終了日時の追加
        if ( messageText.match(dateExp)) {
          var [matched, end_month, end_day, end_Hour, end_Min] = messageText.match(dateExp);
          cache.put("type", 3);
          cache.put("end_month", end_month);
          cache.put("end_day", end_day);
          cache.put("end_hour", end_Hour);
          cache.put("end_min", end_Min);
          //予定名の質問
          var year = new Date().getFullYear();
          //var year = 2020;
          var endDate = new Date(year, cache.get("end_month") - 1, cache.get("end_day"), cache.get("end_hour"), cache.get("end_min"));
          reply(replyToken,"終了日時は\n" + EventFormat(endDate) + "\nですね。\n\n最後に予定名を教えてください。");
          break;
        }else{
          reply(replyToken, "予定追加処理中です。\n「キャンセル」\nで追加作業をキャンセルします。");
          break;
        }
      case "3":
        // 最終確認
        cache.put("type", 4);
        cache.put("title", messageText);
        var [title, startDate, endDate] = createData(cache);
        //予定追加の確認
        replyPlans(replyToken, "予定名:" + title, "開始日時:\n" + EventFormat(startDate)+ "\n終了日時:\n" + EventFormat(endDate), "予定を追加しますか?\n 「はい」か「いいえ」でお知らせください。");
        break;
      case "4":
        if (messageText === "はい") {
          cache.remove("type");
          var [title, startDate, endDate] = createData(cache);
          CalendarApp.getDefaultCalendar().createEvent(title, startDate, endDate);
          reply(replyToken, "Googleカレンダーに予定を追加しました");
        } else if (messageText === "いいえ") {
          cache.remove("type");
          reply(replyToken, "予定の追加をキャンセルしました。");
        } else{
          reply(replyToken, "「はい」か「いいで」でお答えください。");
          break;
        }
        break;
    }
  }
}

function createData(cache) {
  var year = new Date().getFullYear();
  //var year = 2020;
  var title = cache.get("title");
  var startDate = new Date(year, cache.get("start_month") - 1, cache.get("start_day"), cache.get("start_hour"), cache.get("start_min"));
  var endDate = new Date(year, cache.get("end_month") - 1, cache.get("end_day"), cache.get("end_hour"), cache.get("end_min"));
  return [title, startDate, endDate];
}

function EventFormat(Date) {
  var y = Date.getFullYear();
  var m = Date.getMonth() + 1;
  var d = Date.getDate();
  var w = Date.getDay();
  var H = Date.getHours();
  var M = Date.getMinutes();
  var weekname = ['日', '月', '火', '水', '木', '金', '土'];
  m = ('0' + m).slice(-2);
  d = ('0' + d).slice(-2);
  return y + '年' + m + '月' + d + '日 (' + weekname[w] + ')\n' + H + '時' + M + '分';
}

function replyPlans(replyToken, message, message2, message3) {
  var url = "https://api.line.me/v2/bot/message/reply";
  UrlFetchApp.fetch(url, {
    "headers": {
      "Content-Type": "application/json; charset=UTF-8",
      "Authorization": "Bearer " + CHANNEL_ACCESS_TOKEN,
    },
    "method": "post",
    "payload": JSON.stringify({
      "replyToken": replyToken,
      "messages": [{
        "type": "text",
        "text": message,
      },{
        "type": "text",
        "text": message2,
      },{
        "type": "text",
        "text": message3,
      }],
    }),
  });
  return ContentService.createTextOutput(JSON.stringify({"content": "post ok"})).setMimeType(ContentService.MimeType.JSON);
}

function reply(replyToken, message) {
  var url = "https://api.line.me/v2/bot/message/reply";
  UrlFetchApp.fetch(url, {
    "headers": {
      "Content-Type": "application/json; charset=UTF-8",
      "Authorization": "Bearer " + CHANNEL_ACCESS_TOKEN,
    },
    "method": "post",
    "payload": JSON.stringify({
      "replyToken": replyToken,
      "messages": [{
        "type": "text",
        "text": message,
      }],
    }),
  });
  return ContentService.createTextOutput(JSON.stringify({"content": "post ok"})).setMimeType(ContentService.MimeType.JSON);
}

//今日の予定
function getEvents() {
  var events = CalendarApp.getDefaultCalendar().getEventsForDay(new Date());
  var body = "今日の予定は";

  if (events.length === 0) {
    body += "ありません。";
    return body;
  }

  body += "\n";
  events.forEach(function(event) {
    var title = event.getTitle();
    var start = HmFormat(event.getStartTime());
    var end = HmFormat(event.getEndTime());
    body += "★" + title + ": " + start + " ~ " + end + "\n";
  });
  body += "です。";
  return body;
}

//7日間の予定
function notifyWeekly() {
  var  body = "7日間の予定は\n";
  var weekday = ["日", "月", "火", "水", "木", "金", "土"];
for ( var i = 0;  i < 7;  i++ ) {

  var dt = new Date();
  dt.setDate(dt.getDate()+i);
  var events = CalendarApp.getDefaultCalendar().getEventsForDay(dt);
  body += Utilities.formatDate(dt, "JST", '★ MM/dd(' + weekday[dt.getDay()] + ')') + "\n";
  if (events.length === 0) {
    body += "ありません。\n";
  }

  events.forEach(function(event) {
    var title = event.getTitle();
    var start = HmFormat(event.getStartTime());
    var end = HmFormat(event.getEndTime());
    body += title + ": " + start + " ~ " + end + "\n";
  });
}
  return body;
}

function HmFormat(date){
  return Utilities.formatDate(date, "JST", "HH:mm");
}

新しくデプロイしますが、アクセスできるユーザーは全員にしておかないとエラーが出るので要注意です。

次にGASファイルを新しく作成します。このコードを入力します。これは登録した予定を自分で設定したルールで通知してくれるためのコードです。カレンダー通知でもいいのですが、LINEを開く回数が多い人は活用出来ると思います。

var CHANNEL_ACCESS_TOKEN = 'アクセストークン';
var USER_ID = 'ユーザーID';

var googleCalendar = {
  "***********@gmail.com" : "予定",
  "ja.japanese#holiday@group.v.calendar.google.com": "祝日",
};

var weekday = ["日", "月", "火", "水", "木", "金", "土"];
function pushWeekly() {

  var calendars = CalendarApp.getAllCalendars();
  var dt = new Date()
  var message = "1週間の予定です。\n\n";

  for ( var i = 0;  i < 7;  i++ ) {

    dt.setDate(dt.getDate() + 1);
    message += Utilities.formatDate(dt, 'JST', '★ MM/dd(' + weekday[dt.getDay()] + ')') + "\n";

    var dayText = "";
    for(g in calendars) {
      var calendar = calendars[g];

      var calendarName = googleCalendar[calendar.getId()]
      if ( calendarName == undefined ) {
        continue;
      }

      var events = calendar.getEventsForDay(dt);
      if( events.length == 0 ) {
        continue;
      }

      dayText += "< " + calendarName + " >\n";
      for(g in events) {
        dayText += DayText(events[g]);
      }
      dayText += "\n"
    }

    if ( dayText == "") {
        dayText += "予定はない\n\n";
    }
    message += dayText;
  }

  sendToLine(message);
}

function sendToLine(message){
    //deleteTrigger();
  var postData = {
    "to": USER_ID,
    "messages": [{
      "type": "text",
      "text": message,
    }]
  };

  var url = "https://api.line.me/v2/bot/message/push";
  var headers = {
    "Content-Type": "application/json",
    'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
  };

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

function DayText(event) {
  return TimeText(event.getStartTime()) + ' - ' + TimeText(event.getEndTime()) + " " + event.getTitle() + '\n';
}

function TimeText(str){
  return Utilities.formatDate(str, 'JST', 'HH:mm');
}

アクセスチャネルトークン、USER ID、Gmailアドレスを入力します。

次に左端にある時計マークをクリックしてトリガーを設定します。下記のように設定すると毎朝9時〜10時に7日間の予定が通知されるようになります。

結構使えるので是非試してみてください。^^

kazuhiro

旅行が趣味で、国内外さまざまな場所を訪れています。外資系企業で働きながら、副業として不動産投資も行っています。 https://vdhqm2p0.autosns.app/line

特集記事

コメント

この記事へのコメントはありません。

TOP
CLOSE