😀

【Python】TwitterAPIとtweepyを使用してツイート自動化を行う方法

2022/06/12に公開

よく記事にあがっているようなPythonによるTwitterの投稿でハマった箇所があったので、実装の振り返りをしつつ記事に残しておこうと思います。

実装

add_tweet.py
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になっていました。

スクリーンショット 2022-06-12 10.16.04.png

そのため、GETリクエストの実行は行えても、POSTリクエストでは書き込み権限のエラーが出てしまいます。
だからこそ、初期状態のReadではなく、Read and writeないしRead and write Direct messageに設定を変更することでエラーを解消できます。

なお、一度、設定を変更するとAccess TokenならびにAccess Secret Tokenの再発行が必要となるので、その点だけ注意が必要です。

※ tweepyでなく、APIを叩く場合も同様

簡単な実装ですが、意外とハマりやすい箇所なので、403と怒られている方には参考になるのではないでしょうか。

ツイートを自動化する

上記に加え、投稿の自動化を行い、定期的にツイートしたい場合は、コードを以下のように変更します。

add_tweet.py
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.

そのため、上記のコードを少し変更します。

add_tweet.py
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開発支援

tweepy + Twitter API V2でツイート

sched --- イベントスケジューラ

【Python】Scheduleモジュールを用いたイベント定期実行|指定時間動作のスケジュール関数作成例と使い方解説

処理を一時停止!Pythonでsleepを使う方法【初心者向け】

Pythonを使ってランダムな文字列を生成

Discussion