marukot-chの日記

弱小SEの雑記です

DiscordのWebhookでEveryoneにメンションが飛びびっくりしたこと

 はてなブックマークには、関心ワードという機能がある。自分の場合、そこにdiscordというものを登録している。その関心ワードを集めたRSSを取得するURLを作成できるので、それを使ってDiscordへWebhookで連携している。

 そのWebhookから先日、Everyone宛にメンションが飛んだ。

f:id:marukot-ch:20210626104858p:plain

全員へメンションを飛ばす該当のメッセージ(from webhook)

今回この記事で語るのはやったこと、ダメだったこと、成功したことを時系列で語る(どうすれば解決できるか一瞬でわかる人もいそうだけど)。

 概要を把握したい人向けに3行で説明

  • 「@everyone」を文章に含む記事がWebhookで連携されて全員にメンションされてしまった
  • everyoneロールにメンション権限を解除、適当にallowed_mentionsを設定してもダメ(WebのPostできるサイトからはうまくいくのに)
  • 'contentType': 'application/json'に指定し、payloadをJSON.stringify(payload)するとうまくいった

 記事的には以下のやつ。

 

 まず思いつくこととしてこのサーバーでは全員に、メンションできる権限をふっていたので、それをやめた。もう一度試してみるが、普通にメンションされてしまう(Webhookには効かないらしい)。

f:id:marukot-ch:20210626105536p:plain

everyone(デフォルト)の権限のメンション可能かどうかの設定

 続いて、Googleで検索してみると、以下のサイトが見つかる。お目当ての設定も見つかった。以下のようにallowed_mentionsにそれっぽいことをすると誰にも通知されないらしい。

{
  "username": "test",
  "content": "@here hello! 今度こそOKのはず。",
  "allowed_mentions":{
    "parse": []
  }
}

allowed_mentions - Discord Webhooks Guide

 WebhookをサイトからPostして成功したのを確認し、今回事件が起こったGoogle Apps Scriptから実行してみる。
 残念ながら、むしろ何も起こらない。投稿されないし、エラーにもなっていなかった。Google Apps Scriptは無料版だとログが保持されないので、手元から実行させて確認すると、 Responseが以下だった。ステータスコードは400。
allowed_mentions "Only dictionaries may be used in a ModelType"

 検索しても全然いい記事がひっかからない。言っている意味もよくわからないし。ということでjavascriptはあんまり分かってないし、やり方が違うのか? と試行錯誤する。で、JSONで送ることを明示的に指定し、JSON 文字列に置き換えたらうまくいった(最初からそうやっておこうね。。。)。
const payload = {
  'token': discordSettings.token,
  'channel': discordSettings.channel,
  'content': postMsg,
  'parse': parse,
  'allowed_mentions': {
    parse:[
],// 追加
  }
};

const params = {
  'method': methods,
  'contentType': 'application/json', // content-typeをjsonにした
  'payload' : JSON.stringify(payload), //stringifyした
  'muteHttpExceptions': true,
};


 〜終わり〜

f:id:marukot-ch:20210626111059p:plain

メンションされてないやつ