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?

DiscordのBotをtailscale経由で動かす方法

1
Posted at

今後のアプリケーション作成において,通知担当にはボタン機能を備えるDiscordBotを使用したいと思い,お試しでBotを作成しました.前回の続きです.

DiscordのBotの作成方法はほかのサイトを参照してください.

変更したソースコード

.env
TS_AUTHKEY=tskey-auth-...
TS_STATE_DIR=/var/lib/tailscale
TS_USERSPACE=true

DISCORD_BOT_TOKEN=Botのトークン
docker-compose.yml
services:
  myapp:
    build: . # Dockerfileをビルド
    container_name: myapp # コンテナ名
    network_mode: "service:myvpn" # ネットワークモード:"service:ネットワーク担当コンテナ"のフォーマットで.
    depends_on: # 依存関係:ネットワーク担当コンテナの名前にする
      - myvpn
    volumes: # 今のディレクトリをコンテナの /app に同期
      - .:/app
+   env_file: # 環境変数は.envで管理
+     - .env
    working_dir: /app # 作業場所を /app に固定
    tty: true # デバッグ用に仮想端末の有効化
    stdin_open: true # デバッグ用に標準入力の有効化
    restart: always # 起動に失敗したら再起動するように
test_v2.py
import os
import discord
from discord import app_commands

# --- 設定 ---
TOKEN = os.getenv("DISCORD_BOT_TOKEN")
GUILD_ID = discord.Object(id=<サーバーのID>) # テストサーバーのID

class MyClient(discord.Client):
    def __init__(self):
        intents = discord.Intents.default()
        super().__init__(intents=intents)
        self.tree = app_commands.CommandTree(self)

    async def setup_hook(self):
        # 起動時にコマンドをDiscordに同期
        self.tree.copy_global_to(guild=GUILD_ID)
        await self.tree.sync(guild=GUILD_ID)
        print(f"Logged in as {self.user} (ID: {self.user.id})")

client = MyClient()

# --- ボタンの見た目と挙動 ---
class ApprovalView(discord.ui.View):
    def __init__(self):
        super().__init__(timeout=None) # タイムアウトなし

    @discord.ui.button(label="Approve", style=discord.ButtonStyle.green)
    async def approve(self, interaction: discord.Interaction, button: discord.ui.Button):
        print(f"[OK] {interaction.user} が承認しました。")
        await interaction.response.send_message("承認をターミナルに記録しました。", ephemeral=True)

    @discord.ui.button(label="Reject", style=discord.ButtonStyle.red)
    async def reject(self, interaction: discord.Interaction, button: discord.ui.Button):
        print(f"[NG] {interaction.user} が却下しました。")
        await interaction.response.send_message("却下をターミナルに記録しました。", ephemeral=True)

# --- コマンド登録 ---
@client.tree.command(name="hoge", description="判定ボタンを出します")
async def hoge(interaction: discord.Interaction):
    await interaction.response.send_message("判定してください:", view=ApprovalView())

if __name__ == "__main__":
    client.run(TOKEN)

コンテナを起動した後にmyappコンテナ内でtest_v2.pyを実行することで,Botが参加しているサーバーにおいて/hogeコマンドが使用可能になります.コマンドの動作は,ApproveボタンとRejectボタンを表示して,それぞれのボタンがクリックされたときにどちらのボタンがクリックされたかをサーバー側のTerminalに出力します.

image.png

発生したトラブル

Botのトークンが読み込まれない

アホです.環境ファイルの読み込みを忘れており,myappコンテナ内に.envの環境変数が反映されていないだけでした.

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?