T.H/ 2022年 9月 29日/ 技術

はじめに

こんにちは。T.H.です。
今回は、Discordのリマインダーbotの作り方です。

経緯

プライベートでDiscordのリマインダーbotを作成する機会があり、忘備録代わりに記載します。
なお、弊社では現在業務でDiscordは利用しておりません。

botの仕様

googleカレンダーから予定を収集し、特定の文字列を含む予定を取得し、1週間前にDiscordの特定のチャンネルにリマインドします。
すべてGAS(Google App Script)上のjava scriptで動作します。

コード

コード全文を載せます。

function remindAttendance() {

  // googleカレンダーを取得
  // 対象のカレンダーID
  const calendarId = 'xxxxxxxxxxx@import.calendar.google.com';
  // カレンダーオブジェクト取得
  const calendar = CalendarApp.getCalendarById(calendarId);

  // 対象日時を取得
  const target_date = new Date();
  target_date.setDate(target_date.getDate() + 7);

  // 指定日(当日)の予定オブジェクトの配列を取得
  const events = calendar.getEventsForDay(target_date);

  // 予定が0件の場合
  if (events.length === 0) {
    console.log("No events found at" + target_date);
  }
  // 予定が1件以上の場合
  else {
    // console.log("Events:");
    // 予定の件数だけ実行
    for (event in events) {

      // 予定のタイトルを取得
      let title = events[event].getTitle();
      // タイトルに'予定'が入っているか
      result = title.indexOf('予定')
      if(result !== -1){
        // 予定の開始時刻・終了時刻を取得
        let startHour = toDoubleDigits(events[event].getStartTime().getHours());
        let startMinute = toDoubleDigits(events[event].getStartTime().getMinutes());
        let endHour = toDoubleDigits(events[event].getEndTime().getHours());
        let endMinute = toDoubleDigits(events[event].getEndTime().getMinutes());

        msg_schedule = title + '(' + startHour + '時' + startMinute + '分~' + endHour + '時' + endMinute + '分)';
        message = '1週間後の予定です!\n' + msg_schedule
        postMessage(message)

      }
    }
  }
}

// メッセージ投稿
function postMessage(message){

  // discord側で作成したボットのウェブフックURL
  const discordWebHookURL = "https://discord.com/api/webhooks/yyyyyyyyyyyy";

  // 投稿するチャット内容と設定
  const messageContents = {
    "content": message, // チャット本文
    "tts": false  // ロボットによる読み上げ機能を無効化
  }

  const param = {
    "method": "POST",
    "headers": { 'Content-type': "application/json" },
    "payload": JSON.stringify(messageContents)
  }

  UrlFetchApp.fetch(discordWebHookURL, param);

}

// 時刻の0埋め用
function toDoubleDigits(num) {
  num += "";
  if (num.length === 1) {
    num = "0" + num;
  }
 return num;     
}

解説

カレンダーの取得

googleカレンダーはcalender idを使用することでコードから利用することができます。

idはgoogle calenderから取得できます。

  // googleカレンダーを取得
  // 対象のカレンダーID
  const calendarId = 'xxxxxxxxxxx@import.calendar.google.com';
  // カレンダーオブジェクト取得
  const calendar = CalendarApp.getCalendarById(calendarId);

指定日の予定を取得

getEventsForDayにて欲しい日程の予定を取得します。この場合は1週間後の予定が必要なので当日に+7日しています。その日の予定がすべて取得されます。

  // 対象日時を取得
  const target_date = new Date();
  target_date.setDate(target_date.getDate() + 7);

  // 指定日(当日)の予定オブジェクトの配列を取得
  const events = calendar.getEventsForDay(target_date);

指定日の予定一覧から対象の予定を抽出

対象日の予定からタイトルに"予定"の文字が入っている予定を抽出、カレンダーの情報からポストするメッセージを作成し、ポストする関数(postMessage)を呼び出します。

    // 予定の件数だけ実行
    for (event in events) {

      // 予定のタイトルを取得
      let title = events[event].getTitle();
      // タイトルに'予定'が入っているか
      result = title.indexOf('予定')
      if(result !== -1){
        // 予定の開始時刻・終了時刻を取得
        let startHour = toDoubleDigits(events[event].getStartTime().getHours());
        let startMinute = toDoubleDigits(events[event].getStartTime().getMinutes());
        let endHour = toDoubleDigits(events[event].getEndTime().getHours());
        let endMinute = toDoubleDigits(events[event].getEndTime().getMinutes());

        msg_schedule = title + '(' + startHour + '時' + startMinute + '分~' + endHour + '時' + endMinute + '分)';
        message = '1週間後の予定です!\n' + msg_schedule
        postMessage(message)

      }
    }

メッセージのポスト

postMessage関数にてDiscordのチャンネルにポストします。ポストするためにはウェブフックURLが必要になります。ウェブフックはDiscord上で作成できます。(参照

function postMessage(message){

  // discord側で作成したボットのウェブフックURL
  const discordWebHookURL = "https://discord.com/api/webhooks/yyyyyyyyyyyy";

  // 投稿するチャット内容と設定
  const messageContents = {
    "content": message, // チャット本文
    "tts": false  // ロボットによる読み上げ機能を無効化
  }

  const param = {
    "method": "POST",
    "headers": { 'Content-type': "application/json" },
    "payload": JSON.stringify(messageContents)
  }

  UrlFetchApp.fetch(discordWebHookURL, param);

}

定期実行

GAS上で定期実行するにはトリガーを使用します。トリガーはGASのメニューから設定できます。ここでは1日に1回ポーリングで十分ですので「時間主導型」「日付ベースのタイマー」を選択します。(参照

これだけですべての設定が完了です。

最後に

たまたま機会があり調べてみたのですが、想像よりも簡単にbot作成をすることが出来ました。googleのその他のサービス(gmail,google drive等)とも連携出来ますしリマインダー程度であれば非常に簡単に作れるので、色々なbotを作成してみると楽しいかと思います。

About T.H

North Torch株式会社 プログラマ 技術的な経歴は.NETアプリケーションが一番長い。 その他はまだまだ勉強中。