diff --git a/src/Discord.Net.Core/CDN.cs b/src/Discord.Net.Core/CDN.cs
index 32ffbba90..799b037ed 100644
--- a/src/Discord.Net.Core/CDN.cs
+++ b/src/Discord.Net.Core/CDN.cs
@@ -7,6 +7,17 @@ namespace Discord
///
public static class CDN
{
+ ///
+ /// Returns a team icon URL.
+ ///
+ /// The team identifier.
+ /// The icon identifier.
+ ///
+ /// A URL pointing to the team's icon.
+ ///
+ public static string GetTeamIconUrl(ulong teamId, string iconId)
+ => iconId != null ? $"{DiscordConfig.CDNUrl}team-icons/{teamId}/{iconId}.jpg" : null;
+
///
/// Returns an application icon URL.
///
diff --git a/src/Discord.Net.Core/Entities/IApplication.cs b/src/Discord.Net.Core/Entities/IApplication.cs
index 78a87dc19..2174baff9 100644
--- a/src/Discord.Net.Core/Entities/IApplication.cs
+++ b/src/Discord.Net.Core/Entities/IApplication.cs
@@ -22,6 +22,18 @@ namespace Discord
/// Gets the icon URL of the application.
///
string IconUrl { get; }
+ ///
+ /// Gets if the bot is public.
+ ///
+ bool IsBotPublic { get; }
+ ///
+ /// Gets if the bot requires code grant.
+ ///
+ bool BotRequiresCodeGrant { get; }
+ ///
+ /// Gets the team associated with this application if there is one.
+ ///
+ ITeam Team { get; }
///
/// Gets the partial user object containing info on the owner of the application.
diff --git a/src/Discord.Net.Core/Entities/Teams/ITeam.cs b/src/Discord.Net.Core/Entities/Teams/ITeam.cs
new file mode 100644
index 000000000..5ef3e4253
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Teams/ITeam.cs
@@ -0,0 +1,27 @@
+using System.Collections.Generic;
+
+namespace Discord
+{
+ ///
+ /// Represents a Discord Team.
+ ///
+ public interface ITeam
+ {
+ ///
+ /// Gets the team icon url.
+ ///
+ string IconUrl { get; }
+ ///
+ /// Gets the team unique identifier.
+ ///
+ ulong Id { get; }
+ ///
+ /// Gets the members of this team.
+ ///
+ IReadOnlyList TeamMembers { get; }
+ ///
+ /// Gets the user identifier that owns this team.
+ ///
+ ulong OwnerUserId { get; }
+ }
+}
diff --git a/src/Discord.Net.Core/Entities/Teams/ITeamMember.cs b/src/Discord.Net.Core/Entities/Teams/ITeamMember.cs
new file mode 100644
index 000000000..fe0e499e5
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Teams/ITeamMember.cs
@@ -0,0 +1,25 @@
+namespace Discord
+{
+ ///
+ /// Represents a Discord Team member.
+ ///
+ public interface ITeamMember
+ {
+ ///
+ /// Gets the membership state of this team member.
+ ///
+ MembershipState MembershipState { get; }
+ ///
+ /// Gets the permissions of this team member.
+ ///
+ string[] Permissions { get; }
+ ///
+ /// Gets the team unique identifier for this team member.
+ ///
+ ulong TeamId { get; }
+ ///
+ /// Gets the Discord user of this team member.
+ ///
+ IUser User { get; }
+ }
+}
diff --git a/src/Discord.Net.Core/Entities/Teams/MembershipState.cs b/src/Discord.Net.Core/Entities/Teams/MembershipState.cs
new file mode 100644
index 000000000..45b1693b0
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Teams/MembershipState.cs
@@ -0,0 +1,11 @@
+namespace Discord
+{
+ ///
+ /// Represents the membership state of a team member.
+ ///
+ public enum MembershipState
+ {
+ Invited,
+ Accepted,
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Common/Application.cs b/src/Discord.Net.Rest/API/Common/Application.cs
index ca4c443f1..b80aecd27 100644
--- a/src/Discord.Net.Rest/API/Common/Application.cs
+++ b/src/Discord.Net.Rest/API/Common/Application.cs
@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API
@@ -15,6 +15,12 @@ namespace Discord.API
public ulong Id { get; set; }
[JsonProperty("icon")]
public string Icon { get; set; }
+ [JsonProperty("bot_public")]
+ public bool IsBotPublic { get; set; }
+ [JsonProperty("bot_require_code_grant")]
+ public bool BotRequiresCodeGrant { get; set; }
+ [JsonProperty("team")]
+ public Optional Team { get; set; }
[JsonProperty("flags"), Int53]
public Optional Flags { get; set; }
diff --git a/src/Discord.Net.Rest/API/Common/MembershipState.cs b/src/Discord.Net.Rest/API/Common/MembershipState.cs
new file mode 100644
index 000000000..67fcc8908
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Common/MembershipState.cs
@@ -0,0 +1,9 @@
+namespace Discord.API
+{
+ internal enum MembershipState
+ {
+ None = 0,
+ Invited = 1,
+ Accepted = 2,
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Common/Team.cs b/src/Discord.Net.Rest/API/Common/Team.cs
new file mode 100644
index 000000000..4910f43f7
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Common/Team.cs
@@ -0,0 +1,17 @@
+#pragma warning disable CS1591
+using Newtonsoft.Json;
+
+namespace Discord.API
+{
+ internal class Team
+ {
+ [JsonProperty("icon")]
+ public Optional Icon { get; set; }
+ [JsonProperty("id")]
+ public ulong Id { get; set; }
+ [JsonProperty("members")]
+ public TeamMember[] TeamMembers { get; set; }
+ [JsonProperty("owner_user_id")]
+ public ulong OwnerUserId { get; set; }
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Common/TeamMember.cs b/src/Discord.Net.Rest/API/Common/TeamMember.cs
new file mode 100644
index 000000000..788f73b61
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Common/TeamMember.cs
@@ -0,0 +1,17 @@
+#pragma warning disable CS1591
+using Newtonsoft.Json;
+
+namespace Discord.API
+{
+ internal class TeamMember
+ {
+ [JsonProperty("membership_state")]
+ public MembershipState MembershipState { get; set; }
+ [JsonProperty("permissions")]
+ public string[] Permissions { get; set; }
+ [JsonProperty("team_id")]
+ public ulong TeamId { get; set; }
+ [JsonProperty("user")]
+ public User User { get; set; }
+ }
+}
diff --git a/src/Discord.Net.Rest/Entities/RestApplication.cs b/src/Discord.Net.Rest/Entities/RestApplication.cs
index d033978d0..6c22c0836 100644
--- a/src/Discord.Net.Rest/Entities/RestApplication.cs
+++ b/src/Discord.Net.Rest/Entities/RestApplication.cs
@@ -21,6 +21,12 @@ namespace Discord.Rest
public string[] RPCOrigins { get; private set; }
///
public ulong Flags { get; private set; }
+ ///
+ public bool IsBotPublic { get; private set; }
+ ///
+ public bool BotRequiresCodeGrant { get; private set; }
+ ///
+ public ITeam Team { get; private set; }
///
public IUser Owner { get; private set; }
@@ -46,11 +52,15 @@ namespace Discord.Rest
RPCOrigins = model.RPCOrigins;
Name = model.Name;
_iconId = model.Icon;
+ IsBotPublic = model.IsBotPublic;
+ BotRequiresCodeGrant = model.BotRequiresCodeGrant;
if (model.Flags.IsSpecified)
Flags = model.Flags.Value; //TODO: Do we still need this?
if (model.Owner.IsSpecified)
Owner = RestUser.Create(Discord, model.Owner.Value);
+ if (model.Team.IsSpecified)
+ Team = RestTeam.Create(Discord, model.Team.Value);
}
/// Unable to update this object from a different application token.
diff --git a/src/Discord.Net.Rest/Entities/Teams/RestTeam.cs b/src/Discord.Net.Rest/Entities/Teams/RestTeam.cs
new file mode 100644
index 000000000..2343f8b5d
--- /dev/null
+++ b/src/Discord.Net.Rest/Entities/Teams/RestTeam.cs
@@ -0,0 +1,37 @@
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using Model = Discord.API.Team;
+
+namespace Discord.Rest
+{
+ public class RestTeam : RestEntity, ITeam
+ {
+ ///
+ public string IconUrl => _iconId != null ? CDN.GetTeamIconUrl(Id, _iconId) : null;
+ ///
+ public IReadOnlyList TeamMembers { get; private set; }
+ ///
+ public ulong OwnerUserId { get; private set; }
+
+ private string _iconId;
+
+ internal RestTeam(BaseDiscordClient discord, ulong id)
+ : base(discord, id)
+ {
+ }
+ internal static RestTeam Create(BaseDiscordClient discord, Model model)
+ {
+ var entity = new RestTeam(discord, model.Id);
+ entity.Update(model);
+ return entity;
+ }
+ internal virtual void Update(Model model)
+ {
+ if (model.Icon.IsSpecified)
+ _iconId = model.Icon.Value;
+ OwnerUserId = model.OwnerUserId;
+ TeamMembers = model.TeamMembers.Select(x => new RestTeamMember(Discord, x)).ToImmutableArray();
+ }
+ }
+}
diff --git a/src/Discord.Net.Rest/Entities/Teams/RestTeamMember.cs b/src/Discord.Net.Rest/Entities/Teams/RestTeamMember.cs
new file mode 100644
index 000000000..322bb6a3f
--- /dev/null
+++ b/src/Discord.Net.Rest/Entities/Teams/RestTeamMember.cs
@@ -0,0 +1,30 @@
+using System;
+using Model = Discord.API.TeamMember;
+
+namespace Discord.Rest
+{
+ public class RestTeamMember : ITeamMember
+ {
+ ///
+ public MembershipState MembershipState { get; }
+ ///
+ public string[] Permissions { get; }
+ ///
+ public ulong TeamId { get; }
+ ///
+ public IUser User { get; }
+
+ internal RestTeamMember(BaseDiscordClient discord, Model model)
+ {
+ MembershipState = model.MembershipState switch
+ {
+ API.MembershipState.Invited => MembershipState.Invited,
+ API.MembershipState.Accepted => MembershipState.Accepted,
+ _ => throw new InvalidOperationException("Invalid membership state"),
+ };
+ Permissions = model.Permissions;
+ TeamId = model.TeamId;
+ User = RestUser.Create(discord, model.User);
+ }
+ }
+}