Concord - C Discord API library
A Discord API wrapper library written in C
slash-commands.c

Demonstrates registering and reacting to slash commands

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <inttypes.h> /* SCNu64, PRIu64 */
#include "discord.h"
#include "log.h"
u64snowflake g_app_id;
void
print_usage(void)
{
printf("\n\nThis bot demonstrates how easy it is to create, and react to "
"application commands\n"
"1. Type '!slash_create' to create the application command\n"
"2. Type '/' in the same channel and select the newly created "
"command\n"
"\nTYPE ANY KEY TO START BOT\n");
}
void
on_ready(struct discord *client, const struct discord_ready *event)
{
log_info("Slash-Commands-Bot succesfully connected to Discord as %s#%s!",
event->user->username, event->user->discriminator);
g_app_id = event->application->id;
}
void
on_slash_command_create(struct discord *client,
const struct discord_message *event)
{
if (event->author->bot) return;
struct discord_application_command_option_choice gender_choices[] = {
{
.name = "male",
.value = "\"male\"",
},
{
.name = "female",
.value = "\"female\"",
},
{
.name = "other",
.value = "\"other\"",
},
};
{
.name = "nick",
.description = "Your nick",
.required = true,
},
{
.name = "pets",
.description = "How many pets you got",
},
{
.name = "gender",
.description = "Your gender",
.choices =
.size = sizeof(gender_choices) / sizeof *gender_choices,
.array = gender_choices,
},
},
{
.name = "favorite",
.description = "Favorite channel",
.channel_types =
&(struct integers){
.size = 1,
.array =
(int[]){
},
},
},
};
.name = "fill-form",
.description = "A slash command example for form filling",
.default_permission = true,
.options =
.size = sizeof(options) / sizeof *options,
.array = options,
},
};
/* Create slash command */
&params, NULL);
}
void
on_interaction_create(struct discord *client,
const struct discord_interaction *event)
{
/* We're only interested on slash commands */
/* Return in case user input is missing for some reason */
if (!event->data || !event->data->options) return;
char *nick = "blank";
int pets = 0;
char *gender = "blank";
u64snowflake channel_id = 0;
for (int i = 0; i < event->data->options->size; ++i) {
char *name = event->data->options->array[i].name;
char *value = event->data->options->array[i].value;
if (0 == strcmp(name, "nick"))
nick = value;
else if (0 == strcmp(name, "pets"))
pets = strtol(value, NULL, 10);
else if (0 == strcmp(name, "gender"))
gender = value;
else if (0 == strcmp(name, "favorite"))
sscanf(value, "%" SCNu64, &channel_id);
}
char buf[DISCORD_MAX_MESSAGE_LEN] = "";
snprintf(buf, sizeof(buf),
"Fun-facts about <@%" PRIu64 ">!\n"
"Nick: %s\n"
"Pets: %d\n"
"Gender: %s\n"
"Favorite channel: <#%" PRIu64 ">\n",
event->member->user->id, nick, pets, gender, channel_id);
struct discord_interaction_response params = {
.data = &(struct discord_interaction_callback_data){ .content = buf }
};
&params, NULL);
}
int
main(int argc, char *argv[])
{
const char *config_file;
if (argc > 1)
config_file = argv[1];
else
config_file = "../config.json";
struct discord *client = discord_config_init(config_file);
assert(NULL != client && "Could not initialize client");
discord_set_on_command(client, "!slash_create", &on_slash_command_create);
discord_set_on_ready(client, &on_ready);
discord_set_on_interaction_create(client, &on_interaction_create);
print_usage();
fgetc(stdin); // wait for input
discord_run(client);
discord_cleanup(client);
}
@ DISCORD_APPLICATION_OPTION_CHANNEL
Definition: application_commands.h:42
@ DISCORD_APPLICATION_OPTION_STRING
Definition: application_commands.h:36
@ DISCORD_APPLICATION_OPTION_INTEGER
Definition: application_commands.h:38
CCORDcode ccord_global_init()
Initialize global shared-resources not API-specific.
void ccord_global_cleanup()
Cleanup global shared-resources.
Public functions and datatypes.
@ DISCORD_CHANNEL_GUILD_TEXT
Definition: channel.h:50
uint64_t u64snowflake
Snowflake datatype.
Definition: types.h:28
CCORDcode discord_create_guild_application_command(struct discord *client, u64snowflake application_id, u64snowflake guild_id, struct discord_create_guild_application_command *params, struct discord_ret_application_command *ret)
Create a new guild command.
CCORDcode discord_create_interaction_response(struct discord *client, u64snowflake interaction_id, const char interaction_token[], struct discord_interaction_response *params, struct discord_ret_interaction_response *ret)
Create a response to an Interaction from the gateway.
void discord_cleanup(struct discord *client)
Free a Discord Client handle.
CCORDcode discord_run(struct discord *client)
Start a connection to the Discord Gateway.
struct discord * discord_config_init(const char config_file[])
Create a Discord Client handle by a config.json file.
#define DISCORD_MAX_MESSAGE_LEN
Definition: discord.h:64
void discord_set_on_interaction_create(struct discord *client, void(*callback)(struct discord *client, const struct discord_interaction *event))
Triggers when user has used an interaction, such as an application command.
void discord_set_on_command(struct discord *client, char *command, void(*callback)(struct discord *client, const struct discord_message *event))
Set command/callback pair.
void discord_set_on_ready(struct discord *client, void(*callback)(struct discord *client, const struct discord_ready *event))
Triggers when the client session is ready.
@ DISCORD_INTERACTION_APPLICATION_COMMAND
Definition: interactions.h:24
@ DISCORD_INTERACTION_CHANNEL_MESSAGE_WITH_SOURCE
Definition: interactions.h:33
#define log_info(...)
Definition: log.h:52
Definition: application_commands.h:151
char * name
Definition: application_commands.h:153
Definition: application_commands.h:158
struct discord_application_command_option_choice * array
Definition: application_commands.h:159
Definition: application_commands.h:110
struct discord_application_command_options * options
Definition: application_commands.h:128
Definition: application_commands.h:148
struct discord_application_command_option * array
Definition: application_commands.h:149
Definition: application_commands.h:254
char * name
Definition: application_commands.h:256
struct discord_user * user
Definition: guild.h:293
Definition: interactions.h:133
struct discord_application_command_interaction_data_options * options
Definition: interactions.h:86
Definition: interactions.h:125
enum discord_interaction_callback_types type
Definition: interactions.h:127
Definition: interactions.h:48
u64snowflake id
Definition: interactions.h:50
struct discord_interaction_data * data
Definition: interactions.h:56
enum discord_interaction_types type
Definition: interactions.h:54
struct discord_guild_member * member
Definition: interactions.h:62
char * token
Definition: interactions.h:66
Definition: channel.h:191
u64snowflake guild_id
Definition: channel.h:197
struct discord_user * author
Definition: channel.h:199
Definition: gateway.h:332
struct discord_user * user
Definition: gateway.h:336
bool bot
Definition: user.h:79
u64snowflake id
Definition: user.h:71
char * username
Definition: user.h:73
char * discriminator
Definition: user.h:75
The Discord client handler.
Definition: discord-internal.h:1180
Definition: custom.h:36