paloma blog

NWエンジニアやってます。主に自宅環境のお遊びを書きます。Pythonもちょっと。タイトルは好きなカクテルから。

twitter API v2でtweepyからPOSTする

自分用の映画視聴履歴としてtwitterに投稿しておくという事をやっているのですが昨年からAPIが有料になるどうこうで4月半ばから投稿ツールが使えなくなってしまいました。
v2用のナレッジもそろってきたという事で投稿ツールを修正しました。

ツールの投稿系の動作はこちらです。

paloma69.hatenablog.com

v2の変更

変更点は公式や色々なサイトに乗っていますので割愛します。

Developer portalのアカウントがfree, basic, proと有料プランが増えたのが大きな変更でしょうか。
投稿ツールのためにお金出すのもなあということでfreeプランを使います。

認証系詳しくないのですがOath2.0というのになったようで新しくBearer tokenというものが増えました。

Developer portalで取得できますのでこの辺も割愛します。

インタラクティブインタシェルで練習

v2用のキー系を取得したので練習します。
tweepyも関数が変わりますのでこちらもアップデートしました。

ちなみに動かしていたUbuntuが電源故障で壊れたのでメインWindowsのWSL上に退避させました。

(python3) masashi@DESKTOP-HBP3520:/mnt/c/Users/masashi/share/ubuntubackup/movietweet$ pip list
Package            Version
------------------ ---------
…
tweepy             4.14.0

認証。

>>> import configure, tweepy
>>> client = tweepy.Client(bearer_token=configure.BA)
>>>
>>> client.get_me()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>

(略)

    raise TypeError("Consumer key must be string or bytes, not "
TypeError: Consumer key must be string or bytes, not NoneType

Bearer tokenだけだとダメ見たいです。
公式Docに書いてあるのになあ。

一応ConsumerキーやAccess token系も投入。

>>> client = tweepy.Client(bearer_token=configure.BA, consumer_key=configure.CK, consumer_secret=configure.CS, access_token=configure.AT, access_token_secret=configure.AS)
>>> client.get_me()
Response(data=<User id=xxxxxxxxxx name=masashi username=palomax69>, includes={}, errors=[], meta={})

自分のユーザ情報は取れました。
自分のツイートはというと…

>>> client.get_users_tweets(xxxxxxxxxx) # <- User idを入れてます
Traceback (most recent call last):
  (略)
    raise Forbidden(response)
tweepy.errors.Forbidden: 403 Forbidden
When authenticating requests to the Twitter API v2 endpoints, you must use keys and tokens from a Twitter developer App that is attached to a Project. You can create a project via the developer portal.

Developer portalのProjectに紐づいてないからダメって言われます。
紐づいてるんだけどな。

freeプランはPOST、DELETEのみでした

プランの内容をよく見てみるとfreeはPOST、DELETEと自分のユーザのみ見れるようです。

GET使えないと困りますが、一旦POSTだけ出来ればいいか。

POSTしてみます。

>>> client.create_tweet(text='post from api v2')
Response(data={'edit_history_tweet_ids': ['1672791196266266625'], 'id': '1672791196266266625', 'text': 'post from api v2'}, includes={}, errors=[], meta={})

いったっぽい。

OKですね。

コード修正

投稿用の認証とPOST周りのコードを修正します。
といってもちょっとコマンド変えただけ。

(python3) masashi@DESKTOP-HBP3520:/mnt/c/Users/masashi/share/ubuntubackup/movietweet$ git diff tweetapi.py
diff --git a/tweetapi.py b/tweetapi.py
index 793e395..24f6c34 100755
--- a/tweetapi.py
+++ b/tweetapi.py
@@ -3,15 +3,14 @@
 import tweepy
 import configure

+Bearer_Token=configure.BA
 Consumer_Key=configure.CK
 Consumer_Secret=configure.CS
 Access_Token=configure.AT
 Access_Secret=configure.AS

 def TWauth():
-    auth = tweepy.OAuthHandler(Consumer_Key, Consumer_Secret)
-    auth.set_access_token(Access_Token, Access_Secret)
-    api = tweepy.API(auth)
+    api = tweepy.Client(bearer_token=Bearer_Token, consumer_key=Consumer_Key, consumer_secret=Consumer_Secret, access_token=Access_Token, access_token_secret=Access_Secret)

     return api
(python3) masashi@DESKTOP-HBP3520:/mnt/c/Users/masashi/share/ubuntubackup/movietweet$ git diff posttw.py
diff --git a/posttw.py b/posttw.py
old mode 100644
new mode 100755
index 0ce3f30..08682a6
--- a/posttw.py
+++ b/posttw.py
@@ -6,5 +6,5 @@ import sys
 api = TWauth()

 # ツイート
-api.update_status(sys.argv[1])
+api.create_tweet(text=sys.argv[1])

投稿

昨日BLADEというヴァンパイアハンターのアクション映画を見たので投稿してみます。

(python3) masashi@DESKTOP-HBP3520:/mnt/c/Users/masashi/share/ubuntubackup/movietweet$ bash twmovieinfo.sh blade
2023-06-25に「Blade」を視聴しました。

Infomation
---
Year: 1998
Genre: Action, Horror, Sci-Fi
Director: Stephen Norrington
Actors: Wesley Snipes, Stephen Dorff, Kris Kristofferson
Production: N/A
---

from API v2

投稿しますか?: [y/n]y
投稿を完了しました。
tweepy.errors.Forbidden: 403 Forbidden
220 - Your credentials do not allow access to this resource.

のエラーが出ていません。
上手くいった様ですね。

無事投稿も出来てます!

まとめ

API仕様が変更になってからすぐ対応したかったのですがいろんな事情でなかなかできませんでした。
手動で投稿したりと運用は出来ていたものの修正してもPOSTしかできないのでは少し困りますね。
2回同じ映画を見ないようにこのツールを作ったのでGET機能もセットで欲しいところです。有料プランにするかスクレイピングしか方法が思いつきません。

自宅ラボも出来たことだし新しい記録方法を考えてみてもいいかもしれませんね。