バンダイ出荷表の更新を通知する Twitter bot を作ってみた
作成してみた Twitter bot
こちらの記事でバンダイ出荷表の PDF を Google カレンダーに出力するプログラムを作成しましたが、それを自動で定期実行させて出荷表が更新されていたら Twitter で呟く bot を作成してみました。
- daily でガンプラ出荷表のアクセスし PDF を解析し、既に Google カレンダーに登録されている予定と比較する。
- 既存の予定と被るものが無ければ予定を Google カレンダーに登録する。
- Google カレンダーに登録されたら Twitter に通知する。
自動定期実行の方法
AWS Lambda + Cloudwatch Events でプログラムを自動で定期実行させています。AWS Lambda にはプログラムと必要なモジュール等を含んだコンテナイメージをデプロイしてます。というのも今回のプログラムのキモである、PDF からデータを抽出している tabula-py の実行には Java が必要で、AWS が提供している Python ランタイムではプログラムが実行出来ませんでした。(全部 Java で書けば問題いい気がしますが Python しか知らんのです。)
リソースの作成は terraform で行っています。以下がその tf ファイルになります。
resource "aws_ecr_repository" "get_gunpla_shipment" {
name = "get_gunpla_shipment"
}
resource "aws_ecr_lifecycle_policy" "get_gunpla_shipment" {
repository = aws_ecr_repository.get_gunpla_shipment.name
policy = <<EOF
{
"rules": [
{
"rulePriority": 1,
"description": "Expire images older than 3 days",
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 3
},
"action": {
"type": "expire"
}
}
]
}
EOF
}
resource "aws_iam_role" "iam_for_lambda" {
name = "iam_for_lambda"
managed_policy_arns = ["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_lambda_function" "get_gunpla_shipment" {
function_name = "get_gunpla_shipment"
package_type = "Image"
memory_size = 512
timeout = 60
role = aws_iam_role.iam_for_lambda.arn
image_uri = "653376028258.dkr.ecr.ap-northeast-1.amazonaws.com/get_gunpla_shipment@sha256:b00fda93202cadae15ecb7026a786bc60492017824a96ce1cc1e0fcfbbab4873"
}
resource "aws_cloudwatch_log_group" "get_gunpla_shipment" {
name = "/aws/lambda/get_gunpla_shipment"
retention_in_days = 7
}
resource "aws_cloudwatch_event_rule" "get_gunpla_shipment" {
name = "get_gunpla_shipment"
description = "Run Lambda get_gunpla_shipment"
schedule_expression = "cron(0 3 * * ? *)" #daily12:00JST
}
resource "aws_cloudwatch_event_target" "get_gunpla_shipment" {
rule = aws_cloudwatch_event_rule.get_gunpla_shipment.name
arn = aws_lambda_function.get_gunpla_shipment.arn
}
resource "aws_lambda_permission" "allow_cloudwatch_to_run_lambda" {
statement_id = "AllowExecutionFromCloudWatch"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.get_gunpla_shipment.function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.get_gunpla_shipment.arn
}
最初は当サイトを実行させているサーバーで実行させようと思ったのですが、上でも触れている tabula-py のインストールがメモリ不足で出来なかったのです。インストールしようとしたらサーバーからのレスポンスが無くなりサーバーを再起動をする羽目に。サーバーで実行するのが一番シンプル(かつ微々たるものとは言え Lambda のコスト増がない)とは思ったのですが….
これからの展望
次のことを考えています。
- プレミアムバンダイで予約開始前の商品が登録されたらTwitter に通知
- 特定のキットが、ヨドバシやビックカメラなどの Web ストアで販売、予約が再開されたら Twitter に通知
- 新しく追加されたキットに人気キット(例えば HGUC ナイチンゲール)が含まれていたらピックアップして Twitter で通知
いずれも Twitter で通知しています。通知するだけならメールや Slack とか手段は色々ですが、ここではパブリックな Twitter を選んでいます。最近ガンプラ界では色々と転売ヤーが話題になっていますが、おそらくは転売ヤーはこういった情報は当たり前のように収集していると思うので、せめてその転売ヤーとスタート位置を一緒にして1%でも純粋に欲しい人にキットが届くために Twitter に通知をしています。だからフォローしてね☆(ゝω・)vキャピ(ガチな転売ヤーは購入も bot でやっているだろうなー)