Discordのメッセージをボイスロイドに読ませたい

自分でやったことのメモをかねて投稿します。
#ボイスロイドに読ませたい理由
Discordにも読み上げ機能はあるのですが、どうしてもボイスロイドに読ませたほうが聞きやすいのでやりました。
Python触るのも初めてなのでもっといい書き方あったら教えてください。

#やったこと
1. Discordの所属するサーバのメッセージを受信
2. 自宅サーバからメインPCへのデータ送信
3. 棒読みちゃん経由でボイスロイドでの読み上げ

- Windows Server2016（サーバ）
    - Discordのメッセージを受信
    - メインPCの棒読みちゃんに送信

- Windows10（メインPC)
    - 棒読みちゃん　メッセージをボイスロイドに投げる
    - ボイスロイド　メッセージを読み上げて通知
 
こんな感じで作業が分かれてます。
動作環境は**Windowsで棒読みちゃんとPython**が使える環境です。
ほかの環境ではテストできないんでわかりません。

#開発環境 準備とか
- Python3.6(3.5以降推奨）
- windows10
- 棒読みちゃん
- ボイスロイド（今回は結月ゆかりEx）
- Visual Studio2017

エディタはメモ帳でもAtomでも好きなのでいいですが、C++コンパイルをしたのでVSをおすすめします。
Pythonのセットアップなどは、適当にググってください。ここで説明するより親切ですからね。

Python準備したら、discord.pyのインストールから。
Windowsのコマンドプロンプトで**```pip install discord```**でdiscordをインポートできるようにします。
メインPCがなぜかエラーで出来なかったけど、サーバの方は出来たので無視。出来なかったらググってね。

#レッツPython！！
[Discord.py](https://github.com/Rapptz/discord.py)のサンプルとか見てると簡単そうなのでサクッと書いちゃう。

```python:Discord_for_bouyomi.py
import discord
client = discord.Client()

#起動時コンソールにIDと名前を表示
@client.event
async def on_ready():
    print("-"*35)
    print('棒読みちゃんにコメントを送るよ！！')
    #User Name
    print(client.user.name)
    #User ID
    print(client.user.id)
    print("-"*35)



#Discoedのユーザーが所属するサーバからメッセージを受信して棒読みちゃんに投げる
@client.event
async def on_message(message):
    if client.user != message.author:
        user_name=message.author.name       #送ってきた人の名前を記憶
        msg = message.content               #メッセージを受け取り記憶
        print(user_name+msg)

#ユーザーのメールアドレスとパスワードでログイン
client.run("メールアドレス","パスワード")
```
これでDiscordのサーバからメッセージと送信主の名前が受け取れるようになりました。

このままPythonでsocket通信まで書ければよかったんですが、技術不足で断念。
棒読みちゃんに最初から入ってるサンプルの実行ファイルに、引数渡せば読み上げてくれたのでサンプルのIPだけ書き換えてコンパイル。
1台だけでやりたい場合はサンプル内の実行ファイルをリネームするだけでできます。
やり方がVS付属の**開発者コマンドプロント**でサンプルのフォルダまで移動して```cl BouyomiChanSample.cpp ws2_32.lib```するだけ。
コンパイルしたら実行ファイルできてると思うので```Bouyomi.exe```にリネームして適当な場所に配置（今回はE:\test）
**※パスに空白が入るとうまく動作しないので空白の入らないフォルダに配置してください**


それで、メッセージを引数として投げるためにコードを改変

※追記　2018/4/12
URLがうるさいで置換

```python:Discord_for_bouyomi.py
import discord,subprocess
client = discord.Client()

#起動時コンソールにIDと名前を表示
@client.event
async def on_ready():
    print("-"*35)
    print('棒読みちゃんにコメントを送るよ！！')
    #User Name
    print(client.user.name)
    #User ID
    print(client.user.id)
    print("-"*35)

#Discoedのユーザーが所属するサーバからメッセージを受信して棒読みちゃんに投げる
@client.event
async def on_message(message):
    user_name = message.author.name                 #送ってきた人の名前を記憶
    if client.user != message.author:             #そのほか
        Msg = re.sub(r"http(.*)", "、以下URL", message.content)                             #URLは省略
        bouyomi_cmd(user_name,Msg)      #引数渡して実行

#棒読みちゃんに送る
def bouyomi_cmd(uname,msgs):
    print (uname +"さん :"+msgs)     #受け取ったメッセージをコンソールに表示
    #ここで棒読みちゃんに投げる形式にする　（コマンド＋棒読みちゃんに投げるパス＋デフォルトの設定を使う＋相手の名前＋メッセージ）
    subprocess.call(cmd +PATH_Bouyomi+" -1 -1 -1 0 "+uname+"さん、"+msgs)

#コンパイル済みサンプルのパス
PATH_Bouyomi = r"E:\test\Bouyomi.exe"

#コマンドも記憶して楽にしたい
cmd = r"cmd /c start "

#ユーザーのメールアドレスとパスワードでログイン
client.run("メールアドレス","パスワード")
```

これで実行するとこんな画面が出てきます。あとは勝手にメッセージを受信してくれます。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/187817/bc36419d-9ac0-11e9-13ec-a47f02019d19.png)

#おわりに
やりたいことが実装できてうれしいですけど、まだまだ改良の余地がありそうですね。
少しづつ改造していこうと思います。

##おまけ
実は、テストするためにEchoBOT作ってたので良ければどうぞ。
上のコードのユーザーログインをBOTでのログインにもできますが、権限がないとメッセージを受信できないのでやめておいた方がいいと思います。

![Inkedキャプチャ_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/187817/c46f3642-9ac5-23c2-be91-8ddac174bac2.jpeg)

```python:EchoBot.py
import discord,pyperclippyperclip
client = discord.Client()

@client.event
async def on_ready():
    global player
    global voice
    print("-"*35)
    print("user name：", client.user.name)
    print("user id：", client.user.id)
    print("https://discordapp.com/oauth2/authorize?&client_id="+client.user.id +"&scope=bot&permissions=0")
    print("-"*35)
    pyperclip.copy("https://discordapp.com/oauth2/authorize?&client_id="+client.user.id +"&scope=bot&permissions=0")#クリップボードにBOTの招待用URLを格納

@client.event
async def on_message(message):
        # 送り主がBotだった場合反応したくないので
    if client.user != message.author:
        # メッセージを書きます
        # メッセージが送られてきたチャンネルへメッセージを送ります
        m= message.author.name +"の送ったメッセージは"+message.content+"です"
        await client.send_message(message.channel, m)
  

client.run("BOTのトークン")
```
※追記　2018/10/27
Python3.7が配布されていますが、`async` が予約語になったので更新すると使えなくなるようです。
おとなしく3.6を使いましょう