Lambdaで定時刻に呟くDiscord Botを作る

# やりたいこと

AWSのLambdaを用いて、毎分0秒に「やっほー」と呟くDiscordのBotを作成します。

## 本記事の対象者

* とりあえずLambdaで何かしてみたい方
* サーバーレスでBotを作ってみたい方

## 前提条件

Discordの開発者ポータルからアプリ作成＋Bot作成は済んでおり、**Botトークン**が取得できている状態（まだない方は、簡単なのでぜひ取得してみてください）
![スクリーンショット 2024-04-07 17.48.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287737/9613f259-3894-b6e8-227e-fc337b3a4c2e.png)
↑こちらの画面のToken発行ボタンから取得するものです。
※Botのアイコン画像は[ぷしおメーカー](https://vps1-net000.sfc.keio.ac.jp/pushiomaker/)様で作成しました。

# 1. 関数の作成

1. Lambdaコンソールを開く
1. 「関数の作成」を押す
1. 「一から作成」を選択
1. 関数名は「discordBotMessage」
1. ランタイムは「Python3.11」
1. 他の項目はそのままで「関数の作成」を押す

![スクリーンショット 2024-04-07 17.25.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287737/e168001b-fec0-bf74-aa6b-6b1ad1204b2b.png)


これでdiscordBotMessage関数が作成されますので、ここからコーディング開始…といきたいところですが、次に「レイヤー追加」という作業をします。

## レイヤーの追加
レイヤーとは、Lambdaの仕様の一つで、外部のライブラリ等を使用するためのものです。
コードをzipにしてアップロードすることで、Lambda関数内で任意のプログラムが使用可能になります。
今回、pythonでHTTP通信するための**requests**を使用したいので、そのためのレイヤーを追加します。

### Zipの作成

ローカルで以下実行（pipが使えない方は[こちらの記事](https://qiita.com/ohbashunsuke/items/e7c673db606a6dced8a6)を参考にしてください）

```zsh
mkdir python
pip install -t python requests
zip -r9 layer.zip python
```
**layer.zip**が作成されます。

### レイヤー作成
1. Lambdaコンソールのメニューから「レイヤー」を押す
1. 「レイヤーの作成」を押す
1. 名前に「python-requests」
1. アップロードボタンからlayer.zipをアップロード
1. 互換性のアーキテクチャ両方にチェック
1. 「作成」を押す

![スクリーンショット 2024-04-07 17.31.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287737/f7a4b43a-7fdb-05b6-db15-67eafcc0562b.png)


### レイヤーの追加

1. discordBotMessage関数のページに戻り、画面下部「レイヤーの追加」を押す
1. 「カスタムレイヤー」を選択し、プルダウンから「python-requests」を選択、バージョンに「1」を選択して「追加」ボタンを押す

![スクリーンショット 2024-04-07 17.33.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287737/583672b3-64d8-6437-87e5-825eb718aeb9.png)

# 2. 関数のコーディング

discordBotMessage関数に以下実装（Botトークンをソース直書きはあまり望ましくないと思いますが、今回はなるべく簡略に済ましたいので…）

```python:discordBotMessage.py
import json
import requests

def lambda_handler(event, context):

    # Discord APIのエンドポイント [channel_id]にはボットメッセージ送信先のチャンネルIDを入れてください
    url = "https://discord.com/api/channels/[channel_id]/messages"
    # ヘッダー [bot_token]には使用するBotトークンを入れてください
    headers = {
        "Authorization": "Bot [bot_token]",
        "Content-Type": "application/json"
    }

    # 送信内容
    payload = {
        "content": "やっほー"
    }
    
    # POSTリクエストを送信
    r = requests.post(url, json=payload, headers=headers)
    data = r.json()

    # ログに結果を出す
    print(json.dumps(data))
```
DiscordのチャンネルIDの取得については、[こちらの記事](https://note.com/mss_discord/n/nbe5eb71294f0)を参考にして取得してください。（めちゃ簡単です！）

実装できたら、「Deploy」を押してください。

# 3. Test実行

まずはちゃんと関数が動くかを検証します。
1. 「Test」を押す
1. 「テストイベントを設定」というモーダルが出ますが、何も入力せず「呼び出す」を押す

![スクリーンショット 2024-04-07 17.39.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287737/0174011b-4f9b-5a98-df69-52380752a8a4.png)
Discordに通知が来てるのを確認できました。

# 4. トリガーを設定する

Lambdaを実行するためのトリガーを設定します。今回は、定時刻に実行したいのでEventBridgeを設定します。

1. 「関数の概要」の「トリガーを追加」を押す
1. プルダウンから「EventBridge」を選択
1. 「Create a new rule」を選択
1. Rule nameに「discord-bot-message」と入力
1. Schedule expressionに`cron(* * ? * * *)`を入力し、「追加」を押す

![スクリーンショット 2024-04-07 18.02.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287737/83cf191e-0758-333b-209a-160db0975907.png)

#### 備考

Schedule expressionの時刻指定ですが、UTC時間なので注意
例：日本の朝10時の場合は`cron(0 1 ? * * *)`と指定（日本時間にするため-9時間する）

# 5. 動作確認

![スクリーンショット 2024-04-07 17.46.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287737/a2a52ddd-9f2d-dc90-d3f8-3af91ade2a83.png)
毎分０秒にメッセージが来ているのが確認できました！

# まとめ

いかがでしたでしょうか？Lambdaを触ったことがなかった方も、なんとなくLambdaがどんなものかが分かったのではないかと思います。トリガーには様々なAWSサービスを設定できるので、いろいろ試してみてください！

# 告知
最後にお知らせとなりますが、イーディーエーでは一緒に働くエンジニアを
募集しております。詳しくは採用情報ページをご確認ください。

https://eda-inc.jp/recruit/

みなさまからのご応募をお待ちしております。