動機
Blueskyで日本各地の花粉情報を教えてくれるbotを作成しました。
作成するに当たり、AWS CDKを使ってbot作成している記事がほとんど無かったので共有します。
概要
EventBridge SchedulerでLambdaを定期的に呼び出し、Lambdaからatprotoを使って投稿するというシンプルなもの
1.アカウントIDのパスワードを払い出す
こちらの記事を参考にアカウントID,パスワードを生成します。
パスワードは1度しか表示されないのでメモを忘れないように
2.投稿するためのLambdaを書く
atprotoというライブラリを使います。
from atproto import Client
from city_name_list import place
import os
import random
import logging
def lambda_handler(event,context):
client = Client(base_url='https://bsky.social')
client.login(login=os.environ.get("LOGIN"),password=os.environ.get("PASSWORD"))
place_len = 1892
place_num = random.randint(0, place_len-1)
kahun_num = random.randint(0, 1000000)
message = f'{place()[place_num]}の花粉は例年の{kahun_num}倍です'
client.send_post(message)
client = Client(base_url='https://bsky.social')
client.login(login=os.environ.get("LOGIN"),password=os.environ.get("PASSWORD"))
で自アカウントにログイン
client.send_post(message)
で投稿しています。
ログインIDとパスワードはcdkのスタックの環境変数で定義したものを取得しています。
※city_name_list
は都道府県市町村のリストです。
3.スタックの定義
atprotoは標準のライブラリではないため、普通にLambdaでimportするとエラーがでます。
そこでDockerImageを使ってLambdaの定義をしていきます。
※最初はLambda Layerを使って作成しようとしたのですが、何故かimport errorが出るのでDockerにしました。
from aws_cdk import aws_lambda as _lambda
from aws_cdk import aws_events as events
from aws_cdk import aws_events_targets as targets
from aws_cdk import Duration, Stack
from constructs import Construct
class BlueSkyStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
#Dockerfileがあるディレクトリを指定
my_function_image = _lambda.DockerImageCode.from_image_asset("Bluesky_app")
my_function = _lambda.DockerImageFunction(
self, "FunctionName",
code=my_function_image,
memory_size = 128,
environment={
"LOGIN": "your_login_id",
"PASSWORD": "your_password",
},
)
rule = events.Rule(
self,
"my-bot-trigger",
schedule=events.Schedule.rate(Duration.hours(1))
)
rule.add_target(targets.LambdaFunction(my_function))
4.Dockerfileの定義
# 基本イメージとしてPythonのDockerイメージを使用
FROM public.ecr.aws/lambda/python:3.11
# Pythonの依存関係のインストール
COPY requirements.txt .
RUN python3.11 -m pip install -r requirements.txt
# Lambda関数のコードをコピー
COPY lambda_function/app.py .
COPY lambda_function/city_name_list.py .
# Lambdaのエントリポイントを設定
CMD ["app.lambda_handler"]
requirements.txtにはatproto
のみを書いています。
5.デプロイ
あとはcdk deploy
でデプロイするだけです。
参考情報
デプロイする際に以下のようなエラーメッセージが出ました
The stack named BlueSkyStack failed to deploy:
UPDATE_ROLLBACK_COMPLETE: Resource handler returned message:
"Invalid request provided: Updating PackageType is not supported"
(RequestToken: 92f7c6c5-26dd-00c8-df2d-149f0aab09ea, HandlerErrorCode: InvalidRequest)
Dockerを使用する前にLambda Layerで頑張っていたのですが、その時のスタック名(selfの次の引数)が被っていたことによるエラーでした。
スタック名を変えることでエラーを回避できました。
この記事を参照にしました。本当にありがとう
参考文献