0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

読書会用のDiscord botのスケジュール実行をGitHub Actions→AWS Lambdaに切り替えたメモ

Posted at

はじめに

Discordサーバーで「もくもく読書会」なるゆるーい読書会を定期開催しており、その運営をサポートする 2種類の機能を持つBot を作成しました。

  • 読書ログを自動でまとめて投稿するBot(週次)
  • 読書会のリマインドや開始・終了をお知らせするBot(スケジュール実行)

最初はすべて GitHub Actions で実装していたのですが、 読書会の「開始・終了合図」には向いていない という気づきから、一部を AWS Lambda + EventBridge に切り替えました。

読書ログを自動でまとめて投稿するBotの内容は別の記事にメモしてます。本記事では、もう一つのリマインドする機能について記載します。

構成要素:読書会の合図投稿(開始前・開始時・終了5分前)

  • 「明日の朝やります!」
  • 「読書開始の合図です」
  • 「終了5分前です〜感想を投稿してね」 などを自動投稿。
  • イベントの直前通知なので、 正確な時刻での実行 が求められます。

イベントの直前通知が目的なので、正確なタイミングでの実行が重要です。これまでは手動で投稿していましたが、読書に集中するために、Botに任せることにしました。

image.png

GitHub Actions ではなく AWS Lambda を選んだ理由

GitHub Actions を試したときの課題

  • スケジュール(cron)を設定しても、最大で1時間程度のラグが発生することがありました。
  • 読書会の「開始1時間後に『始めます』が届く」といった事態も起こりえます。

これらの理由から、タイミングが重要な通知には不向きであると判断しました。

AWS Lambda + EventBridge にした理由

項目 GitHub Actions AWS Lambda + EventBridge ローカルサーバー
実行の正確性 △ 少しラグあり ◎ 秒単位で正確 ◎ 秒単位で制御可能
管理・保守 ◎ GitHubに集約 △ LambdaとGitHubで分散 △ サーバー管理が必要
実行コスト ◎ 無料プランあり 〇 週1程度ならほぼ無料 〇 電気代程度
拡張性 △ 限定的 ◎ 他のAWSサービスと連携可 ○ ローカルで自由に拡張可能

スケジュール通知BotはLambda or ローカルが相性良し。読書ログBotはGitHub Actionsで十分。
Raspberry Pi や常時稼働のLinuxマシンがあるなら、ローカルサーバーでの運用でもOKです。

AWS Lambda 側の構成

ファイル構成(一部抜粋)

.
├── greet_lambda.py           # モード(day_before/start_notice/end_notice)で定型文送信
├── lambda_package/           # Lambda用のコード+依存ライブラリ(requestsなど)
├── lambda.zip                # アップロード用zipファイル
└── .github/workflows/booklog.yml # GitHub Actionsのスケジュール設定

greet_lambda.py は、例えば以下のような内容です。
引数で以下のモードを受け取り、メッセージを投稿します。

  • day_before:「明日の朝やります!」
  • start_notice:「読書開始の合図です」
  • end_notice:「終了5分前です〜感想を投稿してね」
import os
import discord
import asyncio

DISCORD_TOKEN = os.environ["DISCORD_BOT_TOKEN"]
CHANNEL_ID = int(os.environ["DISCORD_CHANNEL_ID"])

MESSAGES = {
    "day_before": "明日の朝も「もくもく読書会」やります!\nジャンル不問ですし、ほかの人の面白そうな本と出合えるかもしれません。気軽にご参加ください~!",
    "start_notice": "おはようございます☀ 今日ももくもく読書していきましょう!\n\n「読む本のタイトル or 内容」を軽く投稿してください。\n例:「○○の設計思想(3章から)読みます」\n\n📖読書スタート📖",
    "end_notice": "終了5分前~アウトプットタイムです\n読んだ内容や感想・学びを共有(短くてもOK!)"
}

async def send_message(mode):
    intents = discord.Intents.default()
    client = discord.Client(intents=intents)

    @client.event
    async def on_ready():
        print(f"Discordに接続成功!モード: {mode}")
        channel = await client.fetch_channel(CHANNEL_ID)
        await channel.send(MESSAGES.get(mode, f"(未定義モード: {mode}"))
        await client.close()

    await client.start(DISCORD_TOKEN)

def lambda_handler(event, context):
    print("Lambda 起動")
    print(f"イベント受信: {event}")

    # モード取得とバリデーション
    mode = event.get("mode")
    if not mode:
        print("[Error] モードが指定されていません")
        return {
            "statusCode": 400,
            "body": "Error: 'mode' must be specified in the event payload."
        }

    if mode not in MESSAGES:
        print(f"[Error] 無効なモード: {mode}")
        return {
            "statusCode": 400,
            "body": f"Error: Invalid mode '{mode}' specified."
        }

    print(f"使用モード: {mode}")
    asyncio.run(send_message(mode))
    return {
        "statusCode": 200,
        "body": f"Message sent in mode: {mode}"
    }

Lambdaデプロイ手順

Lambda関数の作成

  1. AWSマネジメントコンソールにログイン
  2. 「Lambda」→「関数の作成」→「一から作成」
  3. 関数名、ランタイム(例:Python 3.10)を設定
  4. 適切なIAMロールを設定
    ※ Secrets Manager等へのアクセスを許可しておくと便利です

環境変数の設定(Lambda内)

環境変数キー 内容
DISCORD_BOT_TOKEN Discord Bot のトークン
DISCORD_CHANNEL_ID 投稿先チャンネルのID

Lambda ZIPパッケージの作成とアップロード

ZIPパッケージの作成手順

mkdir lambda_package
# 必要なPythonスクリプトやライブラリを配置
pip install -r requirements.txt -t lambda_package
cp greet_lambda.py lambda_package/
cd lambda_package
zip -r ../lambda.zip .

ZIPのアップロード手順

  1. Lambda関数の「コード」タブを開く
  2. 「アップロード」→「.zipファイルをアップロード」を選択
  3. 作成した lambda.zip をアップロードし、保存
  • Lambda のタイムアウト設定は 最低10秒以上 を推奨します。3秒だとタイムアウトになりました。

テスト実行

Lambda管理画面 → 「テスト」で以下のようなJSONを指定します。

{
  "mode": "start_notice"
}

mode には day_before, start_notice, end_notice のいずれかを指定します。

image.png

※ CloudWatch Logs で実行ログも確認可能です。

EventBridgeによるスケジュール実行

EventBridge → 「ルールの作成」から、以下のスケジュールを設定します。

GitHub ActionsではUTC時刻での設定ですが、EventBridgeではJST時刻で時間指定することができます。日本人にとってはわかりやすいです。

例えば、毎週金曜の21:00にリマインドをする場合、cron式で00 12 ? * FRI * と記述します。

image.png

ターゲットの選択オプションで、今回作成したDiscord bot用のLambda関数を指定し、ペイロードに JSON形式で引数を指定します。

image.png

今回は3つのリマインドを引数を変えて実行するので、以下の3つのスケジュールを作成します。

image.png

以下のように投稿してくれるようになります。

image.png

今後の展望

  • 定型文ではなく、毎回異なるあいさつをするように対応
  • Botからリアクションを返す機能
  • リマインドBotもGitHubでバージョン管理しやすい構成へ改善

まとめ

Botの種類 実行基盤 実行頻度 備考
読書ログまとめ GitHub Actions 週1 or 月1回 まとめるだけなら十分
読書会リマインド AWS Lambda 毎週3回 イベント直前通知に最適

シンプルなBotでも、自動化すると運営の負担がかなり軽くなりました。
個人の備忘録ですが、同じように読書会やイベントを運営している方や、自動化ツールの参考になれば幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?