TwitterのUser Streamが廃止になったけどTwythonのStreamerはどうなっているか調べてみた

# 背景
- 以前作ったTwitter botは、Twitter APIのPythonライブラリTwython経由でUser Streamsを使用していた。
 - [Raspberry PiをTwitter botにして家のグローバルIPを調べさせる](https://qiita.com/y_uehara1011/items/660b86441d5c274cabe2)
 - Twython https://twython.readthedocs.io/en/latest/
 - 使用しているのはtwython.TwythonStreamer 
- 最近のTwitter社の発表によると、User Streamsを含むStreaming APIは8/16をもって廃止されたらしい
 - https://blog.twitter.com/developer/ja_jp/topics/tools/2018/AAA_e.html
 - そういえば開発者アカウントのアドレスにそんなメールが来てた
- が、8/18になってもTwitter botは普通に稼働しているように見える

# 調べようと思ったこと
- twython.TwythonStreamerは内部でTwitter APIのUser Streamsを叩いているのかどうか
- 8/18現在User Streamsは稼働しているのかどうか

## TwythonStreamer調査
### 公式ドキュメントを当たってみる。
- https://twython.readthedocs.io/en/latest/usage/streaming_api.html
- 使い方は書いてあるけど、Twitter APIとの紐付け情報はなさげ？

https://twython.readthedocs.io/en/latest/api.html#streaming-interface ここに

*Streaming class for a friendly streaming user experience Authentication IS required to use the Twitter Streaming API*

こんなこと書いてあるので使ってるのかな？

### ソースを読んでみる
- GitHubにソースが置いてあったので読んでみる。
 - 2018/8/18現在最新のバージョン3.6.0 
 - https://github.com/ryanmcgrath/twython
 - [twython/streaming/api.py](https://github.com/ryanmcgrath/twython/blob/master/twython/streaming/api.py), [twython/streaming/types.py](https://github.com/ryanmcgrath/twython/blob/master/twython/streaming/types.py) あたりを読んでみる

```Python:api.py
class TwythonStreamer(object):
    def __init__(self, app_key, app_secret, oauth_token, oauth_token_secret,
                 timeout=300, retry_count=None, retry_in=10, client_args=None,
                 handlers=None, chunk_size=1):
        """Streaming class for a friendly streaming user experience
        Authentication IS required to use the Twitter Streaming API
        :param app_key: (required) Your applications key
        :param app_secret: (required) Your applications secret key
        :param oauth_token: (required) Used with oauth_token_secret to make
                            authenticated calls
        :param oauth_token_secret: (required) Used with oauth_token to make
                                   authenticated calls
        :param timeout: (optional) How long (in secs) the streamer should wait
                        for a response from Twitter Streaming API
        :param retry_count: (optional) Number of times the API call should be
                            retired
        :param retry_in: (optional) Amount of time (in secs) the previous
                         API call should be tried again
        :param client_args: (optional) Accepts some requests Session
                            parameters and some requests Request parameters.
                            See
                            http://docs.python-requests.org/en/latest/api/#sessionapi
                            and requests section below it for details.
                            [ex. headers, proxies, verify(SSL verification)]
        :param handlers: (optional) Array of message types for which
                         corresponding handlers will be called
        :param chunk_size: (optional) Define the buffer size before data is
                           actually returned from the Streaming API. Default: 1
        """
// ...
    self.client = requests.Session()
// ...
    self.user = StreamTypes.user
```
実際にアクセスに行くのはrequests経由の模様。
エントリポイントはStreamer.user() なのでそちらの実装も見てみる

```Python:types.py
class TwythonStreamerTypes(object):
    """Class for different stream endpoints
    Not all streaming endpoints have nested endpoints.
    User Streams and Site Streams are single streams with no nested endpoints
    Status Streams include filter, sample and firehose endpoints
    """
    def __init__(self, streamer):
        self.streamer = streamer
        self.statuses = TwythonStreamerTypesStatuses(streamer)

    def user(self, **params):
        """Stream user
        Accepted params found at:
        https://dev.twitter.com/docs/api/1.1/get/user
        """
        url = 'https://userstream.twitter.com/%s/user.json' \
              % self.streamer.api_version
        self.streamer._request(url, params=params)
```

https://userstream.twitter.com/%s/user.json にアクセスに行ってるようだ

### Twitter公式のドキュメントを読んでみる

- https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/user-stream

>Resource URL
>https://userstream.twitter.com/1.1/user.json

あっさり使ってた！

## 何でUser Streamsが使えてるのか

よくよくさっきのTwitter公式ドキュメントを読んでみたら、気になる記述があった

>Notice: Starting Thursday August 16th, 2018, we will be flickering User Streams on and off in anticipation of its retirement, scheduled for August 23rd, 2018. The Account Activity API will replace User Streams and Site Streams APIs.

>If you would like to migrate from the User Streams API to the Account Activity API, you should read through our migration guide.

ん？8/23までは断続的に使える？

と思って色々調べてみると、以前こんなアナウンスがあったらしい

- [Details and what to expect from the API deprecations this week on August 16, 2018 ](https://twittercommunity.com/t/details-and-what-to-expect-from-the-api-deprecations-this-week-on-august-16-2018/110746)

> Here is what to expect during the flicker time period:

>    Starting August 16, 2018 through August 20, 2018, we will turn off User Streams and Site Streams for one hour every six hours (1 hour off, 5 hours on) starting at 16:00 UTC on the 16th.
>    Starting August 20, 2018 through August 21, 2018, we will turn off User Streams and Site Streams for two hours every six hours (2 hours off, 4 hours on) starting at 00:00 UTC on the 20th.
>    Starting August 22, 2018 through August 23, 2018, we will turn off User Streams and Site Streams for three hours every six hours (3 hours off, 3 hours on) starting at 00:00 UTC on the 22nd.
>    Finally at 16:00 UTC on August 23rd, the endpoints will be shut off entirely.

なんと。

# 結論
8/16～8/20までは6時間ごとに1時間User Streamsを無効化、20～21は2/6時間、22～23は3/6時間・・・という風に段階的に使えなくしておいて23日に完全停止するらしい。
つまり今（8/18）は5/6時間は使える状態で、試したときはたまたま使える時間帯だった、という結論のようだ。

# 今後どうするか

1. Streaming APIの代替として提供されるらしい、Account Activity APIというので書き直してみる
 - Twythonが対応してくれるかどうかわからないので、API直叩きするコードを書く必要あり？
 - お勉強ネタとしては面白いかも
1. どうせ自分しか使わないbotなので、1分くらいごとにpollingするように書き直す
 - この際Twython使わずに自前で書いてみようか

-> とりあえずpollingでちゃんと動くのかどうか書いてみようと思う