X(Twitter)のツイートをWordPressへ自動投稿する方法(API+Python利用)
SNSやブログなど様々な発信方法が用意されているインターネットの世界。
複数の発信方法を運用されている方も多いですが、1回の発信で複数の場所に投稿できると便利だと思う方も多いと思います。
私もそんなことを思っていた一人。
ということで、先人が築き上げてくれた情報を基にして「IFTTT」を活用してTwitterのツイートをWordPressへ自動投稿できるようにしました。
しかし、ある日Twitterに仕様変更があり、その影響でブログの見た目が変わってしまいました。
写真付きツイートなのに、ブログだと写真が見えなくなってしまったのが一番嬉しくありません(苦笑)
ということで、IFTTT以外での連携方法を調べて、TwitterのAPIを使ったWordPressへの自動投稿の仕組みを構築しました。
もしかしたら参考になる方がいるかも知れないと思い、今回記事にまとめています。
同じようなことを考えていらっしゃる方に対して、参考になれば幸いです。
■<重要>この記事を読むために必要な前提条件と免責事項について
説明を始める前に、この記事を読む、および実践するために必要な前提条件を示します。
■Pythonを使ったX(Twitter)からWordPressへの自動投稿方法とは?
Pythonを使ったTwitterからWordPressへの自動投稿のイメージです。
ちょっと難しく感じる所もありますが、自由にカスタマイズできるのがこの方法の魅力。
この後、実際に動かしているプログラムコードの要点なども交えてご紹介してまいります。
■[準備1]TwitterのAPIの利用許可を取りましょう!(英文頑張って…)
自動投稿プログラムを作るにあたり、まず必要なのはTwitterのAPIの利用手続き。
Twitter社にAPIの利用申請を行います。
TwitterのAPIは、Twitterへのツイートや、ツイートの検索、アカウントの情報を取り出す…など、多種多様な機能が提供されています。
APIには無料(standards APIs)と有料(Premium APIs, Enterprize APIs)のものがありますが、今回の目的のように自分自身のツイートだけを取り出す程度の使い方であれば、無料のAPIが利用できます。
なお有料、無料に関わらず、利用申請は必要です。
Twitter APIの利用申請方法は、検索ワードに「Twitter API 申請」と入力して検索しましょう。
申請手順は多いのですが、最初から最後まで丁寧に説明されたWebサイトの記事が多数存在、Youtubeによる動画で説明されているケースもあります。
私も複数のWebサイトの記事を参考にさせて頂きました。
ちなみに申請に関する記述は、すべて英語。
APIの利用目的などをすべて英文で記載する必要があります。
英文が苦手な方(←私もそうでした)は、Google翻訳などの翻訳サイトを活用しましょう。
■TwitterのAPIの利用申請が通らなかった!…質問が返ってきたら、必ず返信を
Twitter APIの利用申請ですが、初回申請で却下されたという情報がWebサイトに多数掲載されています。
ご多分に漏れず、私の申請も却下されました。
却下された時、Twitterからメールが返信されてきます。
不明点に対する質問が掲載されている場合は、質問に対する回答を記載して返信します。
もちろん質問は英文で書かれていますので、回答も英文で返します。
Twitter APIの申請が通らない場合の回答事例は、Webサイトに多数あり、参考にすることが可能です。
私も3往復やりとりしましたので、これからトライする人の参考になればと思い、やりとりを掲載します。
※なお、2021年2月時点の内容に基づいていおり、最新の状態で100%実現を保証するものではありません。あらかじめご了承下さい。
★1往復目
★2往復目
★3往復目
★利用申請の許可が下りました!(申請から3日後)
■[準備2]PythonをWebサーバーにインストール
TwitterのAPIの利用申請を出している間にPythonを使えるようにしましょう。
検索ワードに「Python インストール」と入力すると、たくさんの有益な情報がヒットします。
詳細はそちらを見て頂くとして、私の事例をご紹介します。
① レンタルサーバーに、Pythonをインストールします。
参考Webサイト:Qita の記事
Pythonのバージョンは、3.9.1 を選択しました。(2021年2月時点での最新バージョン)
$ pyenv install 3.9.1
② 1回目のPython 3.9.1のインストールは失敗。
コンパイルエラーが発生していました。
調べた結果、レンタルサーバーに標準で入っているgcc(Cコンパイラ)のバージョンが4.2.1とかなり古いことが判明。
$ /usr/bin/gcc -v
Using built-in specs.
Target: amd64-undermydesk-freebsd
Configured with: FreeBSD/amd64 system compiler
Thread model: posix
gcc version 4.2.1 20070831 patched [FreeBSD]
$
対策として、最新のバージョン 10.2.0のgccをインストールしました。
$ gcc -v
:
gcc バージョン 10.2.0 (GCC)
$
③ 2回目のPython 3.9.1のインストールを始めますが、またも失敗。
1回目の失敗時のコンパイルエラーは解消しましたが、今度はリンケージエラーが発生。
/usr/bin/ld: Dwarf Error: found dwarf version '4', this reader only handles version 2 in formation.
libpython3.9.a(_localemodule.o): In function `PyIntl_bindtextdomain':
_localemodule.c:(.text+0x27b): undefined reference to `libintl_bindtextdomain'
libpython3.9.a(_localemodule.o): In function `PyIntl_dcgettext':
_localemodule.c:(.text+0x369): undefined reference to `libintl_dcgettext'
libpython3.9.a(_localemodule.o): In function `PyIntl_dgettext':
_localemodule.c:(.text+0x3b2): undefined reference to `libintl_dgettext'
libpython3.9.a(_localemodule.o): In function `PyIntl_gettext':
_localemodule.c:(.text+0x3fa): undefined reference to `libintl_gettext'
libpython3.9.a(_localemodule.o): In function `PyIntl_textdomain':
_localemodule.c:(.text+0x779): undefined reference to `libintl_textdomain'
collect2: error: ld returned 1 exit status
gmake: *** [python] Error 1
gmake: *** Waiting for unfinished jobs....
このリンケージエラーの解消方法が、なかなか見つからず難航。
結局、zlibというパッケージのインストールが必要ということが判明。
ただzlibをインストールするだけではだめで、zlibを入れた後にgccを再インストールするという手順が必要でした。
(要するに②のgccインストールが不完全だったという訳)
④ 3回目のPython 3.9.1のインストールでようやく成功。
ここまで1週間ほどかかりました。長かったです。
● Pythonのインストールログより
Installing collected packages: setuptools, pip
WARNING: The script easy_install-3.9 is installed in '/home/xxxxxxxxxxxx/.pyenv/versions/3.9.1/bin' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
WARNING: The scripts pip3 and pip3.9 are installed in '/home/xxxxxxxxxxxx/.pyenv/versions/3.9.1/bin' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pip-20.2.3 setuptools-49.2.1
~/tmp/python-build.20210211191413.1445 ~
$ python -V
Python 3.9.1
$
■[準備3]必要となるPythonのパッケージをWebサーバーにインストール(Twitter向け)
PythonからTwitter APIを発行するために必要となるPythonのパッケージをインストールします。
$ pip install requests requests-oauthlib
参考Webサイト:Qiita の記事
■[準備4]Twitterへアクセスするための情報を取得
[準備1]Twitter APIの利用申請が許可されたら、Twitterにアクセスするための情報を取得します。
必要な情報は以下の5種類。
①~④は、Twitter Developer PlatformからDeveloper Portalにアクセスして取得します。
・Twitter Applicationを新しく登録後、①②を取得
・アクセス情報を生成して③④を取得
取得した情報はテキストファイルで保存します。
後で再確認することはできません(再発行必須)ので、その場で忘れずに保存しましょう。
詳細は参考Webサイトを参照して下さい。
参考Webサイト:Qiitaの記事([準備3]で紹介したものと同じ記事)
⑤はTwitterのユーザー名ではなく、ユーザーに一意で振られている数字だけのIDです。
検索ワードに「Twitter ユーザーID 確認」と入力すると、確認方法を記載したWebサイトの記事が多数見つかります。
■[準備5]必要となるPythonのパッケージをWebサーバーにインストール(WordPress向け)
PythonからWordPressへの投稿や投稿取得を行うために必要なPythonのパッケージをインストールします。
$ pip install python-wordpress-xmlrpc
検索ワードに「python wordpress xml-rpc」と入力すると、パッケージインストールの手法を記したWebサイトが見つかります。
■[準備6]Twitterのツイートを取得するプログラムを試作
TwitterのAPIが正しく動作するか否かの確認を兼ねて、Twitterのツイートを取得するプログラムを試作します。
プログラムのコードは以下のとおり。
#-------------#
# test01.py # Tweet Get
#-------------#
import json, ACSK_T # 標準のjsonモジュールとアクセスキーの読み込み
from requests_oauthlib import OAuth1Session # OAuthのライブラリの読み込み
CK = ACSK_T.CONSUMER_KEY
CS = ACSK_T.CONSUMER_SECRET
AT = ACSK_T.ACCESS_TOKEN
ATS = ACSK_T.ACCESS_TOKEN_SECRET
twitter = OAuth1Session(CK, CS, AT, ATS) # 認証処理
# APIのエンドポイント指定
endpoint = "https://api.twitter.com/2/users/xxxxxxxxxxxx/tweets?tweet.fields=created_at,author_id,conversation_id,geo,text,entities&user.fields=username&exclude=retweets,replies&max_results=5"
# ↑
# TwitterのユーザーID
res = twitter.get(endpoint)
if res.status_code == 200: # 正常通信出来た場合
timelines = json.loads(res.text) # レスポンスからタイムラインリストを取得
print(json.dumps(timelines,ensure_ascii=False,indent=2)) # ダンプする
else: # 正常通信出来なかった場合
print("Failed: %d" % res.status_code)
#---------------#
# ACSKEY_T.py # Twitter Access Information
#---------------#
CONSUMER_KEY = "xxxx" # Consumer Key (API key)
CONSUMER_SECRET = "xxxx" # Consumer Secret (API Secret key)
ACCESS_TOKEN = "xxxx" # Access Token
ACCESS_TOKEN_SECRET = "xxxx" # Access Token Secret
Twitterのアクセス情報を示す ACSKEY_T.py とTwitterのツイートを取得するtest01.py の2本のプログラムを作成し、同じディレクトリに配置します。
※使用するTwitter APIの詳しい説明については、Twitter Developer Platformのマニュアル「GET /2/users/:id/tweets」を確認して下さい。(すべて英語)
準備が正しく完了していれば、このプログラムを動かすと直近から最大5ツイートの情報を取り出すことができます。
$ python test01.py > $TMPDIR/tweet.txt
取り出したツイートの情報は以下のとおり。
'data' リストの中にある赤枠の部分が1ツイート分の情報です。
Pythonでは辞書として読み込むことができます。
ここからプログラム test01.pyの後半を書き換えて、WordPressに投稿したい情報をピックアップできるようにします。
#-------------#
# test01.py # Tweet Get
#-------------# (後半のみ)
:
res = twitter.get(endpoint)
if res.status_code == 200: #正常通信出来た場合
timelines = json.loads(res.text) #レスポンスからタイムラインリストを取得
for tweet in timelines['data']: #タイムラインリストをループ処理
print(tweet['conversation_id'])
print(tweet['created_at'])
print(tweet['text'])
print(tweet['entities']['urls'][0]['expanded_url'])
print(tweet['entities']['urls'][0]['start'])
print(tweet['entities']['urls'][0]['end'])
print('*******************************************')
else: #正常通信出来なかった場合
print("Failed: %d" % res.status_code)
この例ではツイートの情報から以下に示す内容を取り出します。
プログラムの動作結果は以下のとおり。
これでツイートを取得できることが確認できました。
■[準備7]WordPressへ投稿するプログラムを試作
python_wordpress_xmlrcパッケージを使ってWordPressへ投稿するプログラムを試作します。
プログラムのコードは以下のとおり。
※noteの仕様上、コード+画像+コードと分かれていますが、まとめて1本のプログラムとなります。
#-------------#
# test02.py # WordPress Post
#-------------#
import json
import time
from datetime import datetime
from wordpress_xmlrpc import Client, WordPressPost
from wordpress_xmlrpc.methods.users import GetUserInfo
from wordpress_xmlrpc.methods.posts import GetPosts, NewPost
import ACSKEY_W # アクセスキーの読み込み
def main():
#==============
# ★ Block 2 ★
#==============
post = WordPressPost()
# 投稿内容編集
btitle = "タイトル"
bcontent = "本文です"
btermnames = dict() # カテゴリ辞書を初期化
ctg_list = "風景 Twitter" # カテゴリを指定
btermnames['category'] = ctg_list.split() # リスト化して格納
btime = "2021-02-17T05:17:49.000Z"
# 下書きに投稿するか本番で投稿するか選択
which="draft" # draft/Publish
post.post_status = which
# タイトル
post.title = btitle
# 本文
post.content = bcontent
# タグ、カテゴリ
post.terms_names = btermnames.copy()
# 過去に投稿した記事としたい場合、投稿日を指定
post.date=datetime.strptime(btime,"%Y-%m-%dT%H:%M:%S.%fZ")
#==============
# ★ Block 3 ★
#==============
# WordPressへ投稿する
post_id = wp.call(NewPost(post))
if __name__=="__main__":
main()
#---------------#
# ACSKEY_W.py # WordPress Access information
#---------------#
BLOG_I = "xxxx" # 投稿先のWordPressのユーザーID(管理者権限あり)
BLOG_P = "xxxx" # WordPressのパスワード
WordPressのアクセス情報を示す ACSKEY_W.py とWordPressへの投稿を行うtest02.py の2本のプログラムを作成し、同じディレクトリに配置します。
プログラムのコードを説明します。
① [Block 1] WordPressとの通信を行うクライアントの作成
3種類の情報を用意します。
変数 BIにユーザー名、変数 BPにパスワードを設定します。
変数 BURL には、WordPressで公開中のブログに備わっているリモート手続きを行えるXMLRPCの入口となるURLを設定します。
通常は「ブログのURL」+"/xmlrpc.php"になります。
②[Block 2] 投稿する情報を設定
#==============
# ★ Block 2 ★
#==============
post = WordPressPost()
# 投稿内容編集
btitle = "タイトル"
bcontent = "本文です"
btermnames = dict() # カテゴリ辞書を初期化
ctg_list = "風景 Twitter" # カテゴリを指定
btermnames['category'] = ctg_list.split() # リスト化して格納
btime = "2021-02-17T05:17:49.000Z"
# 下書きに投稿するか本番で投稿するか選択
which="draft" # draft/Publish
post.post_status = which
# タイトル
post.title = btitle
# 本文
post.content = bcontent
# タグ、カテゴリ
post.terms_names = btermnames.copy()
# 過去に投稿した記事としたい場合、投稿日を指定
post.date=datetime.strptime(btime,"%Y-%m-%dT%H:%M:%S.%fZ")
WordPressPostオブジェクトを作成後、WordPressの記事として投稿する情報を用意します。必要な情報は以下の5つです。
タグ、カテゴリに複数の情報を設定する時は、1つのリストに複数の情報を設定し、そのリストをterms_namesに格納します。
dateに投稿日時を設定すると、WordPressの記事の投稿時刻がその日時に変わります。
post_statusに"publish"を設定すると、投稿と同時に記事が公開されます。テストする際は"draft"としてプログラムの動作を確認しましょう。
③[Block3] WordPressへ投稿
#==============
# ★ Block 3 ★
#==============
# WordPressへ投稿する
post_id = wp.call(NewPost(post))
[Block2] で用意したWordPressPostオブジェクトを[Block1]で準備したクライアントに渡して、WordPressへ投稿します。
投稿に成功すると、正の整数値としてクライアントから投稿した記事のIDが返されます。
post_statusを"draft"としておけば、ダッシュボード上で記事の出来上がり方を確認した後、公開すればOK。プログラムの問題がなくなってきたら"publish"に変更することで自動的に記事が公開されるようになります。
■ 後は2つのプログラムを合体するだけ…では足りません!
Twitterからツイートを取得するプログラムとWordPressへ投稿するプログラムができましたので、あとは合体すれば完成\(⌒_⌒)/
のように思えますが、実現にはもう少し考える必要があります。
これらの疑問について、この後、答えていきます。
ここから先は
¥ 1,200
気に入って頂けたら、サポートして頂けると嬉しいです。情報発信のための活動費に充てさせて頂きます。