👏
Discord.js で自分のメッセージを自分で消せないようにする
動機
Discord は実に天才的なソフトウェアです。何でもできる。
しかし、一つ問題があって。自分のメッセージを自分で消すという行動を制御できないんですよあれ。どうにかするにはボットで外部的に介入するしかないらしく、しましょう。
方針
Discord.js はイベント駆動なので、「メッセージを削除した」というイベントを吸って吐けばどうにかなります。ここで重要なのは「結果論的に消せない」ということで、「消すというアクション自体は禁止しない」ことです。ここは課題。
しかし、全員削除を禁止するというのも何かと面倒です。ここでは「消すのを禁止」したロール(以下削除ロール)を生やして、削除ロールで権限管理をすることとします。
そして何かと便利なのでボット自体にも自身のメッセージ削除を禁止します。コード側で実装すると環境依存のパラメタが増えて大変ですが、Discord のロール管理で解決できれば汎用的に処理できるのでそのようにします。
処理フローは以下のようになります。
- (メッセージ削除を禁止するロールを追加して、ID を持ってきて、.env に書いておく)
- (そもそも .env が設定されているかチェックする)
- メッセージ削除イベントを受け取る
- メッセージの削除したユーザが削除ロールを持っているか判別する
- 持っていれば続行
- 持っていなければ終了
- 削除されたメッセージの本人タグ・内容を取得する
- ボットが代理で消されたメッセージを代わりに投稿する
コード
Discord.js のアーキテクチャ自体は示さないので、どうにかしてください。
client.on('messageDelete', ctx => {
// dotenv で .env から権限管理ロールを吸ってくる
const permission = process.env['MESSAGE_PROHIBIT']
if (!permission) {
return
}
if (!ctx.member?.roles.cache.has(permission)) {
return
}
const author = ctx.author?.tag
const content = ctx.content
// こうしないとボットのメッセージを消すと一生タグが増える、やればわかる
if (ctx.author?.bot) {
ctx.channel.send(`${content}`)
return
}
ctx.channel.send(`${author} ${content}`)
})
最後に
今やったことぐらいバニラの Discord でどうにかできるようにしてほしい。
Discussion