aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorturret <turret@duck.com>2025-09-29 00:12:45 -0500
committerturret <turret@duck.com>2025-09-29 00:12:45 -0500
commit4e360a4ed7cd77709588b659c704b43d6d474031 (patch)
tree934bbdaed91aa282c015b7ad891b184bdcfe3e2c
parent535ff19dd942d9d53228200eea9096e7e59f76f8 (diff)
downloaddiscord-bot-skeleton-4e360a4ed7cd77709588b659c704b43d6d474031.tar.gz
discord-bot-skeleton-4e360a4ed7cd77709588b659c704b43d6d474031.tar.bz2
discord-bot-skeleton-4e360a4ed7cd77709588b659c704b43d6d474031.zip
command: add command decl sys
additionally, edit ping to use new abstractions and command declaration facilities. TODO: move interaction create event to somewhere else. this spot isnt too good for it.
-rw-r--r--example/ping.c77
-rw-r--r--include/dbs/commands.h60
-rw-r--r--util/command.c17
3 files changed, 110 insertions, 44 deletions
diff --git a/example/ping.c b/example/ping.c
index 79cb915..1d63e8d 100644
--- a/example/ping.c
+++ b/example/ping.c
@@ -4,8 +4,11 @@
#include <curl/curl.h>
#include <cJSON.h>
+#include <stb_ds.h>
+#include <dbs/abstract.h>
#include <dbs/api.h>
+#include <dbs/commands.h>
#include <dbs/event.h>
#include <dbs/init.h>
#include <dbs/log.h>
@@ -14,57 +17,45 @@
extern char *app_id;
extern double api_latency;
-static void ping(cJSON *i)
+Command ping_command = {
+ .type = COMMAND_CHAT_INPUT,
+ .name = "ping",
+ .description = "ping pong all the way to america :flag_us:",
+ .options = NULL
+};
+void ping(cJSON *i)
{
- struct curl_slist *headers = curl_slist_append(NULL, "Content-type: application/json");
- headers = curl_slist_append(headers, "User-Agent: DiscordBot (DBS, dev)");
-
- char *i_id = js_getStr(i, "id");
- char *i_token = js_getStr(i, "token");
- char *url = malloc(strlen("/interactions/") + strlen(i_id) + strlen("/") + strlen(i_token) + strlen("/messages/@original") + 2);
-
- sprintf(url, "/interactions/%s/%s/callback", i_id, i_token);
- char *defer_message = "{\"type\":5}";
-
+ static int do_hidden = 1;
struct timeval sent;
struct timeval done;
-
- long code;
gettimeofday(&sent, NULL);
- close(api_post(url, headers, defer_message, &code));
+ if(!interaction_defer_reply(i, do_hidden))
+ print("ping: DEFER failed");
+ do_hidden = !do_hidden;
gettimeofday(&done, NULL);
char *response = malloc(128);
snprintf(response, 128, "{\"embeds\":[{\"title\": \"PONG!\", \"description\": \"Measured API Latency: %.4fms\\nWS Latency: %.4fms\"}]}",
(done.tv_sec - sent.tv_sec) * 1000.0f + (done.tv_usec - sent.tv_usec) / 1000.0f,
api_latency);
- sprintf(url, "/webhooks/%s/%s/messages/@original", app_id, i_token);
- headers = curl_slist_append(NULL, "Content-type: application/json");
- headers = curl_slist_append(headers, "User-Agent: DiscordBot (DBS, dev)");
-
- close(api_patch(url, headers, response, &code));
-
+ if(!interaction_edit_reply(i, response, 1))
+ print("ping: EDIT failed");
free(response);
- free(url);
}
-
+declare_command(ping);
+
+Command hi_command = {
+ .type = COMMAND_CHAT_INPUT,
+ .name = "hi",
+ .description = "hallo!!!!",
+ .options = NULL
+};
static void hi(cJSON *i)
{
-
- char *i_id = js_getStr(i, "id");
- char *i_token = js_getStr(i, "token");
- char *url = malloc(strlen("/interactions/") + strlen(i_id) + strlen("/") + strlen(i_token) + strlen("/callback") + 2);
- sprintf(url, "/interactions/%s/%s/callback", i_id, i_token);
-
- char *message = "{\"type\": 4,\"data\":{\"type\":4,\"flags\": 0,\"content\":\"hello world!\"}}";
- long code;
-
- struct curl_slist *headers = curl_slist_append(NULL, "Content-type: application/json");
- headers = curl_slist_append(headers, "User-Agent: DiscordBot (DBS, dev)");
- close(api_post(url, headers, message, &code));
-
- free(url);
+ if(!interaction_reply(i, "hello world!", 0))
+ print("hi: REPLY failed");
}
+declare_command(hi);
int interaction_create(cJSON *ev_data)
{
@@ -75,16 +66,14 @@ int interaction_create(cJSON *ev_data)
case 1: ; /* PING */
break;
case 2: ; /* APPLICATION_COMMAND */
- int cmd_type = js_getInt(i, "type");
- if(cmd_type == -1) cmd_type = 1;
char *cmd_name = js_getStr(i, "name");
- if(strcmp(cmd_name, "ping") == 0) {
- ping(ev_data);
- return 0;
- } else if(strcmp(cmd_name, "hi") == 0) {
- hi(ev_data);
- return 0;
+ for(int i = 0; i < arrlen(commands); ++i) {
+ if(strcmp(cmd_name, commands[i].name) == 0) {
+ commands[i].callback(ev_data);
+ return 0;
+ }
}
+ print(LOG_WARN "commands: unknown command %s", cmd_name);
break;
case 3: ; /* MESSAGE_COMPONENT */
break;
diff --git a/include/dbs/commands.h b/include/dbs/commands.h
new file mode 100644
index 0000000..181a2c0
--- /dev/null
+++ b/include/dbs/commands.h
@@ -0,0 +1,60 @@
+#ifndef DBS_COMMANDS_H
+#define DBS_COMMANDS_H
+
+enum CommandType {
+ COMMAND_CHAT_INPUT = 1,
+ COMMAND_USER = 2,
+ COMMAND_MESSAGE = 3,
+ COMMAND_PRIMARY_ENTRY_POINT = 4
+};
+
+enum CommandOptionType {
+ OPTION_SUB_COMMAND = 1,
+ OPTION_SUB_COMMAND_GROUP = 2,
+ OPTION_STRING = 3,
+ OPTION_INTEGER = 4,
+ OPTION_BOOLEAN = 5,
+ OPTION_USER = 6,
+ OPTION_CHANNEL = 7,
+ OPTION_ROLE = 8,
+ OPTION_MENTIONABLE = 9,
+ OPTION_NUMBER = 10,
+ OPTION_ATTACHMENT = 11
+};
+
+struct command_option {
+ enum CommandOptionType type;
+ char *name;
+ char *description;
+ int required;
+ char **choices;
+ int **choices_int;
+ struct command_option **options;
+ int channel_types;
+ int min_value;
+ int max_value;
+ int min_length;
+ int max_length;
+ int autocomplete;
+};
+typedef struct command_option CommandOption;
+
+struct command {
+ enum CommandType type;
+ char *name;
+ char *description;
+ CommandOption *options;
+ void (*callback)(cJSON*);
+};
+typedef struct command Command;
+
+extern Command *commands;
+
+#define declare_command(command) \
+ void command_register_##command(void) { \
+ command ## _command.callback = &command; \
+ arrput(commands, command ## _command); \
+ } \
+ l3_initcall(command_register_##command)
+
+#endif
diff --git a/util/command.c b/util/command.c
new file mode 100644
index 0000000..57a0bc1
--- /dev/null
+++ b/util/command.c
@@ -0,0 +1,17 @@
+#include <stddef.h>
+
+#include <cJSON.h>
+#include <stb_ds.h>
+
+#include <dbs/commands.h>
+#include <dbs/init.h>
+#include <dbs/log.h>
+
+Command *commands = NULL;
+
+void register_commands() {
+ for(int i = 0; i < arrlen(commands); ++i) {
+ print("command %s: %s (@%x)", commands[i].name, commands[i].description, (long long)commands[i].callback);
+ }
+}
+l4_initcall(register_commands);