diff --git a/docs/guides/bearer_token/bearer_token_guide.md b/docs/guides/bearer_token/bearer_token_guide.md
new file mode 100644
index 000000000..edaf61374
--- /dev/null
+++ b/docs/guides/bearer_token/bearer_token_guide.md
@@ -0,0 +1,68 @@
+---
+uid: Guides.BearerToken
+title: Working with Bearer token
+---
+
+# Working with Bearer token
+
+Some endpoints in Discord API require a Bearer token, which can be obtained through [OAuth2 flow](https://discord.com/developers/docs/topics/oauth2). Discord.Net allows you to interact with these endpoints using the [DiscordRestClient].
+
+## Initializing a new instance of the client
+[!code-csharp[Initialize DiscordRestClient](samples/rest_client_init.cs)]
+
+## Getting current user
+
+The [DiscordRestClient] gets the current user when `LoginAsync()` is called. The user object can be found in the `CurrentUser` property.
+
+If you need to fetch the user again, the `GetGetCurrentUserAsync()` method can be used.
+
+[!code-csharp[Get current user](samples/current_user.cs)]
+
+> [!NOTE]
+> Some properties might be `null` depending on which scopes users authorized your app with.
+> For example: `email` scope is required to fetch current user's email address.
+
+## Fetching current user's guilds
+
+The `GetGuildSummariesAsync()` method is used to fetch current user's guilds. Since it returns an `IAsyncEnumerable` you need to call `FlattenAsync()` to get a plain `IEnumerable` containing [RestUserGuild] objects.
+
+[!code-csharp[Get current user's guilds](samples/current_user_guilds.cs)]
+
+> [!WARNING]
+> This method requires `guilds` scope
+
+## Fetching current user's guild member object
+
+To fetch the current user's guild member object, the `GetCurrentUserGuildMemberAsync()` method can be used.
+
+[!code-csharp[Get current user's guild member](samples/current_user_guild_member.cs)]
+
+> [!WARNING]
+> This method requires `guilds.members.read` scope
+
+## Get user connections
+
+The `GetConnectionsAsync` method can be used to fetch current user's connections to other platforms.
+
+[!code-csharp[Get current user's connections](samples/current_user_connections.cs)]
+
+> [!WARNING]
+> This method requires `connections` scope
+
+## Application role connection
+
+In addition to previous features, Discord.Net supports fetching & updating user's application role connection metadata values. `GetUserApplicationRoleConnectionAsync()` returns a [RoleConnection] object of the current user for the given application id.
+
+The `ModifyUserApplicationRoleConnectionAsync()` method is used to update current user's role connection metadata values. A new set of values can be created with [RoleConnectionProperties] object.
+
+[!code-csharp[Get current user's connections](samples/app_role_connection.cs)]
+
+> [!WARNING]
+> This method requires `role_connections.write` scope
+
+
+
+[DiscordRestClient]: xref:Discord.Rest.DiscordRestClient
+[RestUserGuild]: xref:Discord.Rest.RestUserGuild
+[RoleConnection]: xref:Discord.RoleConnection
+[RoleConnectionProperties]: xref:Discord.RoleConnectionProperties
diff --git a/docs/guides/bearer_token/samples/app_role_connection.cs b/docs/guides/bearer_token/samples/app_role_connection.cs
new file mode 100644
index 000000000..cff57a894
--- /dev/null
+++ b/docs/guides/bearer_token/samples/app_role_connection.cs
@@ -0,0 +1,11 @@
+// fetch application role connection of the current user for the app with provided id.
+var roleConnection = await client.GetUserApplicationRoleConnectionAsync(applicationid);
+
+// create a new role connection metadata properties object & set some values.
+var properties = new RoleConnectionProperties("Discord.Net Docs", "Cool Coding Guy")
+ .WithNumber("eaten_cookies", 69)
+ .WithBool("loves_cookies", true)
+ .WithDate("last_eaten_cookie", DateTimeOffset.UtcNow);
+
+// update current user's values with the given properties.
+await client.ModifyUserApplicationRoleConnectionAsync(applicationId, properties);
diff --git a/docs/guides/bearer_token/samples/current_user.cs b/docs/guides/bearer_token/samples/current_user.cs
new file mode 100644
index 000000000..1b7337d71
--- /dev/null
+++ b/docs/guides/bearer_token/samples/current_user.cs
@@ -0,0 +1,5 @@
+// gets the user object stored in the DiscordRestClient.
+var user = client.CurrentUser;
+
+// fetches the current user with a REST call & updates the CurrentUser property.
+var refreshedUser = await client.GetCurrentUserAsync();
\ No newline at end of file
diff --git a/docs/guides/bearer_token/samples/current_user_connections.cs b/docs/guides/bearer_token/samples/current_user_connections.cs
new file mode 100644
index 000000000..be339753d
--- /dev/null
+++ b/docs/guides/bearer_token/samples/current_user_connections.cs
@@ -0,0 +1,2 @@
+// fetches the current user's connections.
+var connections = await client.GetConnectionsAsync();
\ No newline at end of file
diff --git a/docs/guides/bearer_token/samples/current_user_guild_member.cs b/docs/guides/bearer_token/samples/current_user_guild_member.cs
new file mode 100644
index 000000000..bfbe3632f
--- /dev/null
+++ b/docs/guides/bearer_token/samples/current_user_guild_member.cs
@@ -0,0 +1,6 @@
+// fetches the current user's guild member object in a guild with provided id.
+var member = await client.GetCurrentUserGuildMemberAsync(guildId);
+
+// fetches the current user's guild member object in a RestUserGuild.
+var guild = await client.GetGuildSummariesAsync().FlattenAsync().First();
+var member = await guild.GetCurrentUserGuildMemberAsync();
\ No newline at end of file
diff --git a/docs/guides/bearer_token/samples/current_user_guilds.cs b/docs/guides/bearer_token/samples/current_user_guilds.cs
new file mode 100644
index 000000000..f98e36096
--- /dev/null
+++ b/docs/guides/bearer_token/samples/current_user_guilds.cs
@@ -0,0 +1,2 @@
+// fetches the guilds the current user participate in.
+var guilds = await client.GetGuildSummariesAsync().FlattenAsync();
\ No newline at end of file
diff --git a/docs/guides/bearer_token/samples/rest_client_init.cs b/docs/guides/bearer_token/samples/rest_client_init.cs
new file mode 100644
index 000000000..e810a4fb2
--- /dev/null
+++ b/docs/guides/bearer_token/samples/rest_client_init.cs
@@ -0,0 +1,5 @@
+using Discord;
+using Discord.Rest;
+
+await using var client = new DiscordRestClient();
+await client.LoginAsync(TokenType.Bearer, "bearer token obtained through oauth2 flow");
\ No newline at end of file
diff --git a/docs/guides/toc.yml b/docs/guides/toc.yml
index c892eb8c4..f2cefda8d 100644
--- a/docs/guides/toc.yml
+++ b/docs/guides/toc.yml
@@ -126,6 +126,8 @@
topicUid: Guides.OtherLibs.MediatR
- name: Emoji
topicUid: Guides.Emoji
+- name: Bearer Tokens
+ topicUid: Guides.BearerToken
- name: Voice
topicUid: Guides.Voice.SendingVoice
- name: Deployment
diff --git a/src/Discord.Net.Core/Entities/Guilds/IUserGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IUserGuild.cs
index b6685edf6..741dc335c 100644
--- a/src/Discord.Net.Core/Entities/Guilds/IUserGuild.cs
+++ b/src/Discord.Net.Core/Entities/Guilds/IUserGuild.cs
@@ -18,5 +18,13 @@ namespace Discord
/// Returns the current user's permissions for this guild.
///
GuildPermissions Permissions { get; }
+
+ ///
+ /// Gets the features for this guild.
+ ///
+ ///
+ /// A flags enum containing all the features for the guild.
+ ///
+ GuildFeatures Features { get; }
}
}
diff --git a/src/Discord.Net.Rest/API/Common/UserGuild.cs b/src/Discord.Net.Rest/API/Common/UserGuild.cs
index fc1fe833d..a501604a0 100644
--- a/src/Discord.Net.Rest/API/Common/UserGuild.cs
+++ b/src/Discord.Net.Rest/API/Common/UserGuild.cs
@@ -14,5 +14,7 @@ namespace Discord.API
public bool Owner { get; set; }
[JsonProperty("permissions"), Int53]
public string Permissions { get; set; }
+ [JsonProperty("features")]
+ public GuildFeatures Features { get; set; }
}
}
diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs
index 7d015d912..c759119c2 100644
--- a/src/Discord.Net.Rest/DiscordRestApiClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs
@@ -1,4 +1,3 @@
-
using Discord.API.Rest;
using Discord.Net;
using Discord.Net.Converters;
@@ -2204,6 +2203,14 @@ namespace Discord.API
return await SendJsonAsync("POST", () => "users/@me/channels", args, new BucketIds(), options: options).ConfigureAwait(false);
}
+
+ public async Task GetCurrentUserGuildMember(ulong guildId, RequestOptions options = null)
+ {
+ options = RequestOptions.CreateOrClone(options);
+
+ var ids = new BucketIds();
+ return await SendAsync("GET", () => $"users/@me/guilds/{guildId}/member", ids, options: options).ConfigureAwait(false);
+ }
#endregion
#region Voice Regions
diff --git a/src/Discord.Net.Rest/DiscordRestClient.cs b/src/Discord.Net.Rest/DiscordRestClient.cs
index 0778e69ad..dbb2b9918 100644
--- a/src/Discord.Net.Rest/DiscordRestClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestClient.cs
@@ -152,6 +152,19 @@ namespace Discord.Rest
#endregion
+ public async Task GetCurrentUserAsync(RequestOptions options = null)
+ {
+ var user = await ApiClient.GetMyUserAsync(options);
+ CurrentUser.Update(user);
+ return CurrentUser;
+ }
+
+ public async Task GetCurrentUserGuildMemberAsync(ulong guildId, RequestOptions options = null)
+ {
+ var user = await ApiClient.GetCurrentUserGuildMember(guildId, options);
+ return RestGuildUser.Create(this, null, user, guildId);
+ }
+
public async Task GetApplicationInfoAsync(RequestOptions options = null)
{
return _applicationInfo ??= await ClientHelper.GetApplicationInfoAsync(this, options).ConfigureAwait(false);
diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestUserGuild.cs b/src/Discord.Net.Rest/Entities/Guilds/RestUserGuild.cs
index b75d6288e..6131c6520 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/RestUserGuild.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/RestUserGuild.cs
@@ -21,6 +21,8 @@ namespace Discord.Rest
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
///
public string IconUrl => CDN.GetGuildIconUrl(Id, _iconId);
+ ///
+ public GuildFeatures Features { get; private set; }
internal RestUserGuild(BaseDiscordClient discord, ulong id)
: base(discord, id)
@@ -39,12 +41,20 @@ namespace Discord.Rest
IsOwner = model.Owner;
Name = model.Name;
Permissions = new GuildPermissions(model.Permissions);
+ Features = model.Features;
}
public async Task LeaveAsync(RequestOptions options = null)
{
await Discord.ApiClient.LeaveGuildAsync(Id, options).ConfigureAwait(false);
}
+
+ public async Task GetCurrentUserGuildMemberAsync(RequestOptions options = null)
+ {
+ var user = await Discord.ApiClient.GetCurrentUserGuildMember(Id, options);
+ return RestGuildUser.Create(Discord, null, user, Id);
+ }
+
///
public async Task DeleteAsync(RequestOptions options = null)
{