こしあん
2024-04-15

DiscordのbotコマンドをTerraformで管理する


225{icon} {views}


DiscordのbotのコマンドをTerraformから管理できるProvider(discord-interactions Provider)を見つけたので、試してみました。コマンドをIaCの管理下におけて、デプロイや削除がやりやすくなると思われます。また、AWSとまたいだ認証情報の受け渡しも可能です。

やりたいこと

  • Discordのbotを作りたい
  • コマンド登録の部分でスクリプトで走らせる必要があるのだが、登録はよくても削除したいときにクリーンな形で実装したい
  • Discordのbot用のTerraformを見つけたので試してみた

関連

(Web Socket周りなどかなり厳しいことは知っているのだが)最終的にやりたいことは、AWS Lambdaを使ってどの程度Discord botができるのか知りたい。できたらその周りをTerraformで管理したい。

これに関しては、あまり情報が少ないのだが、YouTube見ていたらかなり有益な情報があった。

これはLambdaに、コンテナとして動くFlaskをデプロイして、それをAPIのエンドポイントとしているもの。この設計が良し悪しはさておき、Discordの実装はNode.jsで作られているものが多いため、Pythonベースの情報が少なく、役立つ。

このリポジトリでは、コマンドをyamlとして記述し、Pythonスクリプトを走らせて登録している。ただ、こういうのはIaCの領域なので、Terraformで動かせてしまえばそっちで管理したほうが良さそう。

discord-interactions Provider

https://registry.terraform.io/providers/roleypoly/discord-interactions/latest/docs

サードパーティのTerraform Providerが公開されている。こちらはInteration用で、botのコマンド管理にも使える。別途DiscordのProviderも公開されているが、サーバーやチャンネル、権限周りのリソースが多いため、こちらはサーバー管理用だと思われる。botのコマンド登録用には、interactionsのほうが向いているだろう。

Discordの認証情報

コマンドの登録だけなら、Discordの認証情報は2つ必要。アプリケーションIDとBotのトークン。

Application ID

Bot Token

それぞれDiscordのDeveloper Portalから取得できる

OAuth2で認証させて、サーバーに追加する(上記手順はYouTubeで公開されている)。BotにAdmin権限をあげるのはさすがに強すぎるので、自分はメッセージのReceive、Sendのみに絞った。

AWS SSM Parameter Storeに登録

Terraform管理だと複数のクラウドベンダーをまたいでデプロイすることが可能なので、認証情報をAWSに保管してトークンを安全に管理する。terraform apply時に、AWSから認証情報をとってきて、Discordにリクエストを送る操作もTerraform側でやってくれる。

ここでは、AWSのSystems Manager(SSM)のパラメーターストアに認証情報を登録した。以下のように登録しておく。

Terraformのコード

以下のようにした。これをmain.tfとして保存しておく。

terraform {
  required_providers {
    discord-interactions = {
      source = "roleypoly/discord-interactions"
      version = "0.1.0"
    }
  }

  backend "local" {
    path = ".cache/terraform.tfstate"
  }
}

# AWS Provider
provider "aws" {
  region = "ap-northeast-1"
  profile = "develop"
}

# Credentials from AWS
data "aws_ssm_parameter" "discord_application_id" {
  name = "/discord/shikoan-app/application-id"
}

data "aws_ssm_parameter" "discord_bot_token" {
  name            = "/discord/shikoan-app/token"
  with_decryption = true
}

# Discord Interaction Provider
provider "discord-interactions" {
  application_id = data.aws_ssm_parameter.discord_application_id.value
  bot_token      = data.aws_ssm_parameter.discord_bot_token.value
}

# Discord bot commands
resource "discord-interactions_global_command" "hello" {
  name        = "hello"
  description = "Say hello!"
}

resource "discord-interactions_global_command" "echo" {
  name        = "echo"
  description = "Echo message back to sender"

  option {
    name        = "message"
    description = "The message to echo back."
    type        = 3
    required    = true
  }
}

きっちり管理したいのなら、バックエンドをS3におくべきだが、サンドボックスなのでローカルにした。例は、こちらのものをそのまま流用

AWSの認証情報は、ローカルにAWS CLIが動作するものとし、プロファイル名はdevelopと仮定。

デプロイしてみる

main.tfがあるディレクトリに移動し、以下のコマンドを実行。

  • terraform init
  • terraform plan
  • terraform apply

以下のようにTerraformのリソースとしてDiscordのコマンドが認識される(ちょっとおもしろい)

Discordのクライアントから

デプロイ後、Discordのクライアントを見ると以下のようにbotのコマンドが表示されている(反映にクライアントの再起動が必要かもしれない)

ただ、コマンドの中身を登録していないのでいかんせん動かないが現状これで期待された動作。

destroyしてみる

Terraformを含めて、IaCの良いところは、リソースの削除がやりやすいことなので、terraform destroyしてから、チャットウィンドウからコマンドを確認する。

反映にはクライアントの再起動が必要かもしれないが、コマンドが消去されているのが確認できる。

まとめ

discord-interactionsを使うと、DiscordのコマンドがTerraformから管理できて便利!

続き

https://blog.shikoan.com/discord-bot-lambda-1/



Shikoan's ML Blogの中の人が運営しているサークル「じゅ~しぃ~すくりぷと」の本のご案内

技術書コーナー

北海道の駅巡りコーナー


One Comment

Add a Comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です