thermograph/scripts/register_discord_commands.py

50 lines
1.8 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""Register (upsert) Thermograph's Discord slash commands. Run once, and again
whenever the command list below changes.
THERMOGRAPH_DISCORD_APP_ID=... THERMOGRAPH_DISCORD_BOT_TOKEN=... \
python scripts/register_discord_commands.py
This is a one-off admin action, not part of the running app: it PUTs the full
command set to Discord's REST API (a global overwrite). The app itself answers the
commands over the HTTP interactions endpoint (notifications/discord_interactions.py) and
needs no bot process. Global commands can take up to an hour to propagate.
"""
import os
import sys
import httpx
APP_ID = os.environ.get("THERMOGRAPH_DISCORD_APP_ID", "").strip()
BOT_TOKEN = os.environ.get("THERMOGRAPH_DISCORD_BOT_TOKEN", "").strip()
# CHAT_INPUT command (type 1) with one required STRING option (type 3).
COMMANDS = [
{
"name": "grade",
"description": "How unusual is a city's weather today?",
"type": 1,
"options": [
{"name": "city", "description": "City name, e.g. Tokyo", "type": 3, "required": True},
],
},
]
def main() -> int:
if not APP_ID or not BOT_TOKEN:
print("Set THERMOGRAPH_DISCORD_APP_ID and THERMOGRAPH_DISCORD_BOT_TOKEN.", file=sys.stderr)
return 2
url = f"https://discord.com/api/v10/applications/{APP_ID}/commands"
resp = httpx.put(url, headers={"Authorization": f"Bot {BOT_TOKEN}"}, json=COMMANDS, timeout=30.0)
if resp.status_code >= 300:
print(f"Discord rejected the registration ({resp.status_code}): {resp.text}", file=sys.stderr)
return 1
names = ", ".join("/" + c["name"] for c in resp.json())
print(f"Registered {len(COMMANDS)} command(s): {names}")
return 0
if __name__ == "__main__":
raise SystemExit(main())