Quick Pollと組み合わせてDiscordで定期イベントの出欠をとる

Quick Pollと組み合わせてDiscordで定期イベントの出欠をとる

せっかくなので「スプシでメンバー管理」のシートができてる前提で、タブと機能とトリガーを追加していく。
メンバー管理シートをコピーするだけでGASもコピーされそうだけど、連携はやり直さないと使えないかも?しくみがわかればやりやすいと思うので見てみてください。

出欠アンケートを流すサーバーにQuick Pollを導入

https://quick-poll.vineder.com/ja/

導入にはDiscordサーバーの管理者権限が必要そう。

サーバーへ導入する
サーバーを選んですすむ

どんな権限使いますかとか聞かれて、3回くらい?ボタン押すだけで簡単に導入できる。

コマンドテスト

導入できたら試しにコマンド打っておこう。

?poll 今の気分を選んで! 😊 😐 😢 😠

これはすばらしい機能です。

出欠アンケートを投稿するチャンネルにWEBHOOKを作っておく

別チャンネルに投稿したい時はチャンネル毎にWEBHOOKを作っておこう

ウェブフックの作り方
  • Discordのサーバー設定 > アプリ 連携サービス から ウェブフック を作成
  • 通知を送るチャンネルを選択して、表示名やプロフィールイメージを設定しておく

出欠を取りたいイベントの日程をまとめるタブで、予定を抽出・整形する(schedule A9:T)

3列ずつ予定を抽出して整形するしくみを作っとく。
今回は定期イベントだけ。
一旦2034年の12月くらいまでにした。10年もやらんやろという気持ちを込めてしまってすみません。

同じタブに通知用のパーツを置いておく(schedule A1:T8)

基準になる日程を「今週の日曜日」にして、今週の土曜日にトリガーを実行する想定で、次週の予定を抽出する。
日付の表示が数字だけにならないように整形が必要だったりするけど、隠しといたら気にならないかな。

3週間おきのイベントの場合に、トリガーの時間指定が3週間おきにできないので、日付のリストに合致した時に通知用のセルに内容を表示する感じにした。

別のチャンネルに投稿したい場合もあると思うので、WEBHOOKのURLもセルに入力する形にした。
ピンク色のセルに、作成したWEBHOOKのURLを入れてね。

セルに入力がある時だけQuick Pollでメッセージを送るGAS

  function schedule() {
  
  /**
  // スプレッドシートの情報を取得する
  **/

  // ①:コピーして作成した自分のメンバー管理シートのIDを設定 → 「https://docs.google.com/spreadsheets/d/●●●●●/edit」●●●●●を↓に記述
  const spreadsheet = SpreadsheetApp.openById('●●●●●');
  const sheet = spreadsheet.getSheetByName("schedule");
 
  // アデン城決戦ラウンド1の出欠アンケートを自動投稿
  const rangeTUE = sheet.getRange("B6");
  const dataTUE = rangeTUE.getDisplayValue();
  const rangeWHTUE = sheet.getRange("B7");
  const dataWHTUE = rangeWHTUE.getDisplayValue();
  const WEBHOOKTUE_URL = dataWHTUE; 

  if(rangeTUE.isBlank()){
  }else{
    const messageTUE = {
      "content": `?expoll @everyone ` + dataTUE + ` ⭕ 参加 ❌ 不参加`,
      "tts": false,
    }
    const param = {
      'method': 'POST',
      'headers': { 'Content-type': 'application/json' },
      'payload': JSON.stringify(messageTUE)
    }
    UrlFetchApp.fetch(WEBHOOKTUE_URL, param);
  }

  // アデン城決戦ラウンド2の出欠アンケートを自動投稿
  const rangeTHU = sheet.getRange("E6");
  const dataTHU = rangeTHU.getDisplayValue();
  const rangeWHTHU = sheet.getRange("E7");
  const dataWHTHU = rangeWHTHU.getDisplayValue();
  const WEBHOOKTHU_URL = dataWHTHU;

  if(rangeTHU.isBlank()){
  }else{
    const messageTHU = {
      "content": `?expoll @everyone ` + dataTHU + ` ⭕ 参加 ❌ 不参加`,
      "tts": false,
    }
    const param = {
      'method': 'POST',
      'headers': { 'Content-type': 'application/json' },
      'payload': JSON.stringify(messageTHU)
    }
    UrlFetchApp.fetch(WEBHOOKTHU_URL, param);
  }

  // 要塞戦の出欠アンケートを自動投稿
  const rangeSAT = sheet.getRange("H6");
  const dataSAT = rangeSAT.getDisplayValue();
  const rangeWHSAT = sheet.getRange("H7");
  const dataWHSAT = rangeWHSAT.getDisplayValue();
  const WEBHOOKSAT_URL = dataWHSAT;

  if(rangeSAT.isBlank()){
  }else{
    const messageSAT = {
      "content": `?expoll @everyone ` + dataSAT + ` ⭕ 参加 ❌ 不参加`,
      "tts": false,
    }
    const param = {
      'method': 'POST',
      'headers': { 'Content-type': 'application/json' },
      'payload': JSON.stringify(messageSAT)
    }
    UrlFetchApp.fetch(WEBHOOKSAT_URL, param);
  }

  // アデン城決戦ファイナル・攻城戦の出欠アンケートを自動投稿
  const rangeSUN = sheet.getRange("K6");
  const dataSUN = rangeSUN.getDisplayValue();
  const rangeWHSUN = sheet.getRange("K7");
  const dataWHSUN = rangeWHSUN.getDisplayValue();
  const WEBHOOKSUN_URL = dataWHSUN;

  if(rangeSUN.isBlank()){
  }else{
    const messageSUN = {
      "content": `?expoll @everyone ` + dataSUN + ` ⭕ 参加 ❌ 不参加`,
      "tts": false,
    }
    const param = {
      'method': 'POST',
      'headers': { 'Content-type': 'application/json' },
      'payload': JSON.stringify(messageSUN)
    }
    UrlFetchApp.fetch(WEBHOOKSUN_URL, param);
  }

  // ワールドダンジョン選抜戦・評価戦の出欠アンケートを自動投稿
  const rangeSUNW = sheet.getRange("N6");
  const dataSUNW = rangeSUNW.getDisplayValue();
  const rangeWHSUNW = sheet.getRange("N7");
  const dataWHSUNW = rangeWHSUNW.getDisplayValue();
  const WEBHOOKSUNW1_URL = dataWHSUNW;
  const WEBHOOKSUNW2_URL = dataWHSUNW;

  if(rangeSUNW.isBlank()){
  }else{
    const messageSUNW1 = {
      "content": `?expoll @everyone ` + dataSUNW + `選抜戦 ⭕ 参加 ❌ 不参加`,
      "tts": false,
    }
    const param = {
      'method': 'POST',
      'headers': { 'Content-type': 'application/json' },
      'payload': JSON.stringify(messageSUNW1)
    }
    UrlFetchApp.fetch(WEBHOOKSUNW1_URL, param);
  }
  if(rangeSUNW.isBlank()){
  }else{
    const messageSUNW2 = {
      "content": `?expoll @everyone ` + dataSUNW + `評価戦 ⭕ 参加 ❌ 不参加`,
      "tts": false,
    }
    const param = {
      'method': 'POST',
      'headers': { 'Content-type': 'application/json' },
      'payload': JSON.stringify(messageSUNW2)
    }
    UrlFetchApp.fetch(WEBHOOKSUNW2_URL, param);
  }

  // 聖物防御戦の出欠アンケートを自動投稿
  const rangeMON = sheet.getRange("N6");
  const dataMON = rangeMON.getDisplayValue();
  const rangeWHMON = sheet.getRange("N7");
  const dataWHMON = rangeWHMON.getDisplayValue();
  const WEBHOOKMON_URL = dataWHMON;

  if(rangeMON.isBlank()){
  }else{
    const messageMON = {
      "content": `?expoll @everyone ` + dataMON + ` ⭕ 参加 ❌ 不参加`,
      "tts": false,
    }
    const param = {
      'method': 'POST',
      'headers': { 'Content-type': 'application/json' },
      'payload': JSON.stringify(messageMON)
    }
    UrlFetchApp.fetch(WEBHOOKMON_URL, param);
  }

}

テスト送信してみておこう

各所入力して実行してみて、来週の予定抽出の行の、入力のあるセル(薄い黄色背景セル)の内容で出欠アンケートが投稿されればできあがり。

トリガーを使って週末に実行

トリガーを開いて、右下にある

を押す

  • 実行する関数を選択:
    今回作ったGASの名前になってればok
  • 実行するデプロイを選択:
    Head(変更しない)
  • イベントのソースを選択:
    時間主導型
  • 時間ベースのトリガーのタイプを選択
    週ベースのタイマー
  • 日を選択
    想定通りに土曜日
  • 時刻を選択
    お好きな時間

に設定して、保存を押す。

いつも出欠とってくれてたそこのあなたに敬意を表します。
これからはBOTに任せて少しだけだけど楽してください。