これがシン・タイトル!
サーバーレス LT vol.2
2022/05/26 nikkie
PythonとAWS LambdaでTwitter Bot 簡単 かもと思っていただく
AWSは独学なので、自分よりも詳しい方から、実装へのフィードバックを得たい
アイの歌声を聴かせて を知っていただく(達成)
Pythonに限らない話題(AWSの構成など)を聞いていただければ!
本当に簡単だと思うので、Pythonの素振りとして試してみては(またはお使いの言語で書き換えてみては)
アイの歌声を聴かせてのおすすめリンク 見ます?
その名も @harmonizer_bot
5/26は #アイの歌声を聴かせて 公開🎬から210日目です。
— sing_a_bot_of_harmony (@harmonizer_bot) May 25, 2022
Blu-ray&DVDリリース📀まで今日を含めてあと62日です(7/27発売。現在予約期間)。
今日も、元気で、頑張るぞっ、おーっ
秘密1
秘密2
秘密3
AWS のデベロッパー向けウェブマガジン
ソリューションアーキテクトの皆様による 豊富な記事
メールメンバーに登録すると、特典(AWSのクーポン)いただけます
金澤さん(a.k.a @ketancho さん)による毎月連載(2022年1月〜)
Twitter Bot を開発・運用しながら AWS を学んでいただきます。(第1回より)
第3回も一部参照しています
ドリル4回分残しているので、拡張しがいがあって最高!
https://aws.amazon.com/jp/builders-flash/202201/aws-drill-twitter-bot-1/
Bot用のTwitterアカウントを用意
Twitter APIを介すと、Twitterアカウントにツイートさせられる
つまり、Twitter Bot= Bot用アカウントでツイートするプログラム
Twitter API v2 の Essential access は申請不要で使える!
Bot用アカウントでdeveloper accountを登録し、APIのキーやトークンを払い出す
詳しくは https://developer.twitter.com/en/docs/twitter-api/getting-started/getting-access-to-the-twitter-api
POST https://api.twitter.com/2/tweets
ドリルに沿って、OAuth 1.0a User Contextを使っています
https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets
import os
from requests_oauthlib import OAuth1Session
# 環境変数の読み込み
consumer_key = os.getenv("TWITTER_API_KEY")
client_secret = os.getenv("TWITTER_API_KEY_SECRET")
access_token = os.getenv("TWITTER_API_ACCESS_TOKEN")
access_token_secret = os.getenv("TWITTER_API_ACCESS_TOKEN_SECRET")
oauth = OAuth1Session(consumer_key, client_secret, access_token, access_token_secret)
payload = {"text": "#アイの歌声を聴かせて 面白いからみんな観て"}
response = oauth.post("https://api.twitter.com/2/tweets", json=payload)
ツイートするプログラムを、定期的に自動で実行。それすなわちBot
AWS Lambda
Amazon EventBridge
先のツイートするプログラムをLambda関数にする
lambda_function.py
の lambda_handler
関数として実装(デフォルト設定に合わせる)
(手に馴染んだ言語に書き換えても素振りになるかもしれませんね)
import os
from requests_oauthlib import OAuth1Session
consumer_key = os.getenv("TWITTER_API_KEY")
client_secret = os.getenv("TWITTER_API_KEY_SECRET")
access_token = os.getenv("TWITTER_API_ACCESS_TOKEN")
access_token_secret = os.getenv("TWITTER_API_ACCESS_TOKEN_SECRET")
oauth = OAuth1Session(consumer_key, client_secret, access_token, access_token_secret)
def lambda_handler(event, context):
payload = {"text": "#アイの歌声を聴かせて 面白いからみんな観て"}
response = oauth.post("https://api.twitter.com/2/tweets", json=payload)
Lambda関数はevent(JSON)を受け取ると実行される(lambda_handler
関数の第1引数)
EventBridgeでeventを 発生 させる
定期的に、Lambda関数に対して(👉Lambda関数の日次実行)
3/21は #アイの歌声を聴かせて 公開から144日目です。
— sing_a_bot_of_harmony (@harmonizer_bot) March 20, 2022
今日も、元気で、頑張るぞっ、おーっ
秘密1: AWSドリル を参考にしました
秘密2
秘密3
Lambda関数をつぶやきの種類だけ作る?
1つのLambda関数の中で、この時間はこのつぶやきというロジックを書く?
この設計について、AWSに詳しい方からのフィードバック希望🙏
Lambda関数は1個(保守しやすい)
EventBridgeで 様々なevent を発生させる
14時には時報用event
20時には劇場情報用event
event
def lambda_handler(event, context):
# EventBridgeで発生させたevent(JSON)がevent引数に渡る
# eventはPythonの辞書という型(他の言語でいうMap)
# {"キー": "値"}
このeventを受け取って実行されたら、この振る舞いをすると実装
EventBridgeの 入力トランスフォーマー
Lambda関数で参照するキーと値をeventに追加する
{"bot-mode": "time-signal"}
def lambda_handler(event, context):
mode = event.get("bot-mode")
if mode == "information":
# informationモードの文面を作ってツイート
elif mode == "time-signal":
# time-signalモードの文面を作ってツイート
...
「何時にどういうeventが発生して、それによりこれこれのツイートをする」という構成
何時の部分は簡単に変えられる (8時にツイートしていたのを今日から9時にしよう)
EventBridgeのルール名は変更できないので、「何時」ではなく「やりたいこと」にした方がよかったです
https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-input-transformer-tutorial.html
入力パス
入力テンプレート
入力パスは変数定義。今回は使わないので {}
にしています
入力テンプレートは eventのJSON。何時ならこの値と固定しています
{
"bot-mode": "time-signal"
}
👩🏻🔬「にぃじ」
— sing_a_bot_of_harmony (@harmonizer_bot) May 26, 2022
アイの歌声を聴かせて 非公式Botが5/26の午後2時をお伝えします🌈
いいわ、いいわ!
秘密1:AWSドリルを参考にしました
秘密2: eventの種類を変え て、1日複数回ツイートさせています
秘密3
lambda_function.py
が肥大化するSmellを察知
Pythonのパッケージングで、薄くするのを試みる日々(エントリポイントは薄く!)
2つ紹介します
Lambda関数デプロイのハードルが下がり、捗りました
小さくこまめにリリース、楽しい
mkdir twitter-ainouta-bot
cd twitter-ainouta-bot
python -m pip install -t ./ -r ../requirements.lock
cp ../lambda_function.py .
zip -r twitter-ainouta-bot.zip ./
aws lambda update-function-code \
--function-name twitter-ainouta-bot \
--zip-file fileb://twitter-ainouta-bot.zip | \
jq 'del(.Environment, .FunctionArn, .Role)'
ドリルから変えて、Lambda関数の環境変数を使いました
aws lambda update-function-code の返り値(JSON)には 環境変数も含まれる!
jq は環境変数などを画面に出さないように追加しています(マスクする方法もあるらしい)
実務レベルではない可能性あるので、気になる点あればフィードバックください
開発中にコンソールを操作するアカウント
自動デプロイするためのアカウント
開発中にコンソールを操作するアカウント:Lambda full access
自動デプロイするためのアカウント:権限絞る(コンソールにログインしない)
full accessは広すぎるので、権限を絞る
するとコンソールが満足に操作できない
👉「これ、複数いるんだ!」と気づき
秘密1:AWSドリルを参考にしました
秘密2:eventの種類を変えて、1日複数回ツイートさせています
秘密3:Twitter Bot開発生産性アップtips! 2つ紹介
AWSドリル(の第1回)を参考に、アイうた応援Botを爆誕させました
AWS Lambda
Amazon EventBridge
eventの種類を変えて、1日複数回ツイートさせています
1つのLambda関数、複数種のevent
入力トランスフォーマー
Twitter Bot開発生産性アップtips!
ドリルのCloudShellのスクリプトをGitHub Actionsに移植
自動デプロイと開発、アカウントが分かれそう
あなたの応援したいものにTwitter Botを試してもらえたら嬉しいです(驚くくらい簡単でした!)