バンダイ出荷表の更新を通知する Twitter bot を作ってみた

作成してみた Twitter bot

 こちらの記事でバンダイ出荷表の PDF を Google カレンダーに出力するプログラムを作成しましたが、それを自動で定期実行させて出荷表が更新されていたら Twitter で呟く bot を作成してみました。

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 でやっているだろうなー)