Concord - C Discord API library

About
Concord is an asynchronous C99 Discord API library with minimal external dependencies, and a low-level translation of the Discord official documentation to C code.
| Contents | Description |
| Build Instructions | How to build libcurl and Concord |
| Environment Setup | Project setup and compilation |
| Configuration | How to configure Concord with config.json |
| Example Bot | Test Concord with a simple copycat bot |
| Build Options | Special flags and build targets |
| Installation | Installing Concord on your system |
| Contributing | How to contribute to Concord |
Getting Started
Configuration
- Config.json Directives - Configure your bot using JSON
- Setup with Environment Variables - Use environment variables
Discord Features
- Embeds - Create rich message embeds
- Slash Commands - Implement Discord application commands
- Event Scheduler - Control Discord event processing
- SQLite3 with Concord - Persist data with SQLite
- Databases with Concord - General database integration
Debugging & Troubleshooting
- Debugging - Debug your Concord applications
Other Guides
Following are other standalone guides created by the community to help you get started with Concord, organized by category:
- Compiling on Windows - Build Concord on Windows systems
- Installing Concord (Termux) - Install on Android using Termux
- Msys2 and Mingw64 - Setup using MSYS2 environment
- Cross Compiling - Compile for different target platforms
- Concord on Old Systems - Support for legacy systems
Examples
*The following are minimalistic examples, refer to examples/ for a better overview.*
Slash Commands (new method)
#include <string.h>
#include <concord/discord.h>
#define GUILD_ID 1234567898765431
void on_ready(
struct discord *client,
const struct discord_ready *event) {
.name = "ping",
.description = "Ping command!"
};
GUILD_ID, ¶ms, NULL);
}
void on_interaction(
struct discord *client,
const struct discord_interaction *event) {
if (event->type != DISCORD_INTERACTION_APPLICATION_COMMAND)
return;
if (strcmp(event->data->name, "ping") == 0) {
struct discord_interaction_response params = {
.type = DISCORD_INTERACTION_CHANNEL_MESSAGE_WITH_SOURCE,
.data = &(struct discord_interaction_callback_data){
.content = "pong"
}
};
event->token, ¶ms, NULL);
}
}
int main(void) {
}
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.
CCORDcode discord_run(struct discord *client)
Start a connection to the Discord Gateway.
struct discord * discord_from_token(const char token[])
Creates a Discord Client handle from a token.
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_ready(struct discord *client, void(*callback)(struct discord *client, const struct discord_ready *event))
Triggers when the client session is ready.
The Discord client handler.
Definition: discord-internal.h:1206
Message Commands (old method)
#include <string.h>
#include <concord/discord.h>
#include <concord/logmod.h>
void on_ready(
struct discord *client,
const struct discord_ready *event) {
logmod_log(INFO, NULL,
"Logged in as %s!", event->user->username);
}
void on_message(
struct discord *client,
const struct discord_message *event) {
if (strcmp(event->content, "ping") == 0) {
}
}
int main(void) {
}
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.
void discord_add_intents(struct discord *client, uint64_t code)
Subscribe to Discord Events.
void discord_set_on_message_create(struct discord *client, void(*callback)(struct discord *client, const struct discord_message *event))
Triggers when a message is created.
#define logmod_log
Alias to logmod_nlog for C89 compatibility.
Definition: logmod.h:487
Supported operating systems (minimum requirements)
- GNU/Linux 4.x
- FreeBSD 12
- NetBSD 8.1
- Windows 7 (Cygwin)
- GNU/Hurd 0.9
- Mac OS X 10.9
Note: big-endian processors running certain OSes like SPARC Solaris, PowerPC AIX, System Z z/OS or Linux, or MIPS IRIX are NOT supported. There are currently a few issues that prevent some of the logic from correctly on big-endian systems. This will be fixed soon.
Build Instructions
The only dependency is curl-8.7.1 or higher with websockets support. Since many system package managers don't provide this specific version with websockets enabled, we recommend compiling from source.
[!IMPORTANT] Libcurl must be compiled with the --enable-websockets flag to work with Concord.
On Windows
- Install Cygwin
- During Cygwin installation, select packages:
gcc, make, git, autoconf, libtool, pkg-config, openssl-devel, zlib-devel
- Follow the Windows tutorial here
- Then compile libcurl from source (instructions below)
Compiling libcurl from source (recommended for all platforms)
# Install build dependencies
# Ubuntu/Debian:
$ sudo apt-get update && sudo apt-get install -y build-essential autoconf libtool pkg-config libssl-dev zlib1g-dev
# Fedora/RHEL/CentOS:
$ sudo dnf install -y gcc make autoconf libtool pkgconfig openssl-devel zlib-devel
# Arch/Manjaro:
$ sudo pacman -S --needed base-devel openssl zlib
# Alpine:
$ apk add build-base autoconf libtool pkgconfig openssl-dev zlib-dev
# FreeBSD:
$ pkg install autoconf libtool pkgconf openssl
# OS X:
$ xcode-select --install
$ brew install autoconf libtool pkg-config openssl@3
# or with MacPorts:
$ port install autoconf libtool pkgconfig openssl
# Download and compile libcurl
$ curl -LO https://curl.se/download/curl-8.7.1.tar.gz
$ tar -xzf curl-8.7.1.tar.gz
$ cd curl-8.7.1
$ ./configure --with-openssl --enable-websockets
$ make
$ sudo make install
# You might need to inform the system's dynamic linker about the new library location with:
$ echo "/usr/local/lib" > /etc/ld.so.conf.d/curl.conf
$ sudo ldconfig
Setting up your environment
Clone Concord into your workspace
$ git clone https://github.com/cogmasters/concord.git && cd concord
Compile Concord
Optional: speed up compilation
You can speed up the compilation process by using -j flag with make:
This will use all available CPU cores to compile Concord. You can also specify a number instead of to limit the number of jobs.
Special notes about Voice Connections
Concord does not support voice connections yet. If you want to use voice connections, you can use CogLink instead. CogLink is a separate project that provides a LavaLink client for Concord. It is not part of the Concord library, but it is designed to work seamlessly with Concord.
Special notes for non-Linux systems
You might run into trouble with the compiler and linker not finding your Libcurl headers. You can do something like this:
$ CFLAGS=-I<some_path> LDFLAGS=-L<some_path> make
For instance, on a FreeBSD system:
$ CFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib make
On OS X using MacPorts:
$ CFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib make
On OS X using a self-compiled libcurl:
$ CFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/include make
On Windows with Cygwin, you might need to pass both arguments to use POSIX threading:
$ CFLAGS="-pthread -lpthread" make
Special note about linking Concord against another library
In some cases, you might want to link Concord into a shared object, or link it as a shared object into another shared object. In that case, you will need to compile Concord with CFLAGS="-fpic" make.
Special notes about compiling Concord with C compilers besides GCC or Clang
Concord will compile with compilers that aren't GCC or Clang, but you may need to do some work. For instance, support exists for Sun Studio C (specifically, Oracle Developer Studio 12.6), but you will need to change options in the Makefiles (look for CFLAGS and WFLAGS) to prevent errors about unknown compiler option flags.
Configuring Concord
discord_config_init() is the initialization method that allows configuring your bot without recompiling.
The following outlines config.json fields:
{
"token": "YOUR-BOT-TOKEN", // replace with your bot token
"log": { // logging directives
"level": "TRACE", // TRACE, DEBUG, INFO, WARN, ERROR, FATAL
"trace": "bot.log", // the log output file (null to disable)
"quiet": false, // true to disable logs in console
"overwrite": true, // true overwrites the file on each run
"color": true, // display color on console
"http": "http.log", // the HTTP log output file (null to disable)
"ws": "ws.log", // the WebSockets log output file (null to disable)
"disable": ["WEBSOCKETS", "HTTP"] // disable logging for specific modules
}
// here you can add your custom fields *
}
See more information about the config.json file in the config.json directives guide.
Test Copycat-Bot
- Get your bot token and add it to
config.json, by assigning it to discord's "token" field. There are well written instructions from discord-irc explaining how to get your bot token and adding it to a server.
- Build example executables:
- Run Copycat-Bot:
$ cd examples && ./copycat
Get Copycat-Bot Response
Type a message in any channel the bot is part of and the bot should send an exact copy of it in return.
Terminate Copycat-Bot
With Ctrl+c or with Ctrl+|
Configure your build
The following outlines special flags and targets to override the default Makefile build with additional functionalities.
Special compilation flags
-DCCORD_SIGINTCATCH
- By default Concord will not shutdown gracefully when a SIGINT is received (i.e.
Ctrl+c), enable this flag if you wish it to be handled for you.
-DCCORD_DEBUG_WEBSOCKETS
- Enable verbose debugging for WebSockets communication.
-DCCORD_DEBUG_HTTP
- Enable verbose debugging for HTTP communication.
Example:
$ CFLAGS="-DCCORD_SIGINTCATCH -DCCORD_DEBUG_HTTP" make
Special targets
make shared
- Produce a dynamically-linked version of Concord. This Makefile is intended for GNU-style compilers, such as
gcc or clang.
make shared_osx
- Produce a dynamically-linked version of Concord, for OS X and Darwin systems.
make debug
- Enable some flags useful while developing, such as
-O0 and -g
Installing Concord
*(note – # means that you should be running as root)*
This will install the headers and library files into $PREFIX. You can override this as such:
# PREFIX=/opt/concord make install
Cross-compiling Concord
To cross-compile Concord, see the manual here.
Included dependencies
The following are stable and well documented dependencies that are packaged with Concord and can be included to your projects:
| File | Description |
| cog-utils | General purpose functions aimed at portability |
| logmod | A modular logging library |
| carray* | Macro-based implementation of type-safe arrays |
| anomap* | Sorted key/value storage for C99 |
| oa_hash | A lightweight open-addressing hashtable |
| json-build | Tiny, zero-allocation JSON serializer |
| jsmn-find | Tiny, zero-allocation JSON tokenizer |
- Concord uses its own modified version that may be not up to date with the original
Note that included headers must be concord/ prefixed:
#include <concord/discord.h>
#include <concord/logmod.h>
Standalone executable
GCC
$ gcc myBot.c -o myBot -pthread -ldiscord -lcurl
Clang
$ clang myBot.c -o myBot -pthread -ldiscord -lcurl
UNIX C compilers
This includes the following compilers:
- IBM XL C/C++ (AIX, z/OS, IBM i)
- Sun/Oracle Studio (Solaris)
- IRIX MIPSpro C++ (IRIX) – NOTE: currently not supported
- HP aCC (HP-UX)
- Compaq C (Tru64 UNIX) – NOTE: also currently not supported Note: if you want to actually compile this on one of the systems listed above, please see the "Compiling on old computers" guide.
$ cc myBot.c -o myBot -ldiscord -lcurl -lpthread
Note: some systems such as Cygwin require you to do this:
$ gcc myBot.c -o myBot -pthread -lpthread -ldiscord -lcurl
(this links against libpthread.a in /usr/lib)
Support
Problems? Check out our Discord Server
Contributing
All kinds of contributions are welcome, all we ask is to abide to our guidelines! If you want to help but is unsure where to get started then our Discord API Roadmap is a good starting point. Check the following guides for more information on how to contribute:
- Contributing - How to contribute to Concord
- Project Outline - Overview of the project structure
- Coding Guidelines - Coding style and best practices
- Discord API Roadmap - Overview of Discord API features and their status
- Concord Internals - Understand how Concord works internally