Daidoquer2(Discord読み上げボット)を使った記録

Daidoquer2 (ddq2) という艮鮟鱇さんが作った読み上げボットをローカルのマシンで立ち上げ、 Discord のテキストチャンネルに書いた内容がボイスチャンネルで読み上げられるようにしたという記録です。 割と苦戦して、艮鮟鱇さんにヘルプ求めまくりながらやったところなんとか動くようになりました。 問題の原因はほとんど使っていた Docker イメージが古かっただけということもしなくもない。

TL; DR 的なサムシング

書いていたら思いの外前置きが長くなったので、(たぶん)順当に構築できた場合の手順との差分を最初に書いておきます。

  1. docker-compose.yml が指しているイメージを最新にする
    • ddq2 の images のところを書き換え
    • ここを見て最新のやつを使ったほうが良さげ
  2. 他の人が喋っていたら音量を下げる機能を無効化する
    • なぜか FFmpeg が死亡するので
    • config/runtime.exsms_before_stop_low_voice0 に設定

Daidoquer2 って何なのよ

(たぶん)数多ある Discord の読み上げボットの 1 つです。README が詳しいのでここであんまり書いても仕方ないんですが、Discord のボイスチャンネルで喋れない人が、 テキストチャンネルに何か投げるとそれが合成音声でボイスチャンネルに流される感じです。

(実は他のボットを触っていないのでイマイチ分かっていないんですが)これの面白いところはテキストを受け取って WAV ファイルを返すサーバを用意すれば適当な音をボイスチャンネルに流せるところだと思っています。 僕が自分で Daidoquer2 のサーバを立てようと思った理由がこれで、共用のボットで変な音を流すのもアレなので自分でサーバを立てて変なことをしようとしたわけです。

前提

Docker Compose で簡単に立ち上げられるようにしてくれているので今回はそれを使っていきます (daidoquer2-docker-compose)。

多分どの環境でも動くんじゃないかと思っているんですが、今回やった環境は一応下のような感じ

  • OS: Arch Linux
  • Docker: 23.0.4, build f480fb1e37
  • Docker Compose: 2.17.3

docker-compose コマンドではなくて Docker CLI の compose コマンド (docker compose) を使っています。 今回やったことくらいで差があるのかは謎。

構築

実は Discord のボットを作ったことがまずなかったのでそこから丁寧めに書いておきます。

Discord のボットの作成

Discord 上で動くボットを作るには Discord の Application を作成してトークンとかをもらってくる必要があります。 なんかアプリとボットとして使うユーザは別の概念らしく、このへんのシステムは Slack と似ているなと思いました(Slack のボットは作ったことがあった)。

  1. Discord Developer Portal からアプリを作る
  2. 左のペインの “Bot” というタブでボットユーザの設定をします(Slack と違って明示的に作らなくてもいいっぽい)
  3. 同じ画面に “Reset Token” というボタンがあるのでそれを押してトークンを貰う(後で使う)
    (こういうのにありがちな、別のページに行くと二度と見られないシステムなので、リセットだけしておいて後から見ようみたいなのは無駄です。もう一度リセットするはめになります。)
  4. 同じ画面の “Message Content Intent” というやつをオンにする
    (これだけあれば動いた気になったけど、他のパーミッションが絡む部分をまだ踏んでいないだけ説もある)
  5. サーバにボットを参加させる
    1. OAuth2 のタブから Client ID をコピーする
    2. https://discord.com/api/oauth2/authorize?client_id=<Client ID>&permissions=3147776&scope=bot%20applications.commands を踏んで、入れたいサーバを選ぶ (<Client ID> を Client ID に置き換えてください)

ちなみにサーバにボットを追加するにはサーバの管理者じゃないといけないらしいので、入れたいサーバの管理者じゃない場合は管理者に頼み込む必要があります。 (←文の中に管理者多すぎて船頭多くして船山登ってる)

最後のサーバにボットを参加させる部分古の技法だと鮟鱇氏が言っていました。 たぶん今のというか正規の方法だと API 叩いて返ってきた URL を踏むとかなんだと思うんですが、何も分かってはないです。

Daidoquer2 を立ち上げる

daidoquer2-docker-composesetup.sh というスクリプトがあるのでこれを使います。 README に書いてある通りに setup.sh を実行すると “Enter your Discord token” と言われるので、ボットユーザのトークンを入れます。

このままだと docker-compose.yml が指しているイメージが古くて動かなくなっているので、ここを見て最新のものに書き換えます。

@@ -4 +4 @@ services:
-    image: anqou/ddq2:0.5.5
+    image: anqou/ddq2:0.5.12

config/runtime.exsms_before_stop_low_voice0 に設定します。これは他の人が喋っていたら読み上げの声を小さくする機能らしいんですが、 これがあると FFmpeg が死亡してしまう問題があったので無効化しています。(本人いわく需要なかったからテストもあんまりしてないらしい、おもしろ)

これが編集できたら docker compose up で普通に起動します。

テスト

まず自分がボイスチャンネルに入り、チャットで /join コマンドを打ちます。するとボットがボイスチャンネルに入ってきます。 あとは適当にチャットに書いた内容を読み上げてくれます。

声が出なかったら多分失敗で、ログとかを見て頑張って対処する必要があるはずです。

自分で TTS 部分を作りたい

runtime.exs に声の割り当ての設定を書くんですが、ここに {:post, "https://example.com"} みたいな感じで書くことで自分が立てた適当な HTTP サーバを TTS のプロバイダとして使うことができます。 Daidoquer2 はここに書いた URL に、body に UTF-8 でエンコードされたメッセージを詰めて POST リクエストを送ってくれるので、適当に WAV ファイルを返してあげます。 するとボイスチャンネルでよしなに再生してくれます。たのしい。

僕は “ドレミファミレドーミファソラソファミー” みたいに書くと音楽ファイルを返してくれるシンセサイザーっぽいサーバを書いたりしました→haniho

ちなみに最大音量まで波形を詰め込むような実装をすると簡単に鼓膜が破壊ボットを作れてしまうので注意が必要です。

最後に

自分でやった風に書いていますが作者氏が言っていたことを書いているだけです。(僕にはこれが分かるほどのエスパー力はない。)

ところで、僕が自作シンセ(と呼べるほど大層なものではないが)で作った作品(と呼べるほどの大層なものではないが)を貼っておくので絶対に聴いてください(別に聴かなくてもいい)。

(最大音量で流す実装にしてしまったせいで)爆音なのでマジで注意してください!!!!(鼓膜が破れても責任は負いません)

かえるの合唱「ドレミファミレドーミファソラソファミードッドッドッドッドドレレミミファファミレド」

ガヴォット「^ソラソミファソファレド^ドvドーファソファレミファミドレソvソー^ソラソミファソファレド^ドvドーミドvラ^ドvラファ#ソ^ソvソ」

君が代「レードーレーミーソーミーレーーーミーソーラーソラ^レーvシーラーソーミーソーラーーー^レードーレーーーvミーソーラーソーミーーソレーーーラー^ドーレーーードーレーvラーソーラーソミレーー」

Windows XP 終了音「^ラbミbvラbシb」

博多駅発車メロディ「ソラシソ^ドレミー-ファーミ-レー-ドー」

入力めんどくさいっす