Creating a Unified Friends List
Build a unified friends list that combines Discord relationships with your application.
Overview
Section titled “Overview”A unified friends list combines both Discord and game-specific relationships in one view. This guide will show you how to:
- Fetch all relationship data
- Filter and organize relationships
- Display online status
- Handle different relationship types
Prerequisites
Section titled “Prerequisites”Before you begin, make sure you have:
- Set up the Discord Social SDK with Getting Started Guide
- Authenticated your users with Development Guide: Account Linking
- Understanding of relationship types with Development Guide: Managing Relationships in Your Game
Implementing a Unified Friends List
Section titled “Implementing a Unified Friends List”The Discord friend list is ultimately constructed from two entities: Relationships, and Users. You can query Relationships API to find everyone a user is a friend with, and the Users API to find the necessary extra information for rendering the list, such as whether they are online or not.
Relationships
Section titled “Relationships”Relationships are how Discord models friends,
friend requests, and more. All relationships for the current user are loaded when the Client connects. Each
relationship has a target user id, and a type, such as Friend, PendingOutgoing, or Blocked.
To allow users to manage their relationships in your game, you should provide a way to accept or reject friend requests, block users, and manage pending requests. See Development Guide: Managing Relationships in Your Game for implementation details.
Users are the Discord users that are part of the relationships. The SDK provides a way to fetch a user by their ID, and the user object contains information such as their username, display name, avatar, and more.
User Status & Rich Presence
Section titled “User Status & Rich Presence”Presence is how Discord stores whether a user is currently online or not, as well as what activities they are currently doing (such as playing a game). The SDK gives you access to two types of status:
- Online Status: Online, Offline, Idle, etc.
- Rich Presence: Any activities associated with the current game (or application in Discord parlance).
See our Design Guidelines: Status & Rich Presence for best practices on displaying presence information.
There are two ways in which you can create a unified friends list in your game:
- Using the SDK Unified Friends List helper functions, which automatically group and sort relationships and users for you.
- Directly retrieving relationships and users from the SDK, and sorting manually.
Approach 1: Using SDK Unified Friends List Helper Functions
Section titled “Approach 1: Using SDK Unified Friends List Helper Functions”The Discord Social SDK provides built-in helper functions that automatically group and sort your friends list according to Discord's recommended design guidelines. This approach is generally simpler and more maintainable than manually fetching and organizing relationships.
The SDK automatically organizes friends into the three groups we find via RelationshipGroupType:
OnlinePlayingGame: Friends who are online and currently playing your gameOnlineElsewhere: Friends who are online but not playing your gameOffline: Friends who are offline
Step 1: Display the Unified Friends List
Section titled “Step 1: Display the Unified Friends List”The Client::GetRelationshipsByGroup method returns a pre-sorted list of relationships for a specific group type.
This eliminates the need to manually filter, categorize, and sort friends yourself. The SDK handles all the logic
for determining which group each friend belongs to based on their online status and game activity, and
automatically sorts users within each group (for example, users who have played your game are moved to the top of
the OnlineElsewhere group).
Let's create a function that uses the SDK helper functions to display a properly organized friends list:
void DisplayUnifiedFriendsList(const std::shared_ptr<discordpp::Client> &client) {
// Get friends playing the game
const auto onlineInGame = client->GetRelationshipsByGroup(
discordpp::RelationshipGroupType::OnlinePlayingGame
);
// Get friends online elsewhere
const auto onlineElsewhere = client->GetRelationshipsByGroup(
discordpp::RelationshipGroupType::OnlineElsewhere
);
// Get offline friends
const auto offline = client->GetRelationshipsByGroup(
discordpp::RelationshipGroupType::Offline
);
// Display "Online - GameTitle" Friends
std::cout << "\n=== Online - GameTitle (" << onlineInGame.size() << ") ===\n";
for (const auto& relationship : onlineInGame) {
auto user = relationship.User();
if (user) {
std::string displayStr = "🟣 " + user->DisplayName();
// Add Discord friend indicator
if (relationship.DiscordRelationshipType() == discordpp::RelationshipType::Friend) {
displayStr += " 👾";
}
// Add game friend indicator
if (relationship.GameRelationshipType() == discordpp::RelationshipType::Friend) {
displayStr += " 🎮";
}
std::cout << displayStr << "\n";
}
}
// Display "Online - Elsewhere" Friends
std::cout << "\n=== Online - Elsewhere (" << onlineElsewhere.size() << ") ===\n";
for (const auto& relationship : onlineElsewhere) {
auto user = relationship.User();
if (user) {
std::string displayStr = "🟢 " + user->DisplayName();
// Add Discord friend indicator
if (relationship.DiscordRelationshipType() == discordpp::RelationshipType::Friend) {
displayStr += " 👾";
}
// Add game friend indicator
if (relationship.GameRelationshipType() == discordpp::RelationshipType::Friend) {
displayStr += " 🎮";
}
std::cout << displayStr << "\n";
}
}
// Display "Offline" Friends
std::cout << "\n=== Offline (" << offline.size() << ") ===\n";
for (const auto& relationship : offline) {
auto user = relationship.User();
if (user) {
std::string displayStr = "⚫ " + user->DisplayName();
// Add Discord friend indicator
if (relationship.DiscordRelationshipType() == discordpp::RelationshipType::Friend) {
displayStr += " 👾";
}
// Add game friend indicator
if (relationship.GameRelationshipType() == discordpp::RelationshipType::Friend) {
displayStr += " 🎮";
}
std::cout << displayStr << "\n";
}
}
}Step 2: Set Up Automatic Updates
Section titled “Step 2: Set Up Automatic Updates”To keep your friends list up-to-date automatically, use the Client::SetRelationshipGroupsUpdatedCallback. This
callback is triggered whenever any change occurs that might affect the friends list grouping, such as a friend going
online or offline, or when a relationship changes, such as when you accept a friend request, or block a user.
// Set up the unified friends list update callback
client->SetRelationshipGroupsUpdatedCallback([&client](const uint64_t userId) {
std::cout << "👥 Friends list updated for user: " << userId << std::endl;
DisplayUnifiedFriendsList(client);
});Approach 2: Manually Fetching Relationships and Users
Section titled “Approach 2: Manually Fetching Relationships and Users”In this section we'll show a more manual method which gives you more control over how the friends list is displayed in your game.
Step 1: Fetch Relationships
Section titled “Step 1: Fetch Relationships”First, let's create a function that utilises Client::GetRelationships to query all the relationships and
user information we for our account:
void DisplayFriendsList(discordpp::Client& client) {
std::vector<std::string> relationships{};
for (auto& relationship: client->GetRelationships()) {
auto user = relationship.User();
if (!user) {
continue;
}
std::string str{};
// Identifying information about the user:
str += " DiscordName: " + user->DisplayName();
str += " DiscordId: " + std::to_string(user->Id());
// Provisional users don't have a Discord icon shown next to them:
str += " IsProvisional: " + std::to_string(user->IsProvisional());
// Whether the relationship is for a friend, a friend request, or because the user is blocked:
// For a friends list you'll want to filter out blocked users
// And likely display friend requests in a different section
str += " DiscordRelationshipType: " + std::string(discordpp::EnumToString(relationship.DiscordRelationshipType()));
str += " GameRelationshipType: " + std::string(discordpp::EnumToString(relationship.GameRelationshipType()));
// Whether the user is online/offline/etc:
str += " IsOnlineAnywhere: " + std::to_string(user->Status() != discordpp::StatusType::Offline);
str += " IsOnlineInGame: " + std::to_string(user->GameActivity() != std::nullopt);
relationships.push_back(str);
}
std::sort(relationships.begin(), relationships.end());
for (auto str : relationships) {
printf("%s\n", str.c_str());
}
}We will want to call this function when the client is ready, so let's add it to our ready callback:
// Set up status callback to monitor client connection
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! You can now call SDK functions.\n";
std::cout << "👥 Friends Count: " << client->GetRelationships().size() << std::endl;
SetRichPresence(client);
DisplayFriendsList(client);
} else if (error != discordpp::Client::Error::None) {
std::cerr << "❌ Connection Error: " << discordpp::Client::ErrorToString(error) << " - Details: " << errorDetail << std::endl;
}
});This will output the raw relationship data to the console. You can use this information to filter, organize and build a friends list that fits your game's design aesthetic.
Step 2: Organize Relationships
Section titled “Step 2: Organize Relationships”Based on our design guidelines for a Unified Friends List, you should separate the player's friends list into three sections: Online - GameTitle, Online - Elsewhere, and Offline.
Because we are building a text console application, we will use emojis to represent the status of each friend but you can use your own design elements to convey status and presence in your game.
Let's update our DisplayFriendsList function to reflect our three sections and categorize friends based on their status:
- We will create three vectors to store the friends in each category.
- We will filter out pending friends and blocked users.
- We will add indicators for Discord friends, game friends, and provisional users.
- We will categorize friends based on their game and presence status.
- We will sort each category alphabetically.
- We will display each category separately.
void DisplayFriendsList(std::shared_ptr<discordpp::Client> client) {
// Create vectors for each section
std::vector<std::string> inGame;
std::vector<std::string> online;
std::vector<std::string> offline;
for (auto& relationship : client->GetRelationships()) {
auto user = relationship.User();
if (!user) {
continue;
}
// Filter out pending friends and blocked users
// You can display friend requests and blocked users in a different view to allow players to manage them in your game
if (relationship.DiscordRelationshipType() != discordpp::RelationshipType::Friend) {
continue;
}
std::string str;
str += user->DisplayName();
// Add Discord friend indicator
// In a real game, please use the official Discord logo available in our design guidelines
if (relationship.DiscordRelationshipType() == discordpp::RelationshipType::Friend) {
str += " 👾";
}
// Add game friend indicator
if (relationship.GameRelationshipType() == discordpp::RelationshipType::Friend) {
str += " 🎮";
}
// Add provisional indicator
if (user->IsProvisional()) {
str += " (Provisional)";
}
// Categorize based on status
if (user->GameActivity()) {
// in game
inGame.push_back("🟣 " + str);
} else if (user->Status() != discordpp::StatusType::Offline) {
// online
online.push_back("🟢 " + str);
} else {
// offline
offline.push_back("⚫ " + str);
}
}
// Sort each category
std::sort(inGame.begin(), inGame.end());
std::sort(online.begin(), online.end());
std::sort(offline.begin(), offline.end());
// Display "Online - GameTitle" Friends
std::cout << "\n=== Online - GameTitle (" << inGame.size() << ") ===\n";
for (const auto& str : inGame) {
std::cout << str << "\n";
}
// Display "Online - Elsewhere" Friends
std::cout << "\n=== Online - Elsewhere (" << online.size() << ") ===\n";
for (const auto& str : online) {
std::cout << str << "\n";
}
// Display "Offline" Friends
std::cout << "\n=== Offline (" << offline.size() << ") ===\n";
for (const auto& str : offline) {
std::cout << str << "\n";
}
}If we build and run our application, we should now see a list of friends separated into three categories: Online - GameTitle, Online - Elsewhere, and Offline.
Step 3: Monitor Changes to Users
Section titled “Step 3: Monitor Changes to Users”To monitor for user changes, we're going using the Client::SetUserUpdatedCallback function.
This callback will be triggered whenever a user's info is updated, such as name or presence changes (when they go online, offline, or start playing your game).
client->SetUserUpdatedCallback([&client](uint64_t userId) {
std::cout << "👤 User updated: " << userId << std::endl;
DisplayFriendsList(*client);
});Now your friends list will automatically update when the presence of a friend changes, such as when they go online, offline or start playing your game.
Step 4: Monitor Changes in Relationships
Section titled “Step 4: Monitor Changes in Relationships”Let us setup two callbacks to handle relationship updates.
Relationship Created Callback
Section titled “Relationship Created Callback”This can happen when a user sends or accepts a friend invite, or blocks a user.
client->SetRelationshipCreatedCallback([&client](uint64_t userId, bool isDiscordRelationshipUpdate) {
std::optional<discordpp::UserHandle> user = client->GetUser(userId);
// if the userid is valid (which it should be), we can display the user's display name
if(user) {
std::cout << "🤝 Relationship created: " << user->DisplayName() << std::endl;
DisplayFriendsList(*client);
}
});Relationship Deleted Callback
Section titled “Relationship Deleted Callback”This can happen when a user rejects a friend request or removes a friend.
client->SetRelationshipDeletedCallback([&client](uint64_t userId, bool isDiscordRelationshipUpdate) {
std::cout << "🔥 Relationship deleted: " << userId << std::endl;
DisplayFriendsList(*client);
});Now your friends list will automatically update when relationships change, such as when you add a new friend, accept a friend request, or block a user.
Next Steps
Section titled “Next Steps”Now that you have a unified friends list, you can build on your social features by allowing players to manage relationships, send game invites, and more. Check out our other guides for more information:
Designing a Unified Friends List
Best practices for designing your Unified Friends List.
Managing Relationships
Allow players to manage their friends, friend requests, and blocked users.
Managing Game Invites
Allow players to invite friends to join their game session or party.
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
Section titled “Change Log”| Date | Changes |
|---|---|
| March 17, 2025 | Initial release |
| July 17, 2025 | Add UFL helper methods |