こんばんは!
表題の件ですが、こんなの簡単に出来るだろうと思っていたのですが、非常に嵌りました。
詰まったところを含めて、設定及びコードを公開します。
正直、かなり試行錯誤しました。間違っている所がありましたら、是非、御指摘ください。 私の苦難が皆様のお役に立てます様に。。。。
1.状況
一週間前に下記の記事を書きました。
ローカル環境で、Twitterのツイートを自動RetweetするBOTを、Pythonで構築しました。
⇒ [Python] Tweepyモジュールで、Tweeterのツイートを自動でretweetするBOTを超簡単に作成する方法 https://qiita.com/naiveprince0507/items/ea66eab7422fa8c682f5
自分のローカル環境では順調に動くのですが、当然ですが、PCの電源を落としたりすれば、プログラムが動かなくなります。これでは、BOTとしてはイマイチですよね。
と言う事で、クラウド環境で、このコードを、24時間/365日、動かし続けようと言うのが、今回のプロジェクトになります。
2.Google Cloud Functionについて。
Googleのサーバレス環境で構築します。(要は、PaaS環境です。)
尚、Googleでは、Cloud RunとCloud Functionと言う2種類のサーバレス環境が用意されております。
詳しい違いは下記サイトに書いておりますが、私の理解では、「簡単な関数(今回の様に、Pythonの単純なプログラムを動かす場合等)では、Cloud Functionを使い、コンテナ環境を構築し、複雑な処理をするプログラムを動かすなら、Cloud Runを使うべし。」と言う理解です。
https://cloud.google.com/blog/ja/topics/developers-practitioners/cloud-run-story-serverless-containers
今回は、Cloud Functionを使います。これは、AWSでは、Lambdaに相当します。(多分)
3.ローカルで動いているコード(「原文」と称する)
import tweepy
import time
from requests_oauthlib import OAuth1Session
CK = "Your Consumer Key"
CS = "Your Consumer Secret Key"
AT = "Your Access Token"
ATS = "Your Access Token secret"
twitter = OAuth1Session(CK, CS, AT, ATS)
def retweet(tweetId):
url = "https://api.twitter.com/1.1/statuses/retweet/%s.json"%tweetId
res = twitter.post(url) # retweet実行
return res
def unretweet(tweetId):
url = "https://api.twitter.com/1.1/statuses/unretweet/%s.json"%tweetId
res = twitter.post(url) # unretweet実行
return res
# リツイートしたいIDのリスト
#tweetIds = [line.strip() for line in open('retweetList.txt',encoding='utf-8')]
# リツイート履歴を保存する準備
retHist = {}
from time import time
def retweetProcess():
### 最後にリツイートした時間が最も遠いものを選ぶ ###
# IDと時刻のペアをリスト化
idTimes = [(tid,retHist[tid] if tid in retHist else 0) for tid in tweetIds]
# 最後にリツイートした時刻でソート
idTimes = [idt for idt in sorted(idTimes, key=lambda x:x[1])]
# 最後にリツイートした時刻が最も古いツイートを選択
tweetId = idTimes[0][0]
# 一度解除してからretweet
resUnrt = unretweet(tweetId)
resRt = retweet(tweetId)
# 処理内容を表示
print(tweetId, resUnrt, resRt)
# 現在の時刻で辞書の値を更新
retHist[tweetId] = time()
from time import sleep
while True:
sleep(60*15) # これは15分毎にリツイートです。
retweetProcess()
4. GCFで設定
Google Cloudにログオンして、GCFを設定します。
「エントリーポイント」ですが、実行したい関数名(ここでは、retweetProcess)と一致させる必要があります。(ここで、丸1日詰まりました。)
また、29行目のコードですが、3の「原文」では、引数不要でしたが、ここでは、"self"を入れないとエラーになります。(原因を調査中です。)
で、この"Requirements.txt"とは何ぞやとの事ですが、ここをキチンと設定しないとエラーになります。(ここで、丸一日費やしました。)
ここに詳しいです。(要は、インストールするモジュールを列記する必要があります。)
https://qiita.com/sakusaku12/items/21083c73c8afa4f6c78d
最後は、リツイートしたいTwitterのTweetIDを並べます。
で、最終工程です。
トリガーを叩くと(URLサイトにアクセスすると)、プログラムが起動して、下記の画面が出る事を確認した。(正常な動作です。)
https://qiita.com/toshiaki_takase/items/ce65cd5582a80917b52f
スケジューラーで、1時間に1回、上記URLを叩くように、Google Schedulerで設定します。(これは、超簡単)
5.懸念点/継続調査事項
1)GCFのmain.pyの29行目のコードですが、3の「原文」では、引数不要だったが、GCFこには、"self"を入れないとエラーになる。(原因を調査中です。)
2)トリガーを叩くと(URLサイトにアクセスすると)、プログラムが起動して、下記の画面が出る事を確認した。(正常な動作です。)
(ただ、設定中に、下記サイトの様なアクセス権エラーが出たので、下記サイトの方法で解決したが、こんなにガバガバで良いのか? 継続調査中)
https://qiita.com/toshiaki_takase/items/ce65cd5582a80917b52f