From a4defbe13e99dc7752dd2bd5c6f60e0a8b47ab7c Mon Sep 17 00:00:00 2001 From: alyssa Date: Wed, 15 Oct 2025 21:15:54 +0000 Subject: [PATCH] chore: move app-commands script to rust --- Cargo.lock | 15 ++++++ Cargo.toml | 2 +- crates/app-commands/Cargo.toml | 14 +++++ crates/app-commands/src/main.rs | 41 +++++++++++++++ scripts/app-commands/.gitignore | 4 -- scripts/app-commands/README.md | 23 -------- scripts/app-commands/commands.py | 10 ---- scripts/app-commands/common/__init__.py | 1 - scripts/app-commands/common/types.py | 7 --- scripts/app-commands/update.py | 70 ------------------------- scripts/dump-db.sh | 3 -- scripts/rclone-db.sh | 15 ------ scripts/run-test-db.sh | 5 -- 13 files changed, 71 insertions(+), 139 deletions(-) create mode 100644 crates/app-commands/Cargo.toml create mode 100644 crates/app-commands/src/main.rs delete mode 100644 scripts/app-commands/.gitignore delete mode 100644 scripts/app-commands/README.md delete mode 100644 scripts/app-commands/commands.py delete mode 100644 scripts/app-commands/common/__init__.py delete mode 100644 scripts/app-commands/common/types.py delete mode 100644 scripts/app-commands/update.py delete mode 100755 scripts/dump-db.sh delete mode 100755 scripts/rclone-db.sh delete mode 100755 scripts/run-test-db.sh diff --git a/Cargo.lock b/Cargo.lock index 5cf54602..79f65d9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,6 +106,20 @@ dependencies = [ "twilight-http", ] +[[package]] +name = "app-commands" +version = "0.1.0" +dependencies = [ + "anyhow", + "futures", + "libpk", + "tokio", + "tracing", + "twilight-http", + "twilight-model", + "twilight-util", +] + [[package]] name = "arc-swap" version = "1.7.1" @@ -4574,6 +4588,7 @@ version = "0.16.0" source = "git+https://github.com/pluralkit/twilight?branch=pluralkit-7f08d95#054a2aa5d29fb46220af1cd5df568b73511cdb26" dependencies = [ "twilight-model", + "twilight-validate", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index f32165b5..3707ce77 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ axum = { git = "https://github.com/pluralkit/axum", branch = "v0.8.4-pluralkit" twilight-gateway = { git = "https://github.com/pluralkit/twilight", branch = "pluralkit-7f08d95" } twilight-cache-inmemory = { git = "https://github.com/pluralkit/twilight", branch = "pluralkit-7f08d95", features = ["permission-calculator"] } -twilight-util = { git = "https://github.com/pluralkit/twilight", branch = "pluralkit-7f08d95", features = ["permission-calculator"] } +twilight-util = { git = "https://github.com/pluralkit/twilight", branch = "pluralkit-7f08d95", features = ["permission-calculator", "builder"] } twilight-model = { git = "https://github.com/pluralkit/twilight", branch = "pluralkit-7f08d95" } twilight-http = { git = "https://github.com/pluralkit/twilight", branch = "pluralkit-7f08d95", default-features = false, features = ["rustls-aws_lc_rs", "rustls-native-roots"] } diff --git a/crates/app-commands/Cargo.toml b/crates/app-commands/Cargo.toml new file mode 100644 index 00000000..11ab75d4 --- /dev/null +++ b/crates/app-commands/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "app-commands" +version = "0.1.0" +edition = "2024" + +[dependencies] +libpk = { path = "../libpk" } +anyhow = { workspace = true } +futures = { workspace = true } +tokio = { workspace = true } +tracing = { workspace = true } +twilight-http = { workspace = true } +twilight-model = { workspace = true } +twilight-util = { workspace = true } diff --git a/crates/app-commands/src/main.rs b/crates/app-commands/src/main.rs new file mode 100644 index 00000000..a03f5b70 --- /dev/null +++ b/crates/app-commands/src/main.rs @@ -0,0 +1,41 @@ +use twilight_model::{ + application::command::{Command, CommandType}, + guild::IntegrationApplication, +}; +use twilight_util::builder::command::CommandBuilder; + +#[libpk::main] +async fn main() -> anyhow::Result<()> { + let discord = twilight_http::Client::builder() + .token( + libpk::config + .discord + .as_ref() + .expect("missing discord config") + .bot_token + .clone(), + ) + .build(); + + let interaction = discord.interaction(twilight_model::id::Id::new( + libpk::config + .discord + .as_ref() + .expect("missing discord config") + .client_id + .clone() + .get(), + )); + + let commands = vec![ + // message commands + // description must be empty string + CommandBuilder::new("\u{2753} Message info", "", CommandType::Message).build(), + CommandBuilder::new("\u{274c} Delete message", "", CommandType::Message).build(), + CommandBuilder::new("\u{1f514} Ping author", "", CommandType::Message).build(), + ]; + + interaction.set_global_commands(&commands).await?; + + Ok(()) +} diff --git a/scripts/app-commands/.gitignore b/scripts/app-commands/.gitignore deleted file mode 100644 index 3e370e3f..00000000 --- a/scripts/app-commands/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/commands.json - -*.pyc -__pycache__/ diff --git a/scripts/app-commands/README.md b/scripts/app-commands/README.md deleted file mode 100644 index 9d8d576a..00000000 --- a/scripts/app-commands/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# PluralKit "application command" helpers - -## Adding new commands - -Edit the `COMMAND_LIST` global in `commands.py`, making sure that any -command names that are specified in that file match up with the -command names used in the bot code (which will generally be in the list -in `PluralKit.Bot/ApplicationCommandMeta/ApplicationCommandList.cs`). - -TODO: add helpers for slash commands to this - -## Dumping application command JSON - -Run `python3 commands.py` to get a JSON dump of the available application -commands - this is in a format that can be sent to Discord as a `PUT` to -`/applications/{clientId}/commands`. - -## Updating Discord's list of application commands - -From the root of the repository (where your `pluralkit.conf` resides), -run `python3 ./scripts/app-commands/update.py`. This will **REPLACE** -any existing application commands that Discord knows about, with the -updated list. \ No newline at end of file diff --git a/scripts/app-commands/commands.py b/scripts/app-commands/commands.py deleted file mode 100644 index 6a908ba7..00000000 --- a/scripts/app-commands/commands.py +++ /dev/null @@ -1,10 +0,0 @@ -from common import * - -COMMAND_LIST = [ - MessageCommand("\U00002753 Message info"), - MessageCommand("\U0000274c Delete message"), - MessageCommand("\U0001f514 Ping author"), -] - -if __name__ == "__main__": - print(__import__('json').dumps(COMMAND_LIST)) \ No newline at end of file diff --git a/scripts/app-commands/common/__init__.py b/scripts/app-commands/common/__init__.py deleted file mode 100644 index 2a53ba18..00000000 --- a/scripts/app-commands/common/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .types import MessageCommand \ No newline at end of file diff --git a/scripts/app-commands/common/types.py b/scripts/app-commands/common/types.py deleted file mode 100644 index 65c35232..00000000 --- a/scripts/app-commands/common/types.py +++ /dev/null @@ -1,7 +0,0 @@ -class MessageCommand(dict): - COMMAND_TYPE = 3 - - def __init__(self, name): - super().__init__() - self["type"] = self.__class__.COMMAND_TYPE - self["name"] = name \ No newline at end of file diff --git a/scripts/app-commands/update.py b/scripts/app-commands/update.py deleted file mode 100644 index 3005db0a..00000000 --- a/scripts/app-commands/update.py +++ /dev/null @@ -1,70 +0,0 @@ -from common import * -from commands import COMMAND_LIST - -import io -import os -import sys -import json - -from pathlib import Path -from urllib import request -from urllib.error import URLError - -DISCORD_API_BASE = "https://discord.com/api/v10" - -def get_config(): - data = {} - - # prefer token from environment if present - envbase = ["PluralKit", "Bot"] - for var in ["Token", "ClientId"]: - for sep in [':', '__']: - envvar = sep.join(envbase + [var]) - if envvar in os.environ: - data[var] = os.environ[envvar] - - if "Token" in data and "ClientId" in data: - return data - - # else fall back to config - cfg_path = Path(os.getcwd()) / "pluralkit.conf" - if cfg_path.exists(): - cfg = {} - with open(str(cfg_path), 'r') as fh: - cfg = json.load(fh) - - if 'PluralKit' in cfg and 'Bot' in cfg['PluralKit']: - return cfg['PluralKit']['Bot'] - - return None - -def main(): - config = get_config() - if config is None: - raise ArgumentError("config was not loaded") - if 'Token' not in config or 'ClientId' not in config: - raise ArgumentError("config is missing 'Token' or 'ClientId'") - - data = json.dumps(COMMAND_LIST) - url = DISCORD_API_BASE + f"/applications/{config['ClientId']}/commands" - req = request.Request(url, method='PUT', data=data.encode('utf-8')) - req.add_header("Content-Type", "application/json") - req.add_header("Authorization", f"Bot {config['Token']}") - req.add_header("User-Agent", "PluralKit (app-commands updater; https://pluralkit.me)") - - try: - with request.urlopen(req) as resp: - if resp.status == 200: - print("Update successful!") - return 0 - - except URLError as resp: - print(f"[!!!] Update not successful: status {resp.status}", file=sys.stderr) - print(f"[!!!] Response body below:\n", file=sys.stderr) - print(resp.read(), file=sys.stderr) - sys.stderr.flush() - - return 1 - -if __name__ == "__main__": - sys.exit(main()) \ No newline at end of file diff --git a/scripts/dump-db.sh b/scripts/dump-db.sh deleted file mode 100755 index d794dab4..00000000 --- a/scripts/dump-db.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -docker-compose -f "$(dirname $0)/../docker-compose.yml" exec -T -u postgres db pg_dump postgres - diff --git a/scripts/rclone-db.sh b/scripts/rclone-db.sh deleted file mode 100755 index 6e4fda7c..00000000 --- a/scripts/rclone-db.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -# Usage: rclone-db.sh : -# eg. rclone-db.sh b2:pluralkit - -FILENAME=pluralkit-$(date -u +"%Y-%m-%dT%H:%M:%S").sql.gz - -echo Dumping database to /tmp/$FILENAME... -$(dirname $0)/dump-db.sh | gzip > /tmp/$FILENAME - -echo Transferring to remote $1... -rclone -P copy /tmp/$FILENAME $1 - -echo Cleaning up... -rm /tmp/$FILENAME \ No newline at end of file diff --git a/scripts/run-test-db.sh b/scripts/run-test-db.sh deleted file mode 100755 index 272d24e5..00000000 --- a/scripts/run-test-db.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -# Runs a local database in the background listening on port 5432, deleting itself once stopped -# Requires Docker. May need sudo if your user isn't in the `docker` group. -docker run --rm --detach --publish 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres:alpine \ No newline at end of file