今後のアプリケーション作成において,通知担当にはボタン機能を備える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に出力します.
発生したトラブル
Botのトークンが読み込まれない
アホです.環境ファイルの読み込みを忘れており,myappコンテナ内に.envの環境変数が反映されていないだけでした.
