DiscordでBotを作りたかったお話

季節外れのAdventCalender3日目です〜

#はじめに
というわけでタイトル通りDiscordでBotを作りたかったお話で,作っていく過程で詰まった部分を紹介していけたらなーと

#とりあえず導入
詰まった部分を紹介するだけじゃあおもしろみもなさそうなので,Bot作りたいって人のために(宣伝も兼ねて)導入あたりから紹介していきます.

今回のDiscordのBotはdiscord.pyを使う関係上Pythonの３系(最新版3.7系以外)を使います.
pythonのインストールの仕方はここでは省きます.

自分の動作環境は以下のような感じです
- Python 3.6.2
- pip 18.0
- discord.py 0.16.12

確認の仕方は上からコマンドライン上で
- `python -V`
- `python -m pip -V`
- `python -q`でインタプリタを起動した後,`import discord`, `discord.__version__`で帰ってくる値がversion

discord.pyのインストールの仕方は
Macなら`python3 -m pip install -U discord.py`
Winなら`py -3 -m pip install -U discord.py`
これが無理そうなら単純に`pip install discord.py`でも多分ok.自分はこっちで入れた.

#botアカウントの作成と登録

botを使うにはdiscord側でbotの設定しないと出来ません.

まず,[ここ](https://discordapp.com/developers/applications/)からdiscordのDEVELOPER PORTALに接続しましょう.

discordにログイン(登録してなかったら新規登録)してから開くと以下のような感じで表示されると思います.

![first.png](https://qiita-image-store.s3.amazonaws.com/0/274354/a0c89186-556d-1174-6a55-0c012a874b59.png)

黒塗りのとこは画像が著作権的に危なそうなので隠しました（）

それはさておき,Create an applicationをクリックしましょう.するとこんなページに行くと思います.

![second.png](https://qiita-image-store.s3.amazonaws.com/0/274354/84195888-c6b5-645e-e6ae-0b8848986b65.png)

そしたら,APP ICONとNAMEを適当に決めて下の方にあるSave Changesで保存しましょう.

で,画面を全画面表示にしてたら左側にこんな感じでsettingsが出てると思うのでそこのBOTのところをクリックしましょう.

![th.png](https://qiita-image-store.s3.amazonaws.com/0/274354/6d7af510-b5e0-bce6-8db1-c6792d1714be.png)


するとこんな感じの画面が出てくるのでadd bot押してYes, do itをクリックしましょう.

![fo.png](https://qiita-image-store.s3.amazonaws.com/0/274354/c525e684-7454-df4b-7ca4-bc30466ed308.png)

![fiv.png](https://qiita-image-store.s3.amazonaws.com/0/274354/547fada2-d81a-a7ec-d2f5-c19c4e1aef75.png)

次に以下のような画面に飛ぶのでpublic botにチェックが入ってるのを確認して,その後Administratorにチェックを入れましょう.

![roku.png](https://qiita-image-store.s3.amazonaws.com/0/274354/5e1ab7d6-6b00-b247-df25-c4e3b3a5d51f.png)

![nana.png](https://qiita-image-store.s3.amazonaws.com/0/274354/1cbc1d07-8299-0d72-8d78-897101972996.png)

次に,settingsに戻ってOAuth2をクリックしましょう.

![hati.png](https://qiita-image-store.s3.amazonaws.com/0/274354/92bfe9bb-75a9-2b2e-855a-83e7fe7dfa4c.png)

で,下の方に行って画像通りにチェック入れましょう.

![kyuu.png](https://qiita-image-store.s3.amazonaws.com/0/274354/bfbcbd1a-6b7c-39b1-8da8-00c6234ce48d.png)

copyってとこクリックしたらURL取得するのでそこからサーバ選んでそのサーバにBot追加できます.

あとは,アクセストークン取得するためにsettingsのBotのとこに戻ってUserNameの下あたりにTokenってあるのでCopyってとこクリックしたら取得できます.アクセストークンに関しては他人には絶対バレないように.

#botの作成

```html:sampleBot.py
   import discord #インストールした discord.pyのimport
   from datetime import datetime #現在時刻の取得に使う   

   client = discord.Client()

   @client.event
   async def on_ready():
       print("ログインしました")
   
   @client.event
   async def on_message(message):
       #!timeとサーバのチャット欄に打てば現在時刻を教えてくれる
       if message.content.startswith('!time'):
           replay = datetime.now().strftime("%Y年%m月%d日 %H時:%M分:%S秒")       
           await client.send_message(message.channel, replay) 
   
   client.run('あなたのアクセスToken')
```

はい,サンプルです.tokenさえ正しいの入れれば動くはずです.自分で色々機能付け足したかったらon_message以下に書き足せばいけます.

#詰まったところ

さて,やっと本題です.自分はこのBotを使って,discordのvoicechannelに入って,音楽を流すMusicBotの真似事をしようとしたんですが,これがうまくいかない…なにせdiscord.pyはgithubにも上がっているのですがコメントは全て英語,APIリファレンスも日本語設定に変えれるけど…っていう感じでよくわからなかったorz

結局discordでpythonのコミュニティがあるのですが,そこで質問しまくって一応の解決に至りました.感謝の極みです.

では,voicechannelに入って音楽流すまでの機能追加で詰まったところの解決策を今から説明します.

#解決策

とりあえず,discord.pyで音声を使うためにはまず,opusとffmpegというやつが必須らしいのでそれらのインストールから始めましょう.

`$ brew install opus
 $ brew install ffmpeg --with-opus`

brewに関してはbrew installあたりで検索して入れてください.

で,しっかり入ってるかどうかの確認でpythonのインタプリタを起動させて

`>>> import discord`
`>>> discord.opus.is_loaded()`

と入力してTrueが帰ってきたらしっかりとインストールされています.
何かしらエラったら

`$ brew uninstall opus
 $ brew uninstall ffmpeg`

これを実行したのちに再度インストールしたら治るかと思います.

ここまで出来たらあとはコードを書くだけです.

```html:sampleVoiceBot.py
   import discord
   
   client = discord.Client()

   @client.event
   async def on_ready():
       print('ログインしました')

   @client.event
   async def on_message(message):
       if message.content.startswith('!bgm'):
           channel = client.get_channel('あなたのvoicechannelのID')
           
           if client.is_voice_connected(channel.server):
               voice = client.voice_client_in(channel.server)
           else:
               voice = await client.join_voice_channel(channel)

            #mp3ファイルはこのプログラムと同じ階層の場所に入れること.
            player = voice.create_ffmpeg_player('sample.mp3')
            player.start()
   
   client.run('あなたのアクセストークン')
```
機能としては!bgmとチャット欄で発言すればsample.mp3が再生されます.

しかし,ここでも嵌ったところがありそれがvoiceのところで,最初に実装した時は一度音楽を流した後に,再度!bgmをしても音楽がならないというものでした.

そのときのvoiceの内容としては
`voice = await client.join_voice_channel(client.get_channel('あなたのvoicechannelのID'))`
だけでif文なんかありませんでした.

これだけでも一応音楽はなりますが再度鳴らそうとするのは無理でした.

この解決策はまたもや,コミュニティの人の力を借りて解決し,解決したのが上のコードですw

まあ,clientからchannelの状態を取ってきてvoicechannelに入ってたら入ってるよーっていう状態をvoiceに入れて,そうじゃなかったらclientからvoicechannelにログインするって処理です.

後から見てみりゃそりゃそうだって感じですが,やってる時はほんとわかんないですね()かなしぃ.

とまあ,参考になるかはわかりませんが以上が詰まった部分とその解決策です.

#最後に
いろんなコミュニティに入ることは本当に自分に取ってプラスしかないので,独学にやるにしてもコミュニティを広げて行くことはめちゃくちゃオススメです.今回お世話になったコミュニティには以下の参考リンクに記載されています.興味があったら入ろう!

そんで,pythonはこれから情報系ならほぼ確実に触って行くことだろうから皆んなもpythonやろう!(唐突の宣伝)

それではまた!お疲れまでした!

#参考リンク
[Pythonで実用Discord bot(discord.py解説)](https://qiita.com/1ntegrale9/items/9d570ef8175cf178468f)