2022年3月16日水曜日

Googleカレンダーの予定をDiscordにリマインダーとしてメンションする

とある集まりの役員になり運営をDiscordで行う事にした。
イベントスケジュールなどリマインダーしてくれるbotは無いものかと探すと

【Discord】Googleカレンダーと連携してテキストチャンネルにリマインダーを送るBotを作る。【プログラミング不要】

と言う記事を発見。

まぁ、大抵のやりたいと思うことは既に実践している先人が居るので助かります。
一応、これと内容が全く同じ記事もあったが上記の記事の方が日付が古かった。(^_^;)
もし「こっちの方が元祖だ!」と言う情報がありましたら教えて下さい。

で、イベントのリマインダーとしては用を足したのだが、イベントの準備のリマインダーとして特定のメンバー宛にメンションで送りたいと思ったので、まずは上記の記事の方法でTitleやDescriptionに@〇〇 送りたいメッセージ としてやってみたけどDiscordに通知されてもメンションになっていない。

単純に本文で@○○として入力されているだけだった。

調べてみると外部からの送信でメンションを送る場合<@user_id>として送る必要があるとの事。

user_idはDiscordを開発者モードにして該当ユーザーを右クリックするとユーザーIDをコピー出来るようになる。
ユーザーIDは18桁の数字。

ユーザーIDが分かったところで、Descriptionに<@xxxxxxxxxxxx> 送りたいメッセージ と登録して通知させて見たところDiscord側には

<html-blob>&lt;@xxxxxxxxxxxx&gt; 〇〇の手配をお願いします。</html-blob>
とHTMLエンコードされた上に余計なタグが追加されてしまう。(^_^;)

で、googleカレンダー メンションで検索すると、こんな記事がヒットした。


一旦、GASのWebアプリケーションにPOSTして、GASから通知するというもの。
通知先がDiscordでは無いがGASにPOSTしてしまえば、やりたい放題ですしお寿司。(^_^;)
なるべくプログラミングレスにしたかったが、結局はこうなってしまうのか、、、

仕様としては、IFTTTからGASにDescriptionと事前にランダム生成した秘密キーをJSONでポスト、GASでは秘密キーの検証を行い一致しないならエラーとする事で万が一のスパムがDiscordに通知されないようにした。

またDescriptionには{user_id,...}{通知メッセージ}という書式でカレンダーに登録し、GAS側で正規表現を使って抜き出しDiscordへ通知するメッセージを組み立てる。
複数ユーザーにメンション出来るようにuser_idはカンマ区切りで複数指定出来るようにする。

IFTTT側の操作は腐るほど記事があるので割愛してPOSTするBODY部だけ。

{ "Description":"{{Description}}","Key":"xxxxxxxxxx"}

GAS側は、下記の記事を参考にした。

GASで簡単に作るDiscord Bot

GAS側のWebアプリケーションの作り方だとか公開の仕方の記事も腐るほどあるのでGAS側のコードだけ。

function doPost(e) {
  const jsonString = e.postData.getDataAsString();

  // スパム対策
  var data;
  try{
    data = JSON.parse(jsonString);
  } catch(e){
    return ContentService.createTextOutput("パラメーターエラー");
  }

  // スパム対策
  const key = data.Key;
  if (key == undefined || key != "xxxxxxxxxx"){
    return ContentService.createTextOutput("実行キーエラー");
  }

  // メンションと通知メッセージを作成
  const description = data.Description;
  const regexp = new RegExp( '(?<={).*?(?=})' , "g");
  const match_text = description.match(regexp); 
  const users = match_text[0].split(",");
  var content="";
  users.forEach(function(id){
    content += "<@" + id + "> ";
  });
  content += match_text[1];

  // discord側で作成したボットのウェブフックURL
  const discordWebHookURL = "";

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

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

  UrlFetchApp.fetch(discordWebHookURL, param);  
}
まぁ、こんなの作らなくても今まで運営出来てたのだから、単純に自分の興味本位が勝ったと言うところか。(^_^;)

0 件のコメント:

コメントを投稿