Twitterの特定キーワードを含むツイートをリアルタイムにSlackに転送するスクリプト

Twitterをモニタリングして、特定キーワードを含むツイートをリアルタイムにSlackに転送する方法について紹介します。スプリプトはpython3で、ツイートのリアルタイム取得には、Twitter APIの`statuses/filter.json`を利用しています。

# システム概略図

こんなシステム構成を想定します。この記事では、この図の左下にある`twitter_monitoring.py`のスクリプトの例を紹介します。

![システム構成図03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315655/e5a57b03-65e5-d534-23af-effb9bb3a7ae.png)

スクリプトの動作としては、Twitter APIの`statuses/filter.json`で特定キーワードを含むツイートを取得し、Slack API経由でそのツイートをSlackbotが任意のチャネルに投稿するようにします。

# 事前準備

Twitter APIとSlack APIを利用するための準備をします。

## Twitter APIアカウント作成

### 取得対象トークン

Twitter APIアカウントを作成し、下記の4つのトークンを入手できたらOKです。

- API key
- API secret key
- Access token
- Access token secret

### 作成方法

アカウント作成方法については、下記サイトが参考になりました。

- https://www.itti.jp/web-direction/how-to-apply-for-twitter-api/
- https://dev.classmethod.jp/articles/twitter-api-approved-way/
- https://cre8cre8.com/python/twitter-api.htm



## Slackbotの作成

Slack APIのページから、ツイートの投稿ユーザとなるBotを作成します。

### 取得対象トークン

Slackbot作成後に、Slack API管理サイトの`OAuth & Permissions`のページから、下記のトークンを入手できたらOKです。

- Bot User OAuth Access Token

### 作成方法


Slackbotの作成方法については、下記サイトが参考になりました。

- https://techacademy.jp/magazine/27979
- https://belltree.life/slack-bot-hands-on/

### スコープ(権限)

Slackbotのスコープ(権限)設定は、今回の用途では`chat:write`のみ許可すれば十分です。

# Pythonスクリプト

今回作成する`twitter_monitoring.py`について解説します。

## コード全体

下記はPythonスクリプトのコーディング例(全45行)です。

```python:twitter_monitoring.py
# coding: utf-8
import json
import logging
from time import sleep

import requests_oauthlib
import slack

# Parameters
keyword = 'keyword' # 任意の検索キーワードを指定する

# Twitter parameters
consumer_key = 'xxxxxxxxxxxxxxxxxxxxxxxxx' # Twitter API key
consumer_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' # Twitter API secret key
access_token = '9999999999999999999-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' # Twitter Access token
access_token_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' # Twitter Access token secret

# Slack parameters
bot_token = "xoxb-999999999999-9999999999999-xxxxxxxxxxxxxxxxxxxxxxxx" # Slack Bot User OAuth Access Token
channel_id = 'xxxxxxxxxxx' # Slack channel ID

# Logging
logging.basicConfig(filename='twitter_monitoring.log', format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=logging.WARNING)

# 処理
uri = 'https://stream.twitter.com/1.1/statuses/filter.json'
twitter_session = requests_oauthlib.OAuth1Session(consumer_key, consumer_secret, access_token, access_token_secret)
slack_client = slack.WebClient(token = bot_token)

while True:
    try:
        logging.info("Request to Twitter API.")
        twitter_response = twitter_session.post(uri, data=dict(track=keyword), stream=True)
        if twitter_response.status_code != 200: # Twitter rate limitに引っかかった場合など
            logging.warning("status_code:%s, reason:%s", twitter_response.status_code, twitter_response.reason)
            sleep(900) # 15分待機
            continue
        for line in twitter_response.iter_lines():
            if not line: # 該当ツイート無し
                logging.info("No any tweets.")
                continue
            tweet_dict = json.loads(line.decode("utf-8"))
            tweet_link = 'https://twitter.com/i/web/status/' + tweet_dict['id_str']
            slack_response = slack_client.chat_postMessage(channel = channel_id , text = tweet_link) # ツイートのリンクをSlackに転送
    except Exception as e:
         logging.error(f'{e}')
```

### 設定パラメータ

コード自体が短いので、この例ではスクリプト内に設定パラメータを埋め込んでいます。下記の変数に、各種トークンとパラメータの値を指定します。

|分類|対象| 変数名 | 説明 |
|:--|:--|:--|:--|
|トークン|Twitter|consumer_key |Twitter API key   |
|トークン|Twitter|consumer_secret  |Twitter API secret key   |
|トークン|Twitter|access_token  |Twitter Access token   |
|トークン|Twitter|access_token_secret  |Twitter Access token secret   |
|トークン|Slack|bot_token | Slack Bot User OAuth Access Token  |
|パラメータ|Twitter| keyword  |  Twitterの検索キーワード |
|パラメータ|Slack| channel_id  | 投稿先Slack チャネルID[^1]  |

[^1]: SlackチャネルのリンクURLの末尾部分。

キーワードに一般的な用語を指定してこのスクリプトを実行すると、転送先のSlackチャネルが大量のツイートで溢れかえってしまう可能性があるため、まずはテスト用のSlackチャネルで試すことを推奨します。

### ロギング設定

デバッグ用に`logging`の設定を入れていますが、不要であれば削除しても大丈夫です。このまま実行すると、下記の動作をします。

- 実行時に同じディレクトリ上に`twitter_monitoring.log`のログファイルが出力される。
- `logging.info`で定義されたログも出力するには、事前にコード内の`logging.basicConfig`の`level`パラメータを`logging.INFO`に変更しておく。

## スクリプト実行方法

下記の方法で、Pythonスクリプトを実行します。

### Pythonライブラリ

必要なPythonライブラリを、事前にインストールしておきます。

```bash
sudo pip install --upgrade pip
sudo pip install slackclient
sudo pip install requests_oauthlib
sudo pip install logging
```

### 実行コマンド

下記コマンドで、pythonスクリプトを実行します。

```bash
nohup python twitter_monitoring.py &
```
nohupで実行することで、Python実行機からログアウトしても、スクリプトが実行され続けるようにします。


以上で完了です。実行後、keywordに指定した文字列を含むツイートのリンクが、転送先のSlackチャネルにリアルタイムに転送され続けることを確認します。

# 結果

成功すると、ツイートがSlackにこのように転送されるようになります。

![twitter_mozaic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315655/ff2dfa69-2b4d-360c-4566-009827d2f0f3.png)



# 備考

- [Twitter API 利用規約](https://developer.twitter.com/ja/developer-terms/agreement-and-policy
)