TwitterのTLをボイスロイドに読み上げてもらう

#はじめに

<b><font color='#ffoo00'>
2018年8月16日以降、TwitterのAPIが変更され、UserStreamが使用できなくなりました。
よって下に記載したソースコードは正しく動作しません。</font>
現状の対応は未定ですが、Userstreamの代わりに
900回/15分使用可能（9月27日時点）なListAPIなどを叩くと良いかもしれません。
</b>

棒読みちゃんのプラグインでも読み上げさせることは可能であり、そっちのほうが簡単。
でもRTを読み上げさせない方法が分からなかったので適当に書いてみた。
~~本当はwindowsじゃなくてlinuxで動かせれば一番いいんだけどなぁ...~~

#実行環境

- Windows10
- Python3.5.2
- tweepy ver3.5.0
- 民安★TALK ver.1.13.2
- VOICEROID＋ 東北きりたん

#準備

- Pythonのインストール
http://qiita.com/t2y/items/2a3eb58103e85d8064b6

- tweepyのインストール
http://qiita.com/laco0416/items/f2a8928ef54626a75ae1

- tweepyを使うためにはTwitter API Keyが必要
http://phiary.me/twitter-api-key-get-how-to/

- 民安★TALKのインストール
http://publish-tool.blogspot.jp/search/label/%E6%B0%91%E5%AE%89%E2%98%85TALK

- お好きなVOICEROID+を買います
http://www.ah-soft.com/voiceroid/


#実行スクリプト

```python:TimelineVR.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import codecs
import json
from os import path as ospath
import re
import subprocess
import tweepy

# Check Config.json
fpath = '{0}\\Config.json'.format(ospath.dirname(ospath.abspath(__file__)))
if ospath.exists(fpath):
    fp = codecs.open(fpath, 'r', 'utf-8')
    conf = json.load(fp)
    fp.close()
else:
    # Initial setting
    PATH_VRX = input('Drag and Drop vrx.exe : ')
    PATH_VOICEROID = input('Drag and Drop VOICEROID.exe : ')
    CK = input("Input Consumer Key (API Key) : ")
    CS = input("Input Consumer Secret (API Secret) : ")
    AT = input("Input Access Token : ")
    AS = input("Input Access Token Secret : ")
    conf = {'path': {'vrx': PATH_VRX, 'voiceroid': PATH_VOICEROID},
            'api': {'ck': CK, 'cs': CS, 'at': AT, 'as': AS}}
    # Save to Config.json
    fp = codecs.open(fpath, 'w', 'utf-8')
    json.dump(conf, fp, indent=4)
    fp.close()

# Call voiceroid.exe and vrx.exe
pvr = subprocess.Popen(conf['path']['voiceroid'])
pvrx = subprocess.Popen(conf['path']['vrx'])

# Set Tweepy api
auth = tweepy.OAuthHandler(conf['api']['ck'], conf['api']['cs'])
auth.set_access_token(conf['api']['at'], conf['api']['as'])
api = tweepy.API(auth)


# Override Listener
class Listener(tweepy.StreamListener):

    def on_status(self, status):
        # NG word
        try:
            for word in conf['NG']['word']:
                if status.text.find(word) != -1:
                    return True
        except KeyError:
            pass
        # NG client
        try:
            if status.source in conf['NG']['client']:
                return True
        except KeyError:
            pass
        # NG user_id
        try:
            if status.user.id in conf['NG']['user_id']:
                return True
        except KeyError:
            pass
        # NG user_screen_name
        try:
            if status.user.screen_name in conf['NG']['user_screen_name']:
                return True
        except KeyError:
            pass
        # replace Tweet text
        try:
            for retxt in conf['re']:
                status.text = re.sub(retxt, conf['re'][retxt], status.text)
        except KeyError:
            pass
        # escapeされてるので大丈夫っぽい(?)
        cmd = "{0} {1}さんのつぶやき。{2}".format(
            conf['path']['vrx'], status.user.name, status.text)
        subprocess.call(cmd)
        return True

listener = Listener()
stream = tweepy.Stream(auth, listener)
try:
    stream.userstream()
except:
    pvr.kill()
    pvrx.kill()
```


```json:Config.json
{
    "path": {
        "vrx": "C:\\xxx\\xxx\\vrx.exe",
        "voiceroid": "D:\\xxx\\xxx\\X\\VOICEROID.exe"
    },
    "api": {
        "ck": "xxx",
        "cs": "xxx",
        "at": "xxx",
        "as": "xxx"
    },
    "NG": {
        "word": ["RT @"],
        "client": ["ツイ廃ジャー"],
        "user_id": ["1919810", "114514"],
        "user_screen_name": ["tadokoro", "kouji"]
    },
    "re": {
        "(https?|ftp)(:\/\/[-_\\.!~*\\'()a-zA-Z0-9;\/?:\\@&=\\+\\$,%#]+)": "URL省略"
    }
}
```

既存のConfig.jsonはTimelineVR.pyと同じフォルダに入れて下さい。
起動時になかった場合、Config.json作成の初期設定が入ります。

・NGワード、NGクライアント、NGユーザーID、NGユーザースクリーンネームを追加。
作成済みConfig.jsonに好きなように書いて下さい。
NGワードに"RT @"を追加することで、RTを読み上げさせない事ができます。

・正規表現置換の追加
置換したい正規表現と、置換先の文字列を指定することで、
ツイートのテキストを置換することが出来ます。
サンプルではURLを"URL省略"と読ませる設定です。

#問題点

上記のスクリプトを実行すれば読み上げてくれますが問題点がいくつか。

~~- たまに読み上げられない事がある(再実行すると改善されたりする)
追記(2017-02-06):修正しました
追記(2017-11-14):subprocess.Popen()だとプロセスを呼び出し終わる前に次の処理に移ってしまうため、subprocess.call()を使うことが望ましいと思われるため修正~~
追記(2018-06-14):ソースコードを全体的に改変。


- 開くウィンドウが多い(最低でも3つになってしまう)
これに関してはwindows10には仮想デスクトップがあるのでうまくすれば気にならない~~..はず~~

終了時は...強制終了すればいいんじゃないかな（適当）

#最後に

とりあえず今回のは動けばいいやって人向け。
実際TLから目を話しながら作業ができるのでTwitterに取られる時間がかなり減ります。
~~じゃあTwitterをやめればいいのでは...?~~