1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Lambdaを使ってDiscordBot(Python)の実行

Last updated at Posted at 2024-09-28

はじめに

今回作成したDiscordBot(Python)は、Discordのチャンネルに対してメッセージを書き込むものを作成しました。
また、毎日0:00に書き込んでほしいので、EventBridgeからLambdaを起動して書き込む仕組みにしました。

用途としては、FiveMのガソリンスタンドを経営しており、ガソリンの価格を日々変更したく、一定の範囲のランダム値を投稿するのと、ゲーム内でのX(ツイッター)でポストするためのテンプレート文章をDiscordのチャンネルに投稿するものを作成しました。

構成イメージ

EventBridgeからLambdaを起動して、Discordのチャンネルにメッセージを書き込みます。
【全体の概要構成】
image.png

【EventBridgeとLambdaの構成】
image.png

Discordの動作イメージ

特定のチャンネルに対して、毎日0:00に価格がランダム(280-420の間)でDiscordBotがメッセージを記載します。
image.png

↑この文章をコピペして、ゲーム内でつぶやいています。

Pythonのコード

lambda_function.py
import discord
import random
import os
import asyncio

TOKEN = os.environ['DISCORD_BOT_TOKEN']
CHANNEL_ID = int(os.environ['DISCORD_CHANNEL_ID'])
CHANNEL_ID_TW = int(os.environ['DISCORD_CHANNEL_ID_TW'])

intents = discord.Intents.default()
client = discord.Client(intents=intents)

async def send_gas_price():
    await client.wait_until_ready()
    channel = client.get_channel(CHANNEL_ID)
    channel_tw = client.get_channel(CHANNEL_ID_TW)
    
    if channel is not None:
        price = round(random.uniform(280, 420), 2)
        message = f"本日のガソリン販売価格は {price} 円です"
        await channel.send(message)
        
    else:
        print("チャンネルが見つかりません")

    if channel_tw is not None:
        message = f"本日の8140番地GSのガソリン販売価格は {price} 円/Lです!!\n(他のGSは、700円台/Lです)"
        await channel_tw.send(message)
        
    else:
        print("チャンネルが見つかりません")

@client.event
async def on_ready():
    await send_gas_price()
    await client.close()

def lambda_handler(event, context):
    loop = asyncio.get_event_loop()
    loop.run_until_complete(client.start(TOKEN))

DiscordBotのトークンやチャンネルIDはLambdaの環境変数に登録して呼び出します。

TOKEN = os.environ['DISCORD_BOT_TOKEN']
CHANNEL_ID = int(os.environ['DISCORD_CHANNEL_ID'])
CHANNEL_ID_TW = int(os.environ['DISCORD_CHANNEL_ID_TW'])

なお、チャンネルは複数にメッセージを書き込むため、2つ用意しています。

DiscordBotのトークンやチャンネルIDの確認については、過去の記事を参照してください。

Lambdaでのデプロイ

外部ライブラリ(dicord.py)を使用するため、Zipにまとめてのデプロイを実施しています。

事前準備

1)アップロードするディレクトリを作成します。

mkdir 35-GS-price-Discord-Bot
cd 35-GS-price-Discord-Bot 

2)外部ライブラリをフォルダに格納(install)します。

pip install discord.py -t .
pip install requests -t .

3)同じディレクトリ内にlambda_function.pyを作成します。
 (上記で記載しているpythonコード)

4)35-GS-price-Discord-Botフォルダをzipで圧縮します。

Lmabdaの作成

AWSマネージメントコンソールからLabmda関数を作成します。

スクリーンショット 2024-09-28 13.33.15.png
[選択する内容]
関数名:任意の名前
ランタイム:Python 3.12
アーキテクチャ:任意

【Zipのアップロード】

image.png

アップロード元で.zipファイルを選択しアップロードします。

image.png

タイムアウト値の変更

デフォルトの3秒だと、タイムアウトしてしまうので、タイムアウト値を30秒に変更します。
スクリーンショット 2024-09-28 15.01.09.png

image.png

Lambdaの環境変数の設定

Lambdaの画面から「設定」タブをクリックし、左メニューの「環境変数」をクリックすします。
キーにpythonで記載したキー名(DISCORD_BOT_TOKENなど)を記載し、値にトークンやチャンネルIDを入力します。

image.png

スクリーンショット 2024-09-27 12.18.44.png

EventBridgeの設定

Lambdaを毎日0:00に実行するEventBridgeを作成します。
今回はLabmdaの画面から[+トリガーを追加]をクリックします。

image.png

トリガーの設定で[EventBridge(CloudWach Envets)]を選択します。
image.png

新規のルールを作成を選択し、ルール名とスケジュール式を入力します。

image.png

Linuxのcronとは若干書式が異なります。また、UTCのため0時に起動するためには15時にする必要があります。

動作テスト

Lmabdaの動作テストをするには、テストタブから[テスト]をクリックします。
※今回のスクリプトはそのままの実行できます。

スクリーンショット 2024-09-28 15.38.12.png
[結果画面]
image.png

これでLambdaのデプロイとEventBridgeの設定は完了です。

最後に

今回は定期的に呟くDiscordBotであり、常時起動させておく必要がなかったため、Lambdaで実装しました。
また、今回はLambdaでのDiscordBot実装が初めてだったのと、今後の他のDiscordBotをLambdaで作成する予定もないため、Lambdaレイヤーは使わずに、外部モジュールも全部合わせてZipにしています。
次回は、Lambdaレイヤーを使った実装に挑戦してみようと思います。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?