はじめに
私はaws初心者です。lambdaで困ったことがあったからメモとして残します。
やりたいこと
lambda functionを時間指定で1回だけ実行したい
想定しているケース
・ あるイベントがまとまったページを監視して、新しいイベントが登録されたらイベントが開催される1日前にLINEで通知する。
この場合だと、
Lambda①:スクレイピング→Lambda②の時間予約(新しいイベントの1日前)
(イベント情報も渡す)
Lambda②:関数①から受け取った情報をLINEに送信
どうしたか
使ったもの:Lambda、EventBridge
補足
EventBridgeは定期実行とかをしてくれるらしい。この定期実行の規則をルールと呼ぶ。
Lambda①
import boto3
client = boto3.client('events')
event_name = "ルールの名前"
description = "ルールの説明"
event_time = "cron(* * * * ? *)" #実行したい時間を満たすようにする(*を全部指定してあげるとミスがない)
lambda_id = 'lambda functionを識別するためのID'
lambda_arn = 'lambda②のArn'
lambda_name = "ambda②の関数名"
def register():
# ルールを追加
response = client.put_rule(
Name=event_name,
ScheduleExpression= event_time,
EventPattern='',
State='DISABLED',
Description=description)
# 実行したい関数を登録
d = {
"name": event_name,
"text": "lambda②で送りたいテキスト"
}
response = client.put_targets(
Rule=event_name,
Targets=[
{
'Id': lambda_id,
'Arn': lambda_arn,
"Input": json.dumps(d)
}
]
)
# ルールの有効化
response = client.enable_rule(
Name=event_name
)
# 初回は許可を与えないと実行してくれない
#lclient = boto3.client("lambda")
#response = lclient.add_permission(
# FunctionName=lambda_name,
# StatementId="1",
# Action='lambda:InvokeFunction',
# Principal='events.amazonaws.com',
#)
Lambda②
import boto3
def delete_rule(d):
client = boto3.client('events')
lambda_id = 'lambda functionを識別するためのID' #lambda①と同じにする
# 定期実行の関数(自分自身)をターゲットから外す
res = client.remove_targets(
Rule=d["name"],
Ids = [
lambda_id
]
)
# ルールそのものを削除する
res = client.delete_rule(
Name=d["name"]
)
return res
def send(d):
# d["text"]を送信
def lambda_handler(event, context):
delete_rule(event)
r = send(event)
Lambda①で実行したい時間をcronで満たすようにルールを設定して、
Lambda②が実行するときにそのルールを削除するというやり方でやりました。
もっといい方法があれば是非お願いします。