4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Python】苦闘、丸3日。Google Cloud Function (コード実行環境)を使って、Twitterの自動リツイートを実装した話。

Last updated at Posted at 2021-09-25

こんばんは!
表題の件ですが、こんなの簡単に出来るだろうと思っていたのですが、非常に嵌りました。
詰まったところを含めて、設定及びコードを公開します。
正直、かなり試行錯誤しました。間違っている所がありましたら、是非、御指摘ください。 私の苦難が皆様のお役に立てます様に。。。。

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.ローカルで動いているコード(「原文」と称する)

.py
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を設定します。
0925x.jpg

保存ボタンを押すと、「次へ」ボタンが出現します。
0925y.jpg

「エントリーポイント」ですが、実行したい関数名(ここでは、retweetProcess)と一致させる必要があります。(ここで、丸1日詰まりました。)
0925z.jpg

また、29行目のコードですが、3の「原文」では、引数不要でしたが、ここでは、"self"を入れないとエラーになります。(原因を調査中です。)
0925c1.jpg
0925c5.jpg
で、この"Requirements.txt"とは何ぞやとの事ですが、ここをキチンと設定しないとエラーになります。(ここで、丸一日費やしました。)
ここに詳しいです。(要は、インストールするモジュールを列記する必要があります。)
https://qiita.com/sakusaku12/items/21083c73c8afa4f6c78d
0925c2.jpg
最後は、リツイートしたいTwitterのTweetIDを並べます。
0925c3.jpg

で、最終工程です。
トリガーを叩くと(URLサイトにアクセスすると)、プログラムが起動して、下記の画面が出る事を確認した。(正常な動作です。)
https://qiita.com/toshiaki_takase/items/ce65cd5582a80917b52f
0925c4.jpg

スケジューラーで、1時間に1回、上記URLを叩くように、Google Schedulerで設定します。(これは、超簡単)
0925c6.jpg

5.懸念点/継続調査事項
1)GCFのmain.pyの29行目のコードですが、3の「原文」では、引数不要だったが、GCFこには、"self"を入れないとエラーになる。(原因を調査中です。)

2)トリガーを叩くと(URLサイトにアクセスすると)、プログラムが起動して、下記の画面が出る事を確認した。(正常な動作です。)
(ただ、設定中に、下記サイトの様なアクセス権エラーが出たので、下記サイトの方法で解決したが、こんなにガバガバで良いのか? 継続調査中)
https://qiita.com/toshiaki_takase/items/ce65cd5582a80917b52f
0925c4.jpg

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?