Overview
Game Invites allow users to invite others to join their game session or party. This feature is available on the
Discord client and the Social SDK.
Game Invites are not a standalone feature - they are powered entirely by Rich Presence. When you configure Rich
Presence with party information, a join secret, and/or supported platforms, Discord automatically enables invite
functionality. This guide shows you how to configure Rich Presence to unlock game invites.
Prerequisites
Before you begin, make sure you have:
Configuring Rich Presence to Enable Game Invites
Game invites, or activity invites, are powered by rich presence.
We covered the basics of Setting Rich Presence in a previous guide but let’s go over the key points again.
Let’s talk about the naming of some Discord primitives first. Rich Presence, aka “Activity”, can be thought of as the “current activity of a user” and is represented by the Activity class in the SDK and in our gateway events. This is not to be confused with Discord Activities, which are embedded games that can also set and display rich presence.
Setting Up Rich Presence
Below is an example of setting up rich presence in your game to be used with game invites.
// Create discordpp::Activity - This Rich Presence Activity is your invite configuration
discordpp::Activity activity;
activity.SetType(discordpp::ActivityTypes::Playing);
// Set the game state and details
activity.SetState("In Competitive Match");
activity.SetDetails("Valhalla");
// Update Rich Presence presence
client.UpdateRichPresence(activity, [](discordpp::ClientResult result) {
if(result.Successful()) {
std::cout << "🎮 Rich Presence updated successfully!\n";
// Note: Invites are NOT yet enabled - we need party info and join secret
} else {
std::cerr << "❌ Rich Presence update failed";
}
});
If we run our game, the Discord client will show we are “In Competitive Match” on “Valhalla”.
You must set up your rich presence Activity with party information and a join secret to send game invites. Let’s do that next.
Adding an Activity Party
// rest of the code
// Create discordpp::ActivityParty
discordpp::ActivityParty party;
party.SetId("party1234");
// current party size
party.SetCurrentSize(1);
// max party size
party.SetMaxSize(5);
// Set the party information in the Activity, to inform the invite about the party size and how many players can join
activity.SetParty(party);
// Update Rich Presence
// Still not enough for invites - we need the join secret!
If we run our game, the Discord client will show that we are “In Competitive Match” on “Valhalla” with more information about the party.
We’re almost there! Let’s add the join secret next so we can send and receive game invites.
The last step is to add a join secret to your rich presence activity.
The Join Secret is a generic secret that you can use to join a Discord lobby, a game session, or something else. The game invite system is a way for players to share this secret value with other players - how you use it is up to you.
You will also need to set the supported platforms for joining the game so that the Discord client can display the correct invite button for the user’s platform.
// Create discordpp::Activity
// Create ActivitySecrets
discordpp::ActivitySecrets secrets;
secrets.SetJoin("joinsecret1234"); // Rich Presence secret will be in the invite payload
activity.SetSecrets(secrets);
// Set supported platforms that can join the game
// See discordpp::ActivityGamePlatforms for available platforms
activity.SetSupportedPlatforms(discordpp::ActivityGamePlatforms::Desktop);
// Update Rich Presence
// ✅ NOW invites are enabled through Rich Presence!
Putting It All Together
// Create discordpp::Activity - This Rich Presence Activity is your invite configuration
discordpp::Activity activity;
activity.SetType(discordpp::ActivityTypes::Playing);
// Set the game state and details
activity.SetState("In Competitive Match");
activity.SetDetails("Valhalla");
// Set the party information
discordpp::ActivityParty party;
party.SetId("party1234");
party.SetCurrentSize(1); // current party size
party.SetMaxSize(5); // max party size
// Set the party information in the Activity, to inform the invite about the party size and how many players can join
activity.SetParty(party);
// Create ActivitySecrets
discordpp::ActivitySecrets secrets;
secrets.SetJoin("joinsecret1234"); // Rich Presence secret will be in the invite payload
activity.SetSecrets(secrets);
// Set supported platforms that can join the game
// See discordpp::ActivityGamePlatforms for available platforms
activity.SetSupportedPlatforms(discordpp::ActivityGamePlatforms::Desktop);
// Update Rich Presence presence
client.UpdateRichPresence(activity, [](discordpp::ClientResult result) {
if(result.Successful()) {
std::cout << "🎮 Rich Presence updated successfully!\n";
// ✅ Rich Presence updated = Game invites now available!
} else {
std::cerr << "❌ Rich Presence update failed";
// ❌ No Rich Presence = No invites possible
}
});
Now your game supports rich presence with game invites! The Discord client will show an invite button to your friends when they see your rich presence.
Registering a Launch Command
Before we send a game invite, let’s make sure that the Discord client knows about your game and how to launch it.
When a user accepts a game invite for your game within Discord, the Discord client needs to know how to launch the game for that user. We have two ways to do this:
- Register a launch command for your game
- Register a Steam Game ID
For desktop games, you should run one of these commands when the SDK starts up so that if the user tries to join from Discord, the game can be launched for them.
Registering a Launch Command
Client::RegisterLaunchCommand allows you to register a command that Discord will run to launch your game.
client->RegisterLaunchCommand(YOUR_APP_ID, "yourgame://");
Registering a Steam Game
For Steam games, Client::RegisterLaunchCommand allows you to register what the Steam game ID. You should run this when the SDK starts up so that if the user tries to join from Discord the game will be able to be launched for them.
client->RegisterLaunchSteamApplication(YOUR_APP_ID, STEAM_GAME_ID);
Sending Game Invites
Game invites can be sent in two ways:
- Users can send game invites directly through the Discord client.
- You can programmatically send game invites on a user’s behalf through the SDK.
Sending Game Invites in the Discord Client
Users can send game invites directly through the Discord client. This feature is described in detail in the Game Invites help center article.
Sending Game Invites in the SDK
If a player has the required party, join secret, and supported platforms set in their rich presence, your game can send game invites programmatically through the SDK using Client::SendActivityInvite.
uint64_t targetUserId = 1111785262289277050;
std::string inviteMessage = "Join my game!";
client->SendActivityInvite(targetUserId, inviteMessage, [](discordpp::ClientResult result) {
if(result.Successful()) {
std::cout << "Activity Invite sent to user" << std::endl;
} else {
std::cerr << "Failed - check if Rich Presence has party, secret, and platforms set" << std::endl;
}
});
Receiving Game Invites
Game invites can also be received in two ways:
- Users can receive game invites directly through the Discord client.
- Your game can receive game invites for a user programmatically through the SDK.
Receiving Game Invites in the Discord Client
Users can receive game invites directly in their DMs. This feature is described in detail in the Game Invites help center article.
Receiving Game Invites in the SDK
Use Client::SetActivityInviteCreatedCallback to detect new invites and Client::AcceptActivityInvite to accept them. The callback you specify for Client::AcceptActivityInvite will be invoked with the join secret you set in Rich Presence.
client->SetActivityInviteCreatedCallback([&client](discordpp::ActivityInvite invite) {
std::cout << "Activity Invite received from user: " << invite.SenderId() << std::endl;
if(auto message = client->GetMessageHandle(invite.MessageId())){
std::cout << "Invite Message: " << message->Content() << std::endl;
}
client->AcceptActivityInvite(invite, [](discordpp::ClientResult result, std::string joinSecret) {
if(result.Successful()) {
std::cout << "Activity Invite accepted successfully!\n";
// joinSecret comes from the sender's Rich Presence configuration
// Use the joinSecret to connect the two players in your game
} else {
std::cerr << "❌ Activity Invite accept failed";
}
});
});
Accepting Game Invites
Use Client::SetActivityJoinCallback to monitor for a user accepting a game invite, either in-game or in Discord. Use the join secret to connect the players in your game.
// This fires when a user clicks "Join" on someone's Rich Presence
client->SetActivityJoinCallback([&client](std::string joinSecret) {
// joinSecret is pulled from the host's Rich Presence ActivitySecrets
// Use the joinSecret to connect the players in your game
});
Using Game Invites with Lobbies
Game invites can be used in conjunction with Lobbies to create a seamless experience for players to join a game session or party.
When a player accepts a game invite, you can use the join secret to connect the two players in your game.
An example flow might look like this:
- When a user starts playing the game, they create a lobby with a random secret string, using
Client::CreateOrJoinLobby
- That user publishes their Rich Presence with the join secret set to the lobby secret, along with party size information
- Another user can then see that Rich Presence on Discord and request to join
- Once accepted, the new user receives the join secret, and their client can call CreateOrJoinLobby(joinSecret) to join the lobby
- Finally, the original user can notice that the lobby membership has changed, so they publish a new Rich Presence update containing the updated party size information
These examples use client-side lobby management but can also be adapted for lobbies created on the server side.
Game Invite with Lobby Example
Here’s a code example of how you might implement this flow:
// User A
// 1. Create a lobby with secret
std::string lobbySecret = "foo"
uint64_t USER_B_ID = 01234567890;
client->CreateOrJoinLobby(lobbySecret, [&client](discordpp::ClientResult result, uint64_t lobbyId) {
// 2. Update Rich Presence with a party and join secret to enable invites
discordpp::Activity activity{};
activity.SetType(discordpp::ActivityTypes::Playing);
activity.SetState("In Lobby");
// Rich Presence party configuration for how many players can join
discordpp::ActivityParty party{};
party.SetId("party1234");
party.SetCurrentSize(1);
party.SetMaxSize(4);
activity.SetParty(party);
// Rich Presence secret is what is shared via invites
discordpp::ActivitySecrets secrets{};
secrets.SetJoin(lobbySecret); // This connects Rich Presence to your lobby
activity.SetSecrets(secrets);
// Don't forget to set this Rich Presence update, otherwise SendActivityInvite won't work!
client->UpdateRichPresence(std::move(activity), [&client](discordpp::ClientResult result) {
// 3. NOW we can send invites because Rich Presence is configured
client->SendActivityInvite(USER_B_ID, "come play with me", [](discordpp::ClientResult result) {
if(result.Successful()) {
std::cout << "💌 Invite sent successfully!\n";
} else {
std::cerr << "❌ Invite failed - check Rich Presence configuration\n";
}
});
});
});
// User B
// 4. Monitor for new invites
client->SetActivityInviteCreatedCallback([&client](discordpp::ActivityInvite invite) {
std::cout << "💌 New invite received: " << invite.SenderId() << "\n";
// 5. When an invite is received, ask the user if they want to accept it.
// If they choose to do so then go ahead and invoke AcceptActivityInvite
client->AcceptActivityInvite(invite, [&client](discordpp::ClientResult result, std::string joinSecret) {
if (result.Successful()) {
std::cout << "🎮 Invite accepted! Joining lobby...\n";
// joinSecret came from User A's Rich Presence configuration
// 6. Join the lobby using the joinSecret
client->CreateOrJoinLobby(joinSecret, [=](discordpp::ClientResult result, uint64_t lobbyId) {
// Successfully joined lobby!
if (result.Successful()) {
std::cout << "🎮 Lobby joined successfully! " << lobbyId << std::endl;
} else {
std::cerr << "❌ Lobby join failed\n";
}
});
}
});
});
Lobby Join Request Example
Users can also request to join each other’s parties. This code example shows how that flow might look:
// User A
// 1. Create a lobby with secret
std::string lobbySecret = "foo";
uint64_t USER_A_ID = 286438705638408203;
client->CreateOrJoinLobby(lobbySecret, [&client](discordpp::ClientResult result, uint64_t lobbyId) {
// 2. Update Rich Presence with a party and join secret to enable invites
discordpp::Activity activity{};
activity.SetType(discordpp::ActivityTypes::Playing);
activity.SetState("In Lobby");
// Rich Presence party configuration for how many players can join
discordpp::ActivityParty party{};
party.SetId("party1234");
party.SetCurrentSize(1);
party.SetMaxSize(4);
activity.SetParty(party);
// Rich Presence secret is what is shared via invites
discordpp::ActivitySecrets secrets{};
secrets.SetJoin(lobbySecret);
activity.SetSecrets(secrets);
// This Rich Presence update is what enables the "Ask to Join" button in Discord
client->UpdateRichPresence(std::move(activity), [&client](discordpp::ClientResult result) {});
});
// User B
// 3. Request to join User A's party
client->SendActivityJoinRequest(USER_A_ID, [](discordpp::ClientResult result) {});
// User A
// 4. Monitor for new invites:
client->SetActivityInviteCreatedCallback([&client](discordpp::ActivityInvite invite) {
// 5. The game can now show that User A has received a request to join their party
// If User A is ok with that, they can reply back:
// Note: invite.type will be ActivityActionTypes::JoinRequest in this example
client->SendActivityJoinRequestReply(invite, [](discordpp::ClientResult result) {});
});
// User B
// 6. Same as before, user B can monitor for invites
client->SetActivityInviteCreatedCallback([&client](discordpp::ActivityInvite invite) {
std::cout << "💌 New invite received: " << invite.SenderId() << "\n";
// 7. When an invite is received, ask the user if they want to accept it.
// If they choose to do so then go ahead and invoke AcceptActivityInvite
client->AcceptActivityInvite(invite, [&client](discordpp::ClientResult result, std::string joinSecret) {
if (result.Successful()) {
std::cout << "🎮 Invite accepted! Joining lobby...\n";
// joinSecret came from User A's Rich Presence
// 5. Join the lobby using the joinSecret
client->CreateOrJoinLobby(joinSecret, [=](discordpp::ClientResult result, uint64_t lobbyId) {
// Successfully joined lobby!
if (result.Successful()) {
std::cout << "🎮 Lobby joined successfully! " << lobbyId << std::endl;
} else {
std::cerr << "❌ Lobby join failed\n";
}
});
}
});
});
Supporting Mobile Game Invites
When a player receives a game invite on mobile, Discord must know how to launch your game. Game launching is handled through deep linking, which allows Discord to pass the join information to your game.
Setting Up Mobile Deep Links
- Configure your deep link URL in the Discord Developer Portal:
- Go to your application’s
General tab
- Enter your game’s URL scheme (e.g.,
yourgame://)
- Discord will append
/_discord/join?secret=SECRETHERE to your URL
- Tell Discord which platforms can accept invites:
activity.SetSupportedPlatforms(
ActivityGamePlatforms.Desktop | // Enable PC/Mac invites
ActivityGamePlatforms.IOS | // Enable iOS invites
ActivityGamePlatforms.Android // Enable Android invites
);
How Mobile Deep Links Work
- The user receives and accepts an invite in Discord
- Discord launches your game using your URL scheme:
yourgame://_discord/join?secret=the_join_secret_you_set
- Your game receives the URL and extracts the join secret
- Use the secret to connect the player to the session
Next Steps
Need help? Join the Discord Developers Server and share questions in the #social-sdk-dev-help channel for support from the community.
If you encounter a bug while working with the Social SDK, please report it here: https://dis.gd/social-sdk-bug-report
Change Log
| Date | Changes |
|---|
| March 17, 2025 | initial release |