よく記事にあがっているようなPythonによるTwitterの投稿でハマった箇所があったので、実装の振り返りをしつつ記事に残しておこうと思います。
実装
from pprint import pprint
import tweepy
import config
api_key = config.TWEETER_API_KEY
api_secret_key = config.TWEETER_API_SECRET_KEY
access_token = config.TWEETER_ACCESS_TOKEN
access_secret_token = config.TWEETER_ACCESS_SECRET_TOKEN
def clinet_info():
"""認証情報を返却する関数
Returns:
_type_: Client
"""
client = tweepy.Client(
consumer_key=api_key,
consumer_secret=api_secret_key,
access_token=access_token,
access_token_secret=access_secret_token
)
return client
# ツイートするテキスト
message = 'Hello World'
def create_tweet(message):
"""ツイートを行う関数
Args:
message (_type_): str
Returns:
_type_: str
"""
tweet = clinet_info().create_tweet(text=message)
return tweet
pprint(create_tweet(message))
コード自体はよくあるものですが、これで実行すると、HTTP403エラー
となります。
エラーの原因
結論から言うと、APIの設定に問題がありました。
具体的には、アプリケーションのパーミッションが、現在設定されているRead and write
でなく初期状態のRead
になっていました。
そのため、GETリクエスト
の実行は行えても、POSTリクエスト
では書き込み権限のエラーが出てしまいます。
だからこそ、初期状態のRead
ではなく、Read and write
ないしRead and write Direct message
に設定を変更することでエラーを解消できます。
なお、一度、設定を変更するとAccess Token
ならびにAccess Secret Token
の再発行が必要となるので、その点だけ注意が必要です。
※ tweepyでなく、APIを叩く場合も同様
簡単な実装ですが、意外とハマりやすい箇所なので、403
と怒られている方には参考になるのではないでしょうか。
ツイートを自動化する
上記に加え、投稿の自動化を行い、定期的にツイートしたい場合は、コードを以下のように変更します。
from pprint import pprint
import tweepy
import schedule
from time import sleep
import config
api_key = config.TWEETER_API_KEY
api_secret_key = config.TWEETER_API_SECRET_KEY
access_token = config.TWEETER_ACCESS_TOKEN
access_secret_token = config.TWEETER_ACCESS_SECRET_TOKEN
def clinet_info():
"""認証情報を返却する関数
Returns:
_type_: Client
"""
client = tweepy.Client(
consumer_key=api_key,
consumer_secret=api_secret_key,
access_token=access_token,
access_token_secret=access_secret_token
)
return client
# ツイートするテキスト
message = 'Hello World'
def create_tweet(message):
"""ツイートを行う関数
Args:
message (_type_): str
Returns:
_type_: str
"""
tweet = clinet_info().create_tweet(text=message)
return tweet
# スケジュールを定義(10秒ごとに投稿)
schedule.every(10).seconds.do(create_tweet, message=message)
# イベントを実行
while True:
# 定義したスケジュールで処理を実行する
schedule.run_pending()
# 1秒ごとにスケジュール定義した関数を呼び出す
sleep(1)
scheduleモジュール
とsleep関数
をインポートして、スケジュールを定義し、ループ処理をするという内容を追加します。
ただし、これをそのまま実行するとツイートの重複はできない
と以下のエラーが出ます。
tweepy.errors.Forbidden: 403 Forbidden
You are not allowed to create a Tweet with duplicate content.
そのため、上記のコードを少し変更します。
import random, string
def random_message(n):
"""n個のランダムな文字列を生成する関数
Args:
n (_type_): int
Returns:
_type_: str
"""
return ''.join(random.choices(string.ascii_letters + string.digits, k=n))
def create_tweet():
"""ツイートを行う関数
Args:
message (_type_): str
Returns:
_type_: str
"""
# ツイートするメッセージ
message = random_message(10)
tweet = clinet_info().create_tweet(text=message)
return tweet
# スケジュールを定義(10秒ごとに投稿)
schedule.every(10).seconds.do(create_tweet)
# イベントを実行
while True:
# 定義したスケジュールで処理を実行する
schedule.run_pending()
# 1秒ごとにスケジュール定義した関数を呼び出す
sleep(1)
randomモジュール
とstringモジュール
をインポートして、ランダムな文字列を生成する関数を定義します。
その関数をツイートを生成する関数内で呼び出し、create_tweet()
に渡すことでランダムな文字列を投稿できます。
また、それに付随し、スケジュールを定義している箇所では、第二引数で渡していたmessage
を削除するひつようがあります。
このようにすると、定期的(上記のコードでは10秒ごと)にツイートを行うことができ、ツイートの自動化ができます。
※ 投稿したい内容をリストで定義し、ループで回し自動化する方法もあるかと思いますので、各々の仕様に合わせて実装してみてください。
私の場合は、「単純に定期投稿できるか」というテスト実装なので、上記実装となっています。
参考文献
・【Python×Twitter】自動ツイート(投稿)を定期実行する方法|APIとtweepyを用いたbot開発支援
・【Python】Scheduleモジュールを用いたイベント定期実行|指定時間動作のスケジュール関数作成例と使い方解説