Discord の同一サーバー内で、指定したチャンネルの投稿を別チャンネルへミラーする Bot アプリケーションです。
この Bot は、同一 Discord サーバー内の特定チャンネルに投稿されたユーザーのテキストメッセージを、別のチャンネルへ自動でミラーします。
- 指定した送信元チャンネルの新規メッセージを検知する
- 指定した送信先チャンネルへ同じ本文を投稿する
- 通常テキストチャンネルに加えて、スレッドを送信元・送信先として指定できる
- 画像添付ファイルは Embed の画像として表示する
- 画像以外の添付ファイルは、ファイル名付きリンクとして表示する
- ミラー先の投稿には、元の発言者情報が残るようにする
- 複数のミラー設定を持てる
- ミラー設定はスラッシュコマンドで追加・削除・確認できる
- ミラー設定は Bot 起動中のみ保持される
- Bot アプリケーションが停止・再起動した場合、ミラー設定は失われてよい
- エラー時も Bot 全体はなるべく停止しない
将来的に必要になれば検討します。
- 添付ファイルの再アップロード
- メッセージ編集の同期
- メッセージ削除の同期
以下は今後も対応しません。
- ミラー設定の永続化
- サーバーを跨いだミラー
- Bot による投稿のミラー
- ミラー先で Discord の返信 UI として再現すること
- 元メッセージ ID とミラー先メッセージ ID の対応管理
- リアクションの同期
- スレッド構造の同期
- 既存メッセージの一括ミラー
- Bot 停止中に投稿されたメッセージの後追いミラー
- Discord API ライブラリには JDA を使用する
- ミラー投稿は Embed で行う
- ミラー設定は永続化せず、Bot 起動中のみ InMemory で保持する
- 状態管理には cats-effect の
Refを使用する
ミラー設定は Discord サーバー単位で管理する。
Map[GuildId, Set[MirrorRule]]MirrorRule は以下の情報を持つ。
sourceChannelId: ChannelId
destinationChannelId: ChannelIdsourceChannelId と destinationChannelId には、通常テキストチャンネル ID またはスレッド ID を指定できる。
フォーラム投稿は Discord 上ではスレッドとして扱われるため、フォーラム投稿単位でミラー設定できる。
フォーラムチャンネルそのものを指定して、配下の投稿をまとめてミラーすることはしない。
1 つの送信元チャンネルから複数の送信先チャンネルへミラーする場合は、送信先ごとに別の MirrorRule として保持する。
ミラー設定は以下のスラッシュコマンドで操作する。
/mirror add source:#送信元 destination:#送信先
/mirror remove source:#送信元 destination:#送信先
/mirror list
/mirror clear
各コマンドの役割:
/mirror add: ミラー設定を追加する/mirror remove: 指定したミラー設定を削除する/mirror list: 現在のサーバーのミラー設定を一覧表示する/mirror clear: 現在のサーバーのミラー設定をすべて削除する
スラッシュコマンドを実行できるのは、管理者権限を持つユーザーのみとする。
source と destination には、通常テキストチャンネルまたはスレッドを指定できる。
新規メッセージを受信したら、以下の順で処理する。
- サーバー内メッセージでなければ無視する
- Bot による投稿なら無視する
- 対象サーバーのミラー設定を取得する
- 送信元チャンネル ID に一致するミラー設定を探す
- 一致する設定がなければ無視する
- ミラー対象メッセージを Embed に変換する
- 各送信先チャンネルへ投稿する
- 送信に失敗した場合はログ出力し、他の送信先への処理は継続する
ミラー先には、Bot が Embed メッセージを投稿する。
Embed には以下を含める。
- 元発言者の表示名
- 元発言者のアイコン
- 元メッセージ本文
- 画像添付ファイル
- 画像以外の添付ファイルのファイル名付きリンク
- 返信メッセージの場合は、返信元発言者の表示名と返信元本文の概要
- 元メッセージの投稿日時
添付ファイルそのものの再アップロードは行わない。
画像添付ファイルが 1 つ以上含まれる場合、本文と 1 枚目の画像添付ファイルを 1 つ目の Embed に表示する。
2 枚目以降の画像添付ファイルは、画像ごとに Embed を分けて表示する。
Discord の制限に合わせて、1 メッセージ内で画像として表示する添付ファイルは最大 10 枚までとする。
11 枚目以降の画像添付ファイルと、画像以外の添付ファイルは [添付ファイル: filename](url) の形式で Embed の本文に追加する。
添付ファイル URL は Discord CDN の URL を使用するため、将来的に期限切れになる可能性がある。
返信メッセージの場合、Discord 上の返信関係そのものは同期せず、Embed の本文先頭に返信元メッセージの概要を表示する。
返信元メッセージの概要は、元メッセージ本文より先に表示する。
返信元の概要には、返信元発言者の表示名と本文の一部を含める。
返信元メッセージに添付ファイルが含まれる場合、概要にも添付ファイル情報を追加する。
返信元メッセージの概要は ┏━━ ◯ <名前> 返信元メッセージ の形式で表示する。
本文ありの場合:
こんにちは
[添付ファイル: document.pdf](https://cdn.discordapp.com/...)
本文なしの場合:
[添付ファイル: document.pdf](https://cdn.discordapp.com/...)
Bot に必要な Discord 権限:
- View Channel
- Send Messages
- Send Messages in Threads
- Embed Links
- Use Application Commands
Discord Gateway Intent:
- Guild Messages
- Message Content Intent
Message Content Intent は Discord Developer Portal で有効化する必要がある。
- 不正なスラッシュコマンド引数は、実行者にエラーメッセージを返す
- 送信先チャンネルが存在しない場合は、そのミラーだけ失敗として扱う
- Bot に送信権限がない場合はログ出力する
- 1 件のミラー送信失敗で Bot 全体を停止しない
- 1 つの送信先で失敗しても、他の送信先へのミラーは継続する
サーバー機上で Docker イメージをビルドして実行できます。
docker build -t discord-channel-mirror:local .docker run --rm \
-e DISCORD_BOT_TOKEN=your-discord-bot-token \
discord-channel-mirror:localバックグラウンドで実行する場合:
docker run -d \
--name discord-channel-mirror \
--restart unless-stopped \
-e DISCORD_BOT_TOKEN=your-discord-bot-token \
discord-channel-mirror:localこの Bot は Discord Gateway へ接続するアプリケーションのため、公開ポートはありません。
DISCORD_BOT_TOKEN が未設定の場合、起動時にエラー終了します。