Activities

Looking to integrate Rich Presence into your game? No need to manage multiple SDKs—this one does all that awesome stuff, too!. Delight your players with the ability to post game invites in chat and party up directly from Discord. Surface interesting live game data in their profile and on the Games Tab for their friends, encouraging them to group up and play together.

For more detailed information and documentation around the Rich Presence feature set and integration tips, check out our Rich Presence Documentation.

Data Models

User Struct
nametypedescription
IdInt64the user's id
Usernamestringtheir name
Discriminatorstringthe user's unique discrim
Avatarstringthe hash of the user's avatar
Botboolif the user is a bot user
Activity Struct
nametypedescription
ApplicationIdInt64your application id - this is a read-only field
Namestringname of the application - this is a read-only field
Statestringthe player's current party status
Detailsstringwhat the player is currently doing
TimestampsActivityTimestampshelps create elapsed/remaining timestamps on a player's profile
AssetsActivityAssetsassets to display on the player's profile
PartyActivityPartyinformation about the player's party
SecretsActivitySecretssecret passwords for joining and spectating the player's game
Instanceboolwhether this activity is an instanced context, like a match
ActivityTimestamps Struct
nametypedescription
StartInt64unix timestamp - send this to have an "elapsed" timer
EndInt64unix timestamp - send this to have a "remaining" timer
ActivityAssets Struct
nametypedescription
LargeImagestringkeyname of an asset to display
LargeTextstringhover text for the large image
SmallImagestringkeyname of an asset to display
SmallTextstringhover text for the small image
ActivityParty Struct
nametypedescription
Idstringa unique identifier for this party
SizePartySizeinfo about the size of the party
PartySize Struct
nametypedescription
CurrentSizeInt32the current size of the party
MaxSizeInt32the max possible size of the party
ActivitySecrets Struct
nametypedescription
Matchstringunique hash for the given match context
Joinstringunique hash for chat invites and Ask to Join
Spectatestringunique hash for Spectate button
ActivityType Enum
nameValue
Playing0
Streaming1
Listening2
Watching3
Custom4
Competing5

For more details about the activity types, see Gateway documentation.

ActivityType is strictly for the purpose of handling events that you receive from Discord; though the SDK/our API will not reject a payload with an ActivityType sent, it will be discarded and will not change anything in the client.

ActivityJoinRequestReply Enum
namevalue
No0
Yes1
Ignore2
ActivityActionType Enum
namevalue
Join1
Spectate2

Activity Action Field Requirements

If you want to hook up joining and spectating for your games, there are certain fields in the activity payload that need to be sent. Refer to the following handy table for what needs to be set for certain actions.

Requirements
FieldCustom ArtworkSpectateJoinAsk to Join
State
Details
ActivityTimestamps.Start
ActivityTimestamps.End
ActivityAssets.LargeImagex
ActivityAssets.SmallImagex
ActivityAssets.LargeTextx
ActivityAssets.SmallTextx
ActivityParty.Idxx
ActivityParty.Size.CurrentSizexx
ActivityParty.Size.MaxSizexx
ActivitySecrets.Joinxx
ActivitySecrets.Spectatex

RegisterCommand

Registers a command by which Discord can launch your game. This might be a custom protocol, like my-awesome-game://, or a path to an executable. It also supports any launch parameters that may be needed, like game.exe --full-screen --no-hax.

On macOS, due to the way Discord registers executables, your game needs to be bundled for this command to work. That means it should be a .app.

Returns void.

Parameters
nametypedescription
commandstringthe command to register
Example
cs
activityManager.RegisterCommand("my-awesome-game://run --full-screen");

RegisterSteam

Used if you are distributing this SDK on Steam. Registers your game's Steam app id for the protocol steam://run-game-id/<id>.

Returns void.

Parameters
nametypedescription
steamIdUInt32your game's Steam app id
Example
cs
activityManager.RegisterSteam(1938123);

UpdateActivity

Sets a user's presence in Discord to a new activity. This has a rate limit of 5 updates per 20 seconds.

Returns a Discord.Result via callback.

Parameters
nametypedescription
activityActivitythe new activity for the user
Example
cs
var activity = new Discord.Activity
{
State = "In Play Mode",
Details = "Playing the Trumpet!",
Timestamps =
{
Start = 5,
},
Assets =
{
LargeImage = "foo largeImageKey", // Larger Image Asset Key
LargeText = "foo largeImageText", // Large Image Tooltip
SmallImage = "foo smallImageKey", // Small Image Asset Key
SmallText = "foo smallImageText", // Small Image Tooltip
},
Party =
{
Id = "foo partyID",
Size = {
CurrentSize = 1,
MaxSize = 4,
},
},
Secrets =
{
Match = "foo matchSecret",
Join = "foo joinSecret",
Spectate = "foo spectateSecret",
},
Instance = true,
};
activityManager.UpdateActivity(activity, (result) =>
{
if (result == Discord.Result.Ok)
{
Console.WriteLine("Success!");
}
else
{
Console.WriteLine("Failed");
}
});

ClearActivity

Clear's a user's presence in Discord to make it show nothing.

Results a Discord.Result via callback.

Parameters

None

Example
cs
activityManager.ClearActivity((result) =>
{
if (result == Discord.Result.Ok)
{
Console.WriteLine("Success!");
}
else
{
Console.WriteLine("Failed");
}
});

SendRequestReply

Sends a reply to an Ask to Join request.

Returns a Discord.Result via callback.

Parameters
nametypedescription
userIdInt64the user id of the person who asked to join
replyActivityJoinRequestReplyNo, Yes, or Ignore
Example
cs
activityManager.OnActivityJoinRequest += user =>
{
Console.WriteLine("Join request from: {0}", user.Id);
activityManager.SendRequestReply(user.Id, Discord.ActivityJoinRequestReply.Yes, (res) =>
{
if (res == Discord.Result.Ok)
{
Console.WriteLine("Responded successfully");
}
});
}

SendInvite

Sends a game invite to a given user. If you do not have a valid activity with all the required fields, this call will error. See Activity Action Field Requirements for the fields required to have join and spectate invites function properly.

Returns a Discord.Result via callback.

Parameters
nametypedescription
userIdInt64the id of the user to invite
typeActivityActionTypemarks the invite as an invitation to join or spectate
contentstringa message to send along with the invite
Example
cs
var userId = 53908232506183680;
activityManager.SendInvite(userId, Discord.ActivityActionType.Join, "Come play!", (result) =>
{
if (result == Discord.Result.Ok)
{
Console.WriteLine("Success!");
}
else
{
Console.WriteLine("Failed");
}
});

AcceptInvite

Accepts a game invitation from a given userId.

Returns a Discord.Result via callback.

Parameters
nametypedescription
userIdInt64the id of the user who invited you
Example
cs
activityManager.AcceptInvite(290926444748734466, (result) =>
{
if (result == Discord.Result.Ok)
{
Console.WriteLine("Success!");
}
else
{
Console.WriteLine("Failed");
}
});

OnActivityJoin

Fires when a user accepts a game chat invite or receives confirmation from Asking to Join.

Parameters
nametypedescription
joinSecretstringthe secret to join the user's game
Example
cs
// Received when someone accepts a request to join or invite.
// Use secrets to receive back the information needed to add the user to the group/party/match
activityManager.OnActivityJoin += secret => {
Console.WriteLine("OnJoin {0}", secret);
lobbyManager.ConnectLobbyWithActivitySecret(secret, (Discord.Result result, ref Discord.Lobby lobby) =>
{
Console.WriteLine("Connected to lobby: {0}", lobby.Id);
// Connect to voice chat, used in this case to actually know in overlay if your successful in connecting.
lobbyManager.ConnectVoice(lobby.Id, (Discord.Result voiceResult) => {
if (voiceResult == Discord.Result.Ok)
{
Console.WriteLine("New User Connected to Voice! Say Hello! Result: {0}", voiceResult);
}
else
{
Console.WriteLine("Failed with Result: {0}", voiceResult);
};
});
//Connect to given lobby with lobby Id
lobbyManager.ConnectNetwork(lobby.Id);
lobbyManager.OpenNetworkChannel(lobby.Id, 0, true);
foreach (var user in lobbyManager.GetMemberUsers(lobby.Id))
{
//Send a hello message to everyone in the lobby
lobbyManager.SendNetworkMessage(lobby.Id, user.Id, 0,
Encoding.UTF8.GetBytes(String.Format("Hello, {0}!", user.Username)));
}
//Sends this off to a Activity callback named here as 'UpdateActivity' passing in the discord instance details and lobby details
UpdateActivity(discord, lobby);
});
};
void UpdateActivity(Discord.Discord discord, Discord.Lobby lobby)
{
//Creates a Static String for Spectate Secret.
string discordSpectateSecret = "wdn3kvj320r8vk3";
spectateActivitySecret = discordSpectateSecret;
var activity = new Discord.Activity
{
State = "Playing Co-Op",
Details = "In a Multiplayer Match!",
Timestamps =
{
Start = startTimeStamp,
},
Assets =
{
LargeImage = "matchimage1",
LargeText = "Inside the Arena!",
},
Party = {
Id = lobby.Id.ToString(),
Size = {
CurrentSize = lobbyManager.MemberCount(lobby.Id),
MaxSize = (int)lobby.Capacity,
},
},
Secrets = {
Spectate = spectateActivitySecret,
Join = joinActivitySecret,
},
Instance = true,
};
activityManager.UpdateActivity(activity, result =>
{
Debug.LogFormat("Updated to Multiplayer Activity: {0}", result);
// Send an invite to another user for this activity.
// Receiver should see an invite in their DM.
// Use a relationship user's ID for this.
// activityManager
// .SendInvite(
// 364843917537050624,
// Discord.ActivityActionType.Join,
// "",
// inviteResult =>
// {
// Console.WriteLine("Invite {0}", inviteResult);
// }
// );
});
}

OnActivitySpectate

Fires when a user accepts a spectate chat invite or clicks the Spectate button on a user's profile.

Parameters
nametypedescription
spectateSecretstringthe secret to join the user's game as a spectator
Example
cs
// Received when someone accepts a request to spectate
activityManager.OnActivitySpectate += secret =>
{
Console.WriteLine("OnSpectate {0}", secret);
};

OnActivityJoinRequest

Fires when a user asks to join the current user's game.

Parameters
nametypedescription
userUserthe user asking to join
Example
cs
// A join request has been received. Render the request on the UI.
activityManager.OnActivityJoinRequest += (ref Discord.User user) =>
{
Console.WriteLine("OnJoinRequest {0} {1}", user.Username, user.Id);
};

OnActivityInvite

Fires when the user receives a join or spectate invite.

Parameters
nametypedescription
typeActivityActiontypewhether this invite is to join or spectate
userUserthe user sending the invite
activityActivitythe inviting user's current activity
Example
cs
// An invite has been received. Consider rendering the user / activity on the UI.
activityManager.OnActivityInvite += (Discord.ActivityActionType Type, ref Discord.User user, ref Discord.Activity activity2) =>
{
Console.WriteLine("Recieved Invite Type: {0}, from User: {1}, with Activity Name: {2}", Type, user.Username, activity2.Name);
// activityManager.AcceptInvite(user.Id, result =>
// {
// Console.WriteLine("AcceptInvite {0}", result);
// });
};

Example: Inviting a User to a Game

cs
var discord = new Discord.Discord(clientId, Discord.CreateFlags.Default);
// Update user's activity for your game.
// Party and secrets are vital.
var activity = new Discord.Activity
{
State = "olleh",
Details = "foo details",
Timestamps =
{
Start = 5,
End = 6,
},
Assets =
{
LargeImage = "foo largeImageKey",
LargeText = "foo largeImageText",
SmallImage = "foo smallImageKey",
SmallText = "foo smallImageText",
},
Party =
{
Id = "foo partyID",
Size = {
CurrentSize = 1,
MaxSize = 4,
},
},
Secrets =
{
Match = "foo matchSecret",
Join = "foo joinSecret",
Spectate = "foo spectateSecret",
},
Instance = true,
};
activityManager.UpdateActivity(activity, (result) =>
{
Console.WriteLine("Update Activity {0}", result);
// Send an invite to another user for this activity.
// Receiver should see an invite in their DM.
// Use a relationship user's ID for this.
activityManager.SendInvite(364843917537050999, Discord.ActivityActionType.Join, "", (inviteUserResult) =>
{
Console.WriteLine("Invite User {0}", inviteUserResult);
});
});