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

Demonstrates a couple use cases of the Message Components API

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h> /* PRIu64 */
#include <assert.h>
#include "discord.h"
#include "log.h"
void
print_usage(void)
{
printf(
"\n\nThis bot demonstrates how to load message components"
" with three different methods.\n"
"1 - Dynamic-approach (type !dynamic): Load the components from "
"a JSON string.\n"
"2 - Static-approach (type !static): A clean initialization approach "
"using the combination of designated initialization and compound "
"literals.\n"
"\nTYPE ANY KEY TO START BOT\n");
}
char JSON[] =
"[\n"
" {\n"
" \"type\": 1,\n"
" \"components\": [\n"
" {\n"
" \"type\": 3,\n"
" \"custom_id\": \"class_select_1\",\n"
" \"options\":[\n"
" {\n"
" \"label\": \"Rogue\",\n"
" \"value\": \"rogue\",\n"
" \"description\": \"Sneak n stab\",\n"
" \"emoji\": {\n"
" \"name\": \"rogue\",\n"
" \"id\": \"625891304148303894\"\n"
" }\n"
" },\n"
" {\n"
" \"label\": \"Mage\",\n"
" \"value\": \"mage\",\n"
" \"description\": \"Turn 'em into a sheep\",\n"
" \"emoji\": {\n"
" \"name\": \"mage\",\n"
" \"id\": \"625891304081063986\"\n"
" }\n"
" },\n"
" {\n"
" \"label\": \"Priest\",\n"
" \"value\": \"priest\",\n"
" \"description\": \"You get heals when I'm done "
"doing damage\",\n"
" \"emoji\": {\n"
" \"name\": \"priest\",\n"
" \"id\": \"625891303795982337\"\n"
" }\n"
" }\n"
" ],\n"
" \"placeholder\": \"Choose a class\",\n"
" \"min_values\": 1,\n"
" \"max_values\": 3\n"
" }\n"
" ]\n"
" }\n"
"]\n";
void
on_ready(struct discord *client, const struct discord_ready *event)
{
log_info("Components-Bot succesfully connected to Discord as %s#%s!",
event->user->username, event->user->discriminator);
}
void
on_dynamic(struct discord *client, const struct discord_message *event)
{
if (event->author->bot) return;
struct discord_components components = { 0 };
discord_components_from_json(JSON, sizeof(JSON), &components);
struct discord_create_message params = {
.content = "Mason is looking for new arena partners. What classes do "
"you play?",
.components = &components
};
discord_create_message(client, event->channel_id, &params, NULL);
/* must cleanup 'components' afterwards */
}
void
on_static(struct discord *client, const struct discord_message *event)
{
if (event->author->bot) return;
struct discord_select_option select_options[] = {
{
.label = "Rogue",
.value = "rogue",
.description = "Sneak n stab",
.emoji =
&(struct discord_emoji){
.name = "rogue",
.id = 625891304148303894ULL,
},
},
{
.label = "Mage",
.value = "mage",
.description = "Turn 'em into a sheep",
.emoji =
&(struct discord_emoji){
.name = "mage",
.id = 625891304081063986ULL,
},
},
{
.label = "Priest",
.value = "priest",
.description = "You get heals when I'm "
"done doing damage",
.emoji =
&(struct discord_emoji){
.name = "priest",
.id = 625891303795982337ULL,
},
},
};
struct discord_component select_menu[] = {
{
.custom_id = "class_select_1",
.options =
.size = sizeof(select_options) / sizeof *select_options,
.array = select_options,
},
.placeholder = "Choose a class",
.min_values = 1,
.max_values = 3,
},
};
struct discord_component action_rows[] = {
{
.components =
&(struct discord_components){
.size = sizeof(select_menu) / sizeof *select_menu,
.array = select_menu,
},
},
};
struct discord_create_message params = {
.content = "Mason is looking for new arena partners. What classes do "
"you play?",
.components =
&(struct discord_components){
.size = sizeof(action_rows) / sizeof *action_rows,
.array = action_rows,
},
};
discord_create_message(client, event->channel_id, &params, NULL);
}
void
on_interaction_create(struct discord *client,
const struct discord_interaction *event)
{
log_info("Interaction %" PRIu64 " received", event->id);
if (!event->data || !event->data->values) return;
char values[1024];
strings_to_json(values, sizeof(values), event->data->values);
snprintf(text, sizeof(text),
"So you have chosen:\n"
"```json\n"
"%s\n"
"```",
values);
struct discord_interaction_response params = {
.data =
.content = text,
.flags = DISCORD_MESSAGE_EPHEMERAL // 1 << 6
}
};
&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 && "Couldn't initialize client");
discord_set_on_ready(client, &on_ready);
discord_set_prefix(client, "!");
discord_set_on_command(client, "dynamic", &on_dynamic);
discord_set_on_command(client, "static", &on_static);
discord_set_on_interaction_create(client, &on_interaction_create);
print_usage();
fgetc(stdin); // wait for input
discord_run(client);
discord_cleanup(client);
}
CCORDcode ccord_global_init()
Initialize global shared-resources not API-specific.
void ccord_global_cleanup()
Cleanup global shared-resources.
size_t strings_to_json(char buf[], size_t size, const struct strings *self)
Public functions and datatypes.
#define DISCORD_MESSAGE_EPHEMERAL
Definition: channel.h:41
CCORDcode discord_create_message(struct discord *client, u64snowflake channel_id, struct discord_create_message *params, struct discord_ret_message *ret)
Post a message to a guild text or DM channel.
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_prefix(struct discord *client, const char prefix[])
Set a mandatory prefix before commands.
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_CHANNEL_MESSAGE_WITH_SOURCE
Definition: interactions.h:33
#define log_info(...)
Definition: log.h:52
size_t discord_components_from_json(const char buf[], size_t size, struct discord_components *self)
@ DISCORD_COMPONENT_ACTION_ROW
Definition: message_components.h:24
@ DISCORD_COMPONENT_SELECT_MENU
Definition: message_components.h:28
void discord_components_cleanup(struct discord_components *self)
Definition: message_components.h:51
enum discord_component_types type
Definition: message_components.h:54
Definition: message_components.h:101
struct discord_component * array
Definition: message_components.h:102
Definition: channel.h:671
char * content
Definition: channel.h:673
struct discord_components * components
Definition: channel.h:688
Definition: emoji.h:23
Definition: interactions.h:133
struct strings * values
Definition: interactions.h:92
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
char * token
Definition: interactions.h:66
Definition: channel.h:191
struct discord_user * author
Definition: channel.h:199
u64snowflake channel_id
Definition: channel.h:195
Definition: gateway.h:332
struct discord_user * user
Definition: gateway.h:336
Definition: message_components.h:104
char * label
Definition: message_components.h:106
Definition: message_components.h:119
struct discord_select_option * array
Definition: message_components.h:120
bool bot
Definition: user.h:79
char * username
Definition: user.h:73
char * discriminator
Definition: user.h:75
The Discord client handler.
Definition: discord-internal.h:1180