Overview
This guide will walk you through integrating the Discord Social SDK into a new standalone C++ project. By the end, you’ll have an application that can:
Authenticate users with Discord
Set up logging and status monitoring
Start the SDK and establish a connection
Request the number of Discord friends the player has
Set the player’s rich presence for your game
Prerequisites
Make sure you have:
Basic understanding of C++ and your platform’s build system
A C++ compiler and build system that supports C++17 or greater
A network connection that can access Discord’s API endpoints
A Discord application created in the Developer Portal
Step 1: Create your Discord application
Go to the Discord Developer Portal and click New Application .
Give your application a name and click Create .
Copy your Application ID — you’ll need it in the code.
In your application settings, click OAuth2 in the sidebar.
Under Redirects , add http://127.0.0.1/callback.
Click Save Changes .
Step 3: Enable public client (optional)
If your application does not have a backend server, enable Public Client in the OAuth2 settings. This allows the SDK’s Client::GetToken method to exchange authorization codes for access tokens client-side.
Review OAuth2 client type security tradeoffs with your security team before enabling Public Client for production builds. See OAuth2 client types for details.
Step 4: Download the Discord SDK for C++
In your application settings, click Downloads under the Discord Social SDK section in the sidebar.
Select the latest version from the dropdown and download the SDK for C++.
Runtime dependencies
When shipping with the Social SDK, bundle the appropriate runtime dependencies:
Windows: discord_partner_sdk.dll must be in your executable directory.
Linux/macOS: libdiscord_partner_sdk.so / libdiscord_partner_sdk.dylib must be accessible via LD_LIBRARY_PATH or placed next to your binary.
Step 5: Project setup
Set up a new C++ project with CMake:
mkdir MyGame
cd MyGame
mkdir lib
Unzip the Social SDK archive into the lib directory. You should end up with a discord_social_sdk folder under lib.
Create a CMakeLists.txt file in the MyGame directory:
cmake_minimum_required ( VERSION 3.10)
project (DiscordSDKExample)
set (CMAKE_CXX_STANDARD 17)
set (CMAKE_CXX_STANDARD_REQUIRED True )
add_executable (DiscordSDKExample main.cpp)
# Define Social SDK variables
set (DISCORD_SDK_ROOT "${CMAKE_SOURCE_DIR}/lib/discord_social_sdk" )
set (DISCORD_SDK_LIB_DIR "${DISCORD_SDK_ROOT}/lib/release" )
set (DISCORD_SDK_BIN_DIR "${DISCORD_SDK_ROOT}/bin/release" )
set (DISCORD_SDK_INCLUDE_DIR "${DISCORD_SDK_ROOT}/include" )
target_include_directories (DiscordSDKExample PRIVATE ${DISCORD_SDK_INCLUDE_DIR} )
if ( WIN32 )
set (DISCORD_LIB_PATH "${DISCORD_SDK_LIB_DIR}/discord_partner_sdk.lib" )
set (DISCORD_SHARED_LIB "${DISCORD_SDK_BIN_DIR}/discord_partner_sdk.dll" )
elseif ( APPLE )
set (DISCORD_LIB_PATH "${DISCORD_SDK_LIB_DIR}/libdiscord_partner_sdk.dylib" )
set (DISCORD_SHARED_LIB "${DISCORD_SDK_LIB_DIR}/libdiscord_partner_sdk.dylib" )
else ()
set (DISCORD_LIB_PATH "${DISCORD_SDK_LIB_DIR}/libdiscord_partner_sdk.so" )
set (DISCORD_SHARED_LIB "${DISCORD_SDK_LIB_DIR}/libdiscord_partner_sdk.so" )
endif ()
target_link_libraries (DiscordSDKExample PRIVATE ${DISCORD_LIB_PATH} )
if ( UNIX )
set ( CMAKE_BUILD_WITH_INSTALL_RPATH TRUE )
set ( CMAKE_INSTALL_RPATH "$ORIGIN" )
if ( APPLE )
set ( CMAKE_INSTALL_RPATH "@executable_path" )
endif ()
endif ()
add_custom_command ( TARGET DiscordSDKExample POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${DISCORD_SHARED_LIB}"
$<TARGET_FILE_DIR:DiscordSDKExample>
)
Create a main.cpp file with a basic client setup:
#define DISCORDPP_IMPLEMENTATION
#include "discordpp.h"
#include <iostream>
#include <thread>
#include <atomic>
#include <csignal>
// Replace with your Discord Application ID
const uint64_t APPLICATION_ID = 123456789012345678 ;
std ::atomic < bool > running = true ;
void signalHandler ( int signum ) {
running . store ( false );
}
int main () {
std :: signal (SIGINT, signalHandler);
std ::cout << "Initializing Discord SDK... \n " ;
auto client = std :: make_shared < discordpp :: Client >();
while (running) {
std :: this_thread :: sleep_for ( std :: chrono :: milliseconds ( 10 ));
}
return 0 ;
}
Build and run:
mkdir build && cd build
cmake ..
cmake --build .
./DiscordSDKExample
Step 6: Set up SDK event handling
Add callbacks to monitor what’s happening with your Discord connection.
Adding logging support
client -> AddLogCallback ([]( auto message , auto severity ) {
std ::cout << "[" << EnumToString (severity) << "] " << message << std ::endl;
}, discordpp :: LoggingSeverity ::Info);
Monitoring connection status
client -> SetStatusChangedCallback ([ client ]( discordpp :: Client :: Status status ,
discordpp :: Client :: Error error , int32_t errorDetail ) {
std ::cout << "Status changed: " << discordpp :: Client :: StatusToString (status) << std ::endl;
if (status == discordpp :: Client :: Status ::Ready) {
std ::cout << "Client is ready! \n " ;
} else if (error != discordpp :: Client :: Error ::None) {
std ::cerr << "Connection Error: " << discordpp :: Client :: ErrorToString (error)
<< " - Details: " << errorDetail << std ::endl;
}
});
Most Discord features won’t work until the status is Client::Status::Ready. The status callback tells you exactly when you can start using them.
Step 7: Run callbacks
Add RunCallbacks to your main event loop so the SDK can process events:
while (running) {
discordpp :: RunCallbacks ();
std :: this_thread :: sleep_for ( std :: chrono :: milliseconds ( 10 ));
}
Step 8: Account linking with Discord
Implement OAuth2 authentication to connect users with their Discord accounts.
This guide uses Client::GetDefaultPresenceScopes, which requests the openid and sdk.social_layer_presence scopes. These enable core features like account linking, friends list, and rich presence. If your game also needs lobbies, voice chat, or direct messaging, use Client::GetDefaultCommunicationScopes instead. See the OAuth2 scopes guide for details.
// Generate OAuth2 code verifier for PKCE security
auto codeVerifier = client -> CreateAuthorizationCodeVerifier ();
discordpp ::AuthorizationArgs args{};
args . SetClientId (APPLICATION_ID);
args . SetScopes ( discordpp :: Client :: GetDefaultPresenceScopes ());
args . SetCodeChallenge ( codeVerifier . Challenge ());
client -> Authorize (args, [ client , codeVerifier ]( auto result , auto code , auto redirectUri ) {
if ( ! result . Successful ()) {
std ::cerr << "Authorization Error: " << result . Error () << std ::endl;
return ;
}
std ::cout << "Authorization successful! Getting access token... \n " ;
client -> GetToken (APPLICATION_ID, code, codeVerifier . Verifier (), redirectUri,
[ client ]( discordpp :: ClientResult result ,
std :: string accessToken ,
std :: string refreshToken ,
discordpp :: AuthorizationTokenType tokenType ,
int32_t expiresIn ,
std :: string scope ) {
std ::cout << "Access token received! \n " ;
// Next step: update the token and connect
});
});
Never log or store access tokens insecurely. Treat them as sensitive credentials.
Step 9: Connect the SDK to Discord
Once you have the access token, update the SDK and connect to Discord:
client -> UpdateToken ( discordpp :: AuthorizationTokenType ::Bearer, accessToken,
[ client ]( discordpp :: ClientResult result ) {
if ( result . Successful ()) {
std ::cout << "Token updated, connecting to Discord... \n " ;
client -> Connect ();
}
});
Watch for these status messages in order:
Status changed: Connecting
Status changed: Connected
Status changed: Ready
Client is ready!
Step 10: Access Discord relationships
When the client is ready, retrieve the user’s friends list:
// Inside the status == Ready block
std ::cout << "Friends Count: " << client -> GetRelationships (). size () << std ::endl;
Example output:
Step 11: Set rich presence
Display your game’s activity on Discord using Rich Presence:
discordpp ::Activity activity;
activity . SetType ( discordpp :: ActivityTypes ::Playing);
activity . SetState ( "In Competitive Match" );
activity . SetDetails ( "Rank: Diamond II" );
client -> UpdateRichPresence (activity, []( discordpp :: ClientResult result ) {
if ( result . Successful ()) {
std ::cout << "Rich Presence updated successfully! \n " ;
} else {
std ::cerr << "Rich Presence update failed \n " ;
}
});
After running, check your Discord profile — you should see your game activity displayed.
#define DISCORDPP_IMPLEMENTATION
#include "discordpp.h"
#include <iostream>
#include <thread>
#include <atomic>
#include <string>
#include <functional>
#include <csignal>
const uint64_t APPLICATION_ID = 123456789012345678 ;
std ::atomic < bool > running = true ;
void signalHandler ( int signum ) {
running . store ( false );
}
int main () {
std :: signal (SIGINT, signalHandler);
std ::cout << "Initializing Discord SDK... \n " ;
auto client = std :: make_shared < discordpp :: Client >();
client -> AddLogCallback ([]( auto message , auto severity ) {
std ::cout << "[" << EnumToString (severity) << "] " << message << std ::endl;
}, discordpp :: LoggingSeverity ::Info);
client -> SetStatusChangedCallback ([ client ]( discordpp :: Client :: Status status ,
discordpp :: Client :: Error error , int32_t errorDetail ) {
std ::cout << "Status changed: " << discordpp :: Client :: StatusToString (status) << std ::endl;
if (status == discordpp :: Client :: Status ::Ready) {
std ::cout << "Client is ready! \n " ;
std ::cout << "Friends Count: " << client -> GetRelationships (). size () << std ::endl;
discordpp ::Activity activity;
activity . SetType ( discordpp :: ActivityTypes ::Playing);
activity . SetState ( "In Competitive Match" );
activity . SetDetails ( "Rank: Diamond II" );
client -> UpdateRichPresence (activity, []( discordpp :: ClientResult result ) {
if ( result . Successful ()) {
std ::cout << "Rich Presence updated successfully! \n " ;
} else {
std ::cerr << "Rich Presence update failed \n " ;
}
});
} else if (error != discordpp :: Client :: Error ::None) {
std ::cerr << "Connection Error: " << discordpp :: Client :: ErrorToString (error)
<< " - Details: " << errorDetail << std ::endl;
}
});
auto codeVerifier = client -> CreateAuthorizationCodeVerifier ();
discordpp ::AuthorizationArgs args{};
args . SetClientId (APPLICATION_ID);
args . SetScopes ( discordpp :: Client :: GetDefaultPresenceScopes ());
args . SetCodeChallenge ( codeVerifier . Challenge ());
client -> Authorize (args, [ client , codeVerifier ]( auto result , auto code , auto redirectUri ) {
if ( ! result . Successful ()) {
std ::cerr << "Authorization Error: " << result . Error () << std ::endl;
return ;
}
client -> GetToken (APPLICATION_ID, code, codeVerifier . Verifier (), redirectUri,
[ client ]( discordpp :: ClientResult result ,
std :: string accessToken ,
std :: string refreshToken ,
discordpp :: AuthorizationTokenType tokenType ,
int32_t expiresIn ,
std :: string scope ) {
client -> UpdateToken ( discordpp :: AuthorizationTokenType ::Bearer, accessToken,
[ client ]( discordpp :: ClientResult result ) {
if ( result . Successful ()) {
client -> Connect ();
}
});
});
});
while (running) {
discordpp :: RunCallbacks ();
std :: this_thread :: sleep_for ( std :: chrono :: milliseconds ( 10 ));
}
return 0 ;
}
Conclusion
You’ve successfully integrated the Discord Social SDK into a C++ application.
What you’ve built
A Discord application configured with OAuth2
SDK logging and status monitoring
User authentication flow with PKCE
Discord relationships data retrieval
Rich Presence support
Next steps
Creating a unified friends list Build a unified friends list combining Discord and game-specific friendships.
Setting rich presence Customize your game’s rich presence to show advanced information and game invites.
Managing lobbies Bring players together in a shared lobby with text chat and voice communication.
Change log
Date Changes March 17, 2025 Initial release