Replacer(リプレーサー)
VCSpeaker.kt では、メッセージを読み上げる際に、特定のパターンやメンションなどを読みやすい形に置き換える「Replacer(リプレーサー)」という仕組みがあります。
Replacer の実行順序
Replacer は、以下の優先度順に実行されます:
- High(高優先度):
ReplacerPriority.High(level = 2) - Normal(通常優先度):
ReplacerPriority.Normal(level = 1) - Low(低優先度):
ReplacerPriority.Low(level = 0)
優先度の高い Replacer から順に実行され、各 Replacer は優先度の level 値の降順でソートされます。同一優先度内での実行順序は保証されていません。
Replacer の一覧
高優先度(High)
1. EmojiReplacer
優先度: High
機能: 絵文字エイリアスを置換します。
- エイリアスストアに登録された絵文字タイプ(
AliasType.Emoji)のエイリアスを検索します - 一致する絵文字を登録された置換文字列に変換します
- 例:
:smile:→ 「スマイル」(エイリアスで設定されている場合)
2. UrlReplacer
優先度: High
機能: URL を読みやすい形式に置換します。以下の順序で複数の置換処理を実行します:
- Discord メッセージリンク:
https://discord.com/channels/{guild}/{channel}/{message}→ 「{チャンネル種別}「{チャンネル名}」で送信したメッセージのリンク」 - スレッド内の場合: 「{チャンネル種別}「{親チャンネル名}」のスレッド「{スレッド名}」で送信したメッセージのリンク」
- Discord チャンネルリンク:
https://discord.com/channels/{guild}/{channel}→ 「{チャンネル種別}「{チャンネル名}」へのリンク」 - スレッド内の場合: 「{チャンネル種別}「{親チャンネル名}」のスレッド「{スレッド名}」へのリンク」
- Discord イベント直接リンク:
https://discord.com/events/{guild}/{event}→ 「イベント「{イベント名}」へのリンク」 - Discord イベント招待リンク:
https://discord.com/invite/{code}?event={event}→ 「イベント「{イベント名}」へのリンク」 - ツイート(X):
https://twitter.com/{user}/status/{id}またはhttps://x.com/{user}/status/{id}→ 「{ユーザー名}のツイート「{ツイート内容(70 文字まで)}」へのリンク」(70 文字を超える場合は「以下略」が付きます) - Discord 招待リンク:
https://discord.gg/{code}→ 「サーバ「{サーバ名}」のチャンネル「{チャンネル名}」への招待リンク」 - Steam:
https://store.steampowered.com/app/{id}→ 「Steam アイテム「{アイテム名}」へのリンク」 - YouTube 動画: YouTube の動画、ショート、ライブ配信 → 「YouTube の「{投稿者名}」による{種別}「{タイトル}」へのリンク」
- 動画タイトルが 20 文字を超える場合は 20 文字に短縮して「以下略」が付きます
- 投稿者名が 15 文字を超える場合は 15 文字に短縮して「以下略」が付きます
- YouTube プレイリスト: YouTube プレイリスト → 「YouTube の「{投稿者名}」によるプレイリスト「{タイトル}」へのリンク」
- Google 検索:
https://www.google.com/search?q={query}→ 「Google 検索「{検索語}」へのリンク」 - Web ページタイトル: 一般的な Web ページ → 「Web ページ「{ページタイトル(30 文字まで)}」へのリンク」
- ファイル拡張子: 拡張子が認識できる場合 → 「{拡張子名}ファイルへのリンク」(例:
.jpg→ 「JPEG ファイルへのリンク」) - その他 URL: 上記に該当しない場合 → 「Web ページのリンク」
通常優先度(Normal)
3. UserMentionReplacer
優先度: Normal
機能: ユーザーメンションを名前に置換します。
<@123456789>または<@!123456789>の形式のメンションを検出します- メンションをユーザーの表示名に変換します(
@{ユーザー名}) - 例:
<@123456789>→ 「@太郎」
4. ChannelMentionReplacer
優先度: Normal
機能: チャンネルメンションをチャンネル名に置換します。
<#123456789>の形式のメンションを検出します- メンションをチャンネル名に変換します(
#{チャンネル名}) - 例:
<#123456789>→ 「#一般」
5. RoleMentionReplacer
優先度: Normal
機能: ロールメンションをロール名に置換します。
<@&123456789>の形式のメンションを検出します- メンションをロール名に変換します(
@{ロール名}) - 例:
<@&123456789>→ 「@管理者」
6. GuildEmojiReplacer
優先度: Normal
機能: サーバー絵文字を絵文字名に置換します。
<:emoji_name:123456789>または<a:emoji_name:123456789>の形式を検出します(アニメーション絵文字にも対応)- 絵文字を名前だけに変換します
- 例:
<:custom_emoji:123456789>→ 「custom_emoji」
低優先度(Low)
7. AliasReplacer
優先度: Low
機能: テキストエイリアスを置換します。
- エイリアスストアに登録されたテキストタイプ(
AliasType.Text)のエイリアスを検索します - 一致するテキストを登録された置換文字列に変換します
- 例: 「NG ワード」 → 「適切な言葉」(エイリアスで設定されている場合)
8. RegexReplacer
優先度: Low
機能: 正規表現エイリアスを置換します。
- エイリアスストアに登録された正規表現タイプ(
AliasType.Regex)のエイリアスを検索します - 正規表現にマッチするテキストを登録された置換文字列に変換します
- 複雑なパターンマッチングに対応します
- 例:
https?://example\.com/.*というパターン → 「特定サイトへのリンク」(エイリアスで設定されている場合)
置換処理の仕組み
- メッセージテキストは最初に
TextTokenのリストとして処理されます - 各 Replacer は優先度順に実行され、トークンのリストを変換します
- すでに置換されたトークン(
replaced()がtrue)は、後続の Replacer によってスキップされます - 最終的に、すべてのトークンが結合され、絵文字も名前に変換されて読み上げられます
注意事項
- Replacer は常に上記の優先度順に実行されるため、高優先度の Replacer によって置換されたテキストは、低優先度の Replacer では処理されません
- URL の置換は他の置換より先に行われるため、URL 内のパターンが意図せず置換されることを防ぎます
- エイリアス機能を使用することで、サーバー固有の置換ルールをカスタマイズできます