teriyaki note

好きなものはラーメンと将棋

友人の特定ツイートにクソリプを自動的に送りたい

(Python 2.7.13)

Twitter APIを使ってみたという記事は山ほどあるので、今更という感じだが

成果物

特定のユーザが"二郎"という単語を含んだツイートをすると、自動的に二郎に誘うリプを送る
(二郎:一部の人が大好きな高カロリーラーメン)

f:id:teriyaki398:20181001141813j:plain

Twitter API の準備

これも多くの人が解説してくれてるので、そちらを参照しよう

Twitterアプリケーションの作成(Consumer key、Consumer secret、Access token、Access token secretの確認方法)

Twitter REST APIの使い方

以下の4つの情報が取得できればOK * Consumer Key (API Key) * Consumer Secret (API Secret) * Access Token * Access Token Secret

Python ライブラリ

わざわざライブラリを使うまでもないとは思うが、圧倒的に楽なので

様々なライブラリが存在するが、今回はこちらを用いる

GitHub - sixohsix/twitter: Python Twitter API

以下のコマンドでインストールする

% pip install twitter

基本的には以下のような形で用いる

各認証情報は先ほど取得したものに置き換える

また、タイムラインなどは辞書型で取得される

from twitter import *

# 認証情報
CONSUMER_KEY        = "Consumer Key"
CONSUMER_SECRET     = "Consumer Secret"
ACCESS_TOKEN        = "Access Token"
ACCESS_TOKEN_SECRET = "Access Token Secret"

twitter = Twitter( auth=OAuth(ACCESS_TOKEN, ACCESS_TOKEN_SECRET, CONSUMER_KEY, CONSUMER_SECRET) )

home_timeline = twitter.statuses.home_timeline()    # ホームのタイムラインを取得(デフォルトは20件)
user_timeline = twitter.statuses.user_timeline(screen_name="@xxxx")    # 指定したユーザのタイムラインを取得
twitter.statuses.update(status="hello")    # "hello" とつぶやく

指定できるパラメータの情報などはこの辺りで確認しよう

POST statuses/update — Twitter Developers

特定のツイートに対してリプをする

各ツイートにはidが設定されており、ツイートの際にこのidを指定することで、特定のツイートにリプが返せる

ユーザ@xxxx のツイートid yyyyにリプするときは以下のようにする

status_id = "yyyy"
twitter.statuses.update(status="@xxxx hello", in_reply_to_status_id=status_id)

基本的な流れは、

  1. ユーザのタイムラインを取得
  2. 取得したツイートのテキストにキーワードが含まれているかを判定
  3. リプ済IDリストを確認し、まだリプしていないならクソリプし、IDをリストに追加
  4. 1分ほど待って、1.に戻る

これを繰り返すことで、自動的にチェックしてリプする

同じツイートにリプを返さないように、一度リプしたものは除外する処理が必要

# coding:utf-8

from twitter import *
import time

# 認証情報
CONSUMER_KEY        = "Consumer Key"
CONSUMER_SECRET     = "Consumer Secret"
ACCESS_TOKEN        = "Access Token"
ACCESS_TOKEN_SECRET = "Access Token Secret"

SCREEN_NAME = "@xxxx"


twitter = Twitter(auth=OAuth(ACCESS_TOKEN, ACCESS_TOKEN_SECRET, CONSUMER_KEY, CONSUMER_SECRET))
status_id_list = [] # 同じツイートにリプしないように、リプしたidを記録しておく

while True:
    # secreen_nameのユーザのタイムラインを取得
    tweet_list = twitter.statuses.user_timeline(screen_name=SCREEN_NAME)

    # 二郎に関するツイートをしていた場合、クソリプを送る
    for tweet in tweet_list:
        if tweet["text"].find(u"二郎") != -1:    # 探せなかった場合は、-1が帰ってくる
        
            status_id = str(tweet["id"])

            # まだリプしていないツイートがあったらリプする
            if status_id not in status_id_list:
                twitter.statuses.update(status="だったら、二郎行こうぜ", in_reply_to_status_id=status_id)
                status_id_list.append(status_id)

                if len(status_id_list) >= 20:  # 20以上保持する必要はないので、必要に応じて減らす
                    status_id_list = status_id_list[1:]
    time.sleep(60)

プログラムを動かしっぱなしにすることを想定しているため、timeで制御している

cronなどで定期的にプログラムを実行させる方法もある

(こちらの場合は、IDリストを外部ファイルに書き出す必要がある)