* fix integration models; add integration events * fix description on IGUILD for integration * fix typo in integration documentation * fix documentation in connection visibility * removed public identitiers from app and connection * Removed REST endpoints that are not part of the API. * Added documentation for rest integrations * added optional types * Fixed rest interaction field with not being IsSpecifiedtags/3.5.0
| @@ -1,21 +0,0 @@ | |||||
| namespace Discord | |||||
| { | |||||
| /// <summary> | |||||
| /// Provides properties used to modify an <see cref="IGuildIntegration" /> with the specified changes. | |||||
| /// </summary> | |||||
| public class GuildIntegrationProperties | |||||
| { | |||||
| /// <summary> | |||||
| /// Gets or sets the behavior when an integration subscription lapses. | |||||
| /// </summary> | |||||
| public Optional<int> ExpireBehavior { get; set; } | |||||
| /// <summary> | |||||
| /// Gets or sets the period (in seconds) where the integration will ignore lapsed subscriptions. | |||||
| /// </summary> | |||||
| public Optional<int> ExpireGracePeriod { get; set; } | |||||
| /// <summary> | |||||
| /// Gets or sets whether emoticons should be synced for this integration. | |||||
| /// </summary> | |||||
| public Optional<bool> EnableEmoticons { get; set; } | |||||
| } | |||||
| } | |||||
| @@ -718,8 +718,25 @@ namespace Discord | |||||
| /// </returns> | /// </returns> | ||||
| Task<IReadOnlyCollection<IVoiceRegion>> GetVoiceRegionsAsync(RequestOptions options = null); | Task<IReadOnlyCollection<IVoiceRegion>> GetVoiceRegionsAsync(RequestOptions options = null); | ||||
| Task<IReadOnlyCollection<IGuildIntegration>> GetIntegrationsAsync(RequestOptions options = null); | |||||
| Task<IGuildIntegration> CreateIntegrationAsync(ulong id, string type, RequestOptions options = null); | |||||
| /// <summary> | |||||
| /// Gets a collection of all the integrations this guild contains. | |||||
| /// </summary> | |||||
| /// <param name="options">The options to be used when sending the request.</param> | |||||
| /// <returns> | |||||
| /// A task that represents the asynchronous get operation. The task result contains a read-only collection of | |||||
| /// integrations the guild can has. | |||||
| /// </returns> | |||||
| Task<IReadOnlyCollection<IIntegration>> GetIntegrationsAsync(RequestOptions options = null); | |||||
| /// <summary> | |||||
| /// Deletes an integration. | |||||
| /// </summary> | |||||
| /// <param name="id">The id for the integration.</param> | |||||
| /// <param name="options">The options to be used when sending the request.</param> | |||||
| /// <returns> | |||||
| /// A task that represents the asynchronous removal operation. | |||||
| /// </returns> | |||||
| Task DeleteIntegrationAsync(ulong id, RequestOptions options = null); | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets a collection of all invites in this guild. | /// Gets a collection of all invites in this guild. | ||||
| @@ -1,18 +0,0 @@ | |||||
| using System.Diagnostics; | |||||
| namespace Discord | |||||
| { | |||||
| [DebuggerDisplay("{DebuggerDisplay,nq}")] | |||||
| public struct IntegrationAccount | |||||
| { | |||||
| /// <summary> Gets the ID of the account. </summary> | |||||
| /// <returns> A <see cref="string"/> unique identifier of this integration account. </returns> | |||||
| public string Id { get; } | |||||
| /// <summary> Gets the name of the account. </summary> | |||||
| /// <returns> A string containing the name of this integration account. </returns> | |||||
| public string Name { get; private set; } | |||||
| public override string ToString() => Name; | |||||
| private string DebuggerDisplay => $"{Name} ({Id})"; | |||||
| } | |||||
| } | |||||
| @@ -3,15 +3,16 @@ using System; | |||||
| namespace Discord | namespace Discord | ||||
| { | { | ||||
| /// <summary> | /// <summary> | ||||
| /// Holds information for a guild integration feature. | |||||
| /// Holds information for an integration feature. | |||||
| /// Nullable fields not provided for Discord bot integrations, but are for Twitch etc. | |||||
| /// </summary> | /// </summary> | ||||
| public interface IGuildIntegration | |||||
| public interface IIntegration | |||||
| { | { | ||||
| /// <summary> | /// <summary> | ||||
| /// Gets the integration ID. | /// Gets the integration ID. | ||||
| /// </summary> | /// </summary> | ||||
| /// <returns> | /// <returns> | ||||
| /// An <see cref="UInt64"/> representing the unique identifier value of this integration. | |||||
| /// A <see cref="ulong"/> representing the unique identifier value of this integration. | |||||
| /// </returns> | /// </returns> | ||||
| ulong Id { get; } | ulong Id { get; } | ||||
| /// <summary> | /// <summary> | ||||
| @@ -45,30 +46,52 @@ namespace Discord | |||||
| /// <returns> | /// <returns> | ||||
| /// <c>true</c> if this integration is syncing; otherwise <c>false</c>. | /// <c>true</c> if this integration is syncing; otherwise <c>false</c>. | ||||
| /// </returns> | /// </returns> | ||||
| bool IsSyncing { get; } | |||||
| bool? IsSyncing { get; } | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets the ID that this integration uses for "subscribers". | /// Gets the ID that this integration uses for "subscribers". | ||||
| /// </summary> | /// </summary> | ||||
| ulong ExpireBehavior { get; } | |||||
| ulong? RoleId { get; } | |||||
| /// <summary> | |||||
| /// Gets whether emoticons should be synced for this integration (twitch only currently). | |||||
| /// </summary> | |||||
| bool? HasEnabledEmoticons { get; } | |||||
| /// <summary> | |||||
| /// Gets the behavior of expiring subscribers. | |||||
| /// </summary> | |||||
| IntegrationExpireBehavior? ExpireBehavior { get; } | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets the grace period before expiring "subscribers". | /// Gets the grace period before expiring "subscribers". | ||||
| /// </summary> | /// </summary> | ||||
| ulong ExpireGracePeriod { get; } | |||||
| int? ExpireGracePeriod { get; } | |||||
| /// <summary> | |||||
| /// Gets the user for this integration. | |||||
| /// </summary> | |||||
| IUser User { get; } | |||||
| /// <summary> | |||||
| /// Gets integration account information. | |||||
| /// </summary> | |||||
| IIntegrationAccount Account { get; } | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets when this integration was last synced. | /// Gets when this integration was last synced. | ||||
| /// </summary> | /// </summary> | ||||
| /// <returns> | /// <returns> | ||||
| /// A <see cref="DateTimeOffset"/> containing a date and time of day when the integration was last synced. | /// A <see cref="DateTimeOffset"/> containing a date and time of day when the integration was last synced. | ||||
| /// </returns> | /// </returns> | ||||
| DateTimeOffset SyncedAt { get; } | |||||
| DateTimeOffset? SyncedAt { get; } | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets integration account information. | |||||
| /// Gets how many subscribers this integration has. | |||||
| /// </summary> | /// </summary> | ||||
| IntegrationAccount Account { get; } | |||||
| int? SubscriberCount { get; } | |||||
| /// <summary> | |||||
| /// Gets whether this integration been revoked. | |||||
| /// </summary> | |||||
| bool? IsRevoked { get; } | |||||
| /// <summary> | |||||
| /// Gets the bot/OAuth2 application for a discord integration. | |||||
| /// </summary> | |||||
| IIntegrationApplication Application { get; } | |||||
| IGuild Guild { get; } | IGuild Guild { get; } | ||||
| ulong GuildId { get; } | ulong GuildId { get; } | ||||
| ulong RoleId { get; } | |||||
| IUser User { get; } | |||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,23 @@ | |||||
| namespace Discord | |||||
| { | |||||
| /// <summary> | |||||
| /// Provides the account information for an <see cref="IIntegration" />. | |||||
| /// </summary> | |||||
| public interface IIntegrationAccount | |||||
| { | |||||
| /// <summary> | |||||
| /// Gets the ID of the account. | |||||
| /// </summary> | |||||
| /// <returns> | |||||
| /// A <see cref="string"/> unique identifier of this integration account. | |||||
| /// </returns> | |||||
| string Id { get; } | |||||
| /// <summary> | |||||
| /// Gets the name of the account. | |||||
| /// </summary> | |||||
| /// <returns> | |||||
| /// A string containing the name of this integration account. | |||||
| /// </returns> | |||||
| string Name { get; } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,33 @@ | |||||
| namespace Discord | |||||
| { | |||||
| /// <summary> | |||||
| /// Provides the bot/OAuth2 application for an <see cref="IIntegration" />. | |||||
| /// </summary> | |||||
| public interface IIntegrationApplication | |||||
| { | |||||
| /// <summary> | |||||
| /// Gets the id of the app. | |||||
| /// </summary> | |||||
| ulong Id { get; } | |||||
| /// <summary> | |||||
| /// Gets the name of the app. | |||||
| /// </summary> | |||||
| string Name { get; } | |||||
| /// <summary> | |||||
| /// Gets the icon hash of the app. | |||||
| /// </summary> | |||||
| string Icon { get; } | |||||
| /// <summary> | |||||
| /// Gets the description of the app. | |||||
| /// </summary> | |||||
| string Description { get; } | |||||
| /// <summary> | |||||
| /// Gets the summary of the app. | |||||
| /// </summary> | |||||
| string Summary { get; } | |||||
| /// <summary> | |||||
| /// Gets the bot associated with this application. | |||||
| /// </summary> | |||||
| IUser Bot { get; } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,17 @@ | |||||
| namespace Discord | |||||
| { | |||||
| /// <summary> | |||||
| /// The behavior of expiring subscribers for an <see cref="IIntegration" />. | |||||
| /// </summary> | |||||
| public enum IntegrationExpireBehavior | |||||
| { | |||||
| /// <summary> | |||||
| /// Removes a role from an expired subscriber. | |||||
| /// </summary> | |||||
| RemoveRole = 0, | |||||
| /// <summary> | |||||
| /// Kicks an expired subscriber from the guild. | |||||
| /// </summary> | |||||
| Kick = 1 | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,17 @@ | |||||
| namespace Discord | |||||
| { | |||||
| /// <summary> | |||||
| /// The visibility of the connected account. | |||||
| /// </summary> | |||||
| public enum ConnectionVisibility | |||||
| { | |||||
| /// <summary> | |||||
| /// Invisible to everyone except the user themselves. | |||||
| /// </summary> | |||||
| None = 0, | |||||
| /// <summary> | |||||
| /// Visible to everyone. | |||||
| /// </summary> | |||||
| Everyone = 1 | |||||
| } | |||||
| } | |||||
| @@ -4,24 +4,53 @@ namespace Discord | |||||
| { | { | ||||
| public interface IConnection | public interface IConnection | ||||
| { | { | ||||
| /// <summary> Gets the ID of the connection account. </summary> | |||||
| /// <returns> A <see cref="string"/> representing the unique identifier value of this connection. </returns> | |||||
| /// <summary> | |||||
| /// Gets the ID of the connection account. | |||||
| /// </summary> | |||||
| /// <returns> | |||||
| /// A <see cref="string"/> representing the unique identifier value of this connection. | |||||
| /// </returns> | |||||
| string Id { get; } | string Id { get; } | ||||
| /// <summary> Gets the service of the connection (twitch, youtube). </summary> | |||||
| /// <returns> A string containing the name of this type of connection. </returns> | |||||
| string Type { get; } | |||||
| /// <summary> Gets the username of the connection account. </summary> | |||||
| /// <returns> A string containing the name of this connection. </returns> | |||||
| /// <summary> | |||||
| /// Gets the username of the connection account. | |||||
| /// </summary> | |||||
| /// <returns> | |||||
| /// A string containing the name of this connection. | |||||
| /// </returns> | |||||
| string Name { get; } | string Name { get; } | ||||
| /// <summary> Gets whether the connection is revoked. </summary> | |||||
| /// <returns> A value which if true indicates that this connection has been revoked, otherwise false. </returns> | |||||
| bool IsRevoked { get; } | |||||
| /// <summary> Gets a <see cref="IReadOnlyCollection{T}"/> of integration IDs. </summary> | |||||
| /// <summary> | |||||
| /// Gets the service of the connection (twitch, youtube). | |||||
| /// </summary> | |||||
| /// <returns> | |||||
| /// A string containing the name of this type of connection. | |||||
| /// </returns> | |||||
| string Type { get; } | |||||
| /// <summary> | |||||
| /// Gets whether the connection is revoked. | |||||
| /// </summary> | |||||
| /// <returns> | /// <returns> | ||||
| /// An <see cref="IReadOnlyCollection{T}"/> containing <see cref="ulong"/> | |||||
| /// representations of unique identifier values of integrations. | |||||
| /// A value which if true indicates that this connection has been revoked, otherwise false. | |||||
| /// </returns> | /// </returns> | ||||
| IReadOnlyCollection<ulong> IntegrationIds { get; } | |||||
| bool? IsRevoked { get; } | |||||
| /// <summary> | |||||
| /// Gets a <see cref="IReadOnlyCollection{T}"/> of integration parials. | |||||
| /// </summary> | |||||
| IReadOnlyCollection<IIntegration> Integrations { get; } | |||||
| /// <summary> | |||||
| /// Gets whether the connection is verified. | |||||
| /// </summary> | |||||
| bool Verified { get; } | |||||
| /// <summary> | |||||
| /// Gets whether friend sync is enabled for this connection. | |||||
| /// </summary> | |||||
| bool FriendSync { get; } | |||||
| /// <summary> | |||||
| /// Gets whether activities related to this connection will be shown in presence updates. | |||||
| /// </summary> | |||||
| bool ShowActivity { get; } | |||||
| /// <summary> | |||||
| /// Visibility of this connection. | |||||
| /// </summary> | |||||
| ConnectionVisibility Visibility { get; } | |||||
| } | } | ||||
| } | } | ||||
| @@ -7,14 +7,22 @@ namespace Discord.API | |||||
| { | { | ||||
| [JsonProperty("id")] | [JsonProperty("id")] | ||||
| public string Id { get; set; } | public string Id { get; set; } | ||||
| [JsonProperty("type")] | |||||
| public string Type { get; set; } | |||||
| [JsonProperty("name")] | [JsonProperty("name")] | ||||
| public string Name { get; set; } | public string Name { get; set; } | ||||
| [JsonProperty("type")] | |||||
| public string Type { get; set; } | |||||
| [JsonProperty("revoked")] | [JsonProperty("revoked")] | ||||
| public bool Revoked { get; set; } | |||||
| public Optional<bool> Revoked { get; set; } | |||||
| [JsonProperty("integrations")] | [JsonProperty("integrations")] | ||||
| public IReadOnlyCollection<ulong> Integrations { get; set; } | |||||
| public Optional<IReadOnlyCollection<Integration>> Integrations { get; set; } | |||||
| [JsonProperty("verified")] | |||||
| public bool Verified { get; set; } | |||||
| [JsonProperty("friend_sync")] | |||||
| public bool FriendSync { get; set; } | |||||
| [JsonProperty("show_activity")] | |||||
| public bool ShowActivity { get; set; } | |||||
| [JsonProperty("visibility")] | |||||
| public ConnectionVisibility Visibility { get; set; } | |||||
| } | } | ||||
| } | } | ||||
| @@ -5,6 +5,9 @@ namespace Discord.API | |||||
| { | { | ||||
| internal class Integration | internal class Integration | ||||
| { | { | ||||
| [JsonProperty("guild_id")] | |||||
| public Optional<ulong> GuildId { get; set; } | |||||
| [JsonProperty("id")] | [JsonProperty("id")] | ||||
| public ulong Id { get; set; } | public ulong Id { get; set; } | ||||
| [JsonProperty("name")] | [JsonProperty("name")] | ||||
| @@ -14,18 +17,26 @@ namespace Discord.API | |||||
| [JsonProperty("enabled")] | [JsonProperty("enabled")] | ||||
| public bool Enabled { get; set; } | public bool Enabled { get; set; } | ||||
| [JsonProperty("syncing")] | [JsonProperty("syncing")] | ||||
| public bool Syncing { get; set; } | |||||
| public Optional<bool?> Syncing { get; set; } | |||||
| [JsonProperty("role_id")] | [JsonProperty("role_id")] | ||||
| public ulong RoleId { get; set; } | |||||
| public Optional<ulong?> RoleId { get; set; } | |||||
| [JsonProperty("enable_emoticons")] | |||||
| public Optional<bool?> EnableEmoticons { get; set; } | |||||
| [JsonProperty("expire_behavior")] | [JsonProperty("expire_behavior")] | ||||
| public ulong ExpireBehavior { get; set; } | |||||
| public Optional<IntegrationExpireBehavior> ExpireBehavior { get; set; } | |||||
| [JsonProperty("expire_grace_period")] | [JsonProperty("expire_grace_period")] | ||||
| public ulong ExpireGracePeriod { get; set; } | |||||
| public Optional<int?> ExpireGracePeriod { get; set; } | |||||
| [JsonProperty("user")] | [JsonProperty("user")] | ||||
| public User User { get; set; } | |||||
| public Optional<User> User { get; set; } | |||||
| [JsonProperty("account")] | [JsonProperty("account")] | ||||
| public IntegrationAccount Account { get; set; } | |||||
| public Optional<IntegrationAccount> Account { get; set; } | |||||
| [JsonProperty("synced_at")] | [JsonProperty("synced_at")] | ||||
| public DateTimeOffset SyncedAt { get; set; } | |||||
| public Optional<DateTimeOffset> SyncedAt { get; set; } | |||||
| [JsonProperty("subscriber_count")] | |||||
| public Optional<int?> SubscriberAccount { get; set; } | |||||
| [JsonProperty("revoked")] | |||||
| public Optional<bool?> Revoked { get; set; } | |||||
| [JsonProperty("application")] | |||||
| public Optional<IntegrationApplication> Application { get; set; } | |||||
| } | } | ||||
| } | } | ||||
| @@ -5,7 +5,7 @@ namespace Discord.API | |||||
| internal class IntegrationAccount | internal class IntegrationAccount | ||||
| { | { | ||||
| [JsonProperty("id")] | [JsonProperty("id")] | ||||
| public ulong Id { get; set; } | |||||
| public string Id { get; set; } | |||||
| [JsonProperty("name")] | [JsonProperty("name")] | ||||
| public string Name { get; set; } | public string Name { get; set; } | ||||
| } | } | ||||
| @@ -0,0 +1,20 @@ | |||||
| using Newtonsoft.Json; | |||||
| namespace Discord.API | |||||
| { | |||||
| internal class IntegrationApplication | |||||
| { | |||||
| [JsonProperty("id")] | |||||
| public ulong Id { get; set; } | |||||
| [JsonProperty("name")] | |||||
| public string Name { get; set; } | |||||
| [JsonProperty("icon")] | |||||
| public Optional<string> Icon { get; set; } | |||||
| [JsonProperty("description")] | |||||
| public string Description { get; set; } | |||||
| [JsonProperty("summary")] | |||||
| public string Summary { get; set; } | |||||
| [JsonProperty("bot")] | |||||
| public Optional<User> Bot { get; set; } | |||||
| } | |||||
| } | |||||
| @@ -49,7 +49,7 @@ namespace Discord.Rest | |||||
| public static async Task<IReadOnlyCollection<RestConnection>> GetConnectionsAsync(BaseDiscordClient client, RequestOptions options) | public static async Task<IReadOnlyCollection<RestConnection>> GetConnectionsAsync(BaseDiscordClient client, RequestOptions options) | ||||
| { | { | ||||
| var models = await client.ApiClient.GetMyConnectionsAsync(options).ConfigureAwait(false); | var models = await client.ApiClient.GetMyConnectionsAsync(options).ConfigureAwait(false); | ||||
| return models.Select(RestConnection.Create).ToImmutableArray(); | |||||
| return models.Select(model => RestConnection.Create(client, model)).ToImmutableArray(); | |||||
| } | } | ||||
| public static async Task<RestInviteMetadata> GetInviteAsync(BaseDiscordClient client, | public static async Task<RestInviteMetadata> GetInviteAsync(BaseDiscordClient client, | ||||
| @@ -1626,7 +1626,7 @@ namespace Discord.API | |||||
| #region Guild Integrations | #region Guild Integrations | ||||
| /// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception> | /// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception> | ||||
| public async Task<IReadOnlyCollection<Integration>> GetGuildIntegrationsAsync(ulong guildId, RequestOptions options = null) | |||||
| public async Task<IReadOnlyCollection<Integration>> GetIntegrationsAsync(ulong guildId, RequestOptions options = null) | |||||
| { | { | ||||
| Preconditions.NotEqual(guildId, 0, nameof(guildId)); | Preconditions.NotEqual(guildId, 0, nameof(guildId)); | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| @@ -1634,47 +1634,14 @@ namespace Discord.API | |||||
| var ids = new BucketIds(guildId: guildId); | var ids = new BucketIds(guildId: guildId); | ||||
| return await SendAsync<IReadOnlyCollection<Integration>>("GET", () => $"guilds/{guildId}/integrations", ids, options: options).ConfigureAwait(false); | return await SendAsync<IReadOnlyCollection<Integration>>("GET", () => $"guilds/{guildId}/integrations", ids, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| /// <exception cref="ArgumentException"><paramref name="guildId"/> and <paramref name="args.Id"/> must not be equal to zero.</exception> | |||||
| /// <exception cref="ArgumentNullException"><paramref name="args"/> must not be <see langword="null"/>.</exception> | |||||
| public async Task<Integration> CreateGuildIntegrationAsync(ulong guildId, CreateGuildIntegrationParams args, RequestOptions options = null) | |||||
| { | |||||
| Preconditions.NotEqual(guildId, 0, nameof(guildId)); | |||||
| Preconditions.NotNull(args, nameof(args)); | |||||
| Preconditions.NotEqual(args.Id, 0, nameof(args.Id)); | |||||
| options = RequestOptions.CreateOrClone(options); | |||||
| var ids = new BucketIds(guildId: guildId); | |||||
| return await SendAsync<Integration>("POST", () => $"guilds/{guildId}/integrations", ids, options: options).ConfigureAwait(false); | |||||
| } | |||||
| public async Task<Integration> DeleteGuildIntegrationAsync(ulong guildId, ulong integrationId, RequestOptions options = null) | |||||
| { | |||||
| Preconditions.NotEqual(guildId, 0, nameof(guildId)); | |||||
| Preconditions.NotEqual(integrationId, 0, nameof(integrationId)); | |||||
| options = RequestOptions.CreateOrClone(options); | |||||
| var ids = new BucketIds(guildId: guildId); | |||||
| return await SendAsync<Integration>("DELETE", () => $"guilds/{guildId}/integrations/{integrationId}", ids, options: options).ConfigureAwait(false); | |||||
| } | |||||
| public async Task<Integration> ModifyGuildIntegrationAsync(ulong guildId, ulong integrationId, Rest.ModifyGuildIntegrationParams args, RequestOptions options = null) | |||||
| { | |||||
| Preconditions.NotEqual(guildId, 0, nameof(guildId)); | |||||
| Preconditions.NotEqual(integrationId, 0, nameof(integrationId)); | |||||
| Preconditions.NotNull(args, nameof(args)); | |||||
| Preconditions.AtLeast(args.ExpireBehavior, 0, nameof(args.ExpireBehavior)); | |||||
| Preconditions.AtLeast(args.ExpireGracePeriod, 0, nameof(args.ExpireGracePeriod)); | |||||
| options = RequestOptions.CreateOrClone(options); | |||||
| var ids = new BucketIds(guildId: guildId); | |||||
| return await SendJsonAsync<Integration>("PATCH", () => $"guilds/{guildId}/integrations/{integrationId}", args, ids, options: options).ConfigureAwait(false); | |||||
| } | |||||
| public async Task<Integration> SyncGuildIntegrationAsync(ulong guildId, ulong integrationId, RequestOptions options = null) | |||||
| public async Task DeleteIntegrationAsync(ulong guildId, ulong integrationId, RequestOptions options = null) | |||||
| { | { | ||||
| Preconditions.NotEqual(guildId, 0, nameof(guildId)); | Preconditions.NotEqual(guildId, 0, nameof(guildId)); | ||||
| Preconditions.NotEqual(integrationId, 0, nameof(integrationId)); | Preconditions.NotEqual(integrationId, 0, nameof(integrationId)); | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| var ids = new BucketIds(guildId: guildId); | var ids = new BucketIds(guildId: guildId); | ||||
| return await SendAsync<Integration>("POST", () => $"guilds/{guildId}/integrations/{integrationId}/sync", ids, options: options).ConfigureAwait(false); | |||||
| await SendAsync("DELETE", () => $"guilds/{guildId}/integrations/{integrationId}", ids, options: options).ConfigureAwait(false); | |||||
| } | } | ||||
| #endregion | #endregion | ||||
| @@ -305,19 +305,15 @@ namespace Discord.Rest | |||||
| #endregion | #endregion | ||||
| #region Integrations | #region Integrations | ||||
| public static async Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(IGuild guild, BaseDiscordClient client, | |||||
| public static async Task<IReadOnlyCollection<RestIntegration>> GetIntegrationsAsync(IGuild guild, BaseDiscordClient client, | |||||
| RequestOptions options) | RequestOptions options) | ||||
| { | { | ||||
| var models = await client.ApiClient.GetGuildIntegrationsAsync(guild.Id, options).ConfigureAwait(false); | |||||
| return models.Select(x => RestGuildIntegration.Create(client, guild, x)).ToImmutableArray(); | |||||
| } | |||||
| public static async Task<RestGuildIntegration> CreateIntegrationAsync(IGuild guild, BaseDiscordClient client, | |||||
| ulong id, string type, RequestOptions options) | |||||
| { | |||||
| var args = new CreateGuildIntegrationParams(id, type); | |||||
| var model = await client.ApiClient.CreateGuildIntegrationAsync(guild.Id, args, options).ConfigureAwait(false); | |||||
| return RestGuildIntegration.Create(client, guild, model); | |||||
| var models = await client.ApiClient.GetIntegrationsAsync(guild.Id, options).ConfigureAwait(false); | |||||
| return models.Select(x => RestIntegration.Create(client, guild, x)).ToImmutableArray(); | |||||
| } | } | ||||
| public static async Task DeleteIntegrationAsync(IGuild guild, BaseDiscordClient client, ulong id, | |||||
| RequestOptions options) => | |||||
| await client.ApiClient.DeleteIntegrationAsync(guild.Id, id, options).ConfigureAwait(false); | |||||
| #endregion | #endregion | ||||
| #region Interactions | #region Interactions | ||||
| @@ -720,10 +720,10 @@ namespace Discord.Rest | |||||
| #endregion | #endregion | ||||
| #region Integrations | #region Integrations | ||||
| public Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(RequestOptions options = null) | |||||
| public Task<IReadOnlyCollection<RestIntegration>> GetIntegrationsAsync(RequestOptions options = null) | |||||
| => GuildHelper.GetIntegrationsAsync(this, Discord, options); | => GuildHelper.GetIntegrationsAsync(this, Discord, options); | ||||
| public Task<RestGuildIntegration> CreateIntegrationAsync(ulong id, string type, RequestOptions options = null) | |||||
| => GuildHelper.CreateIntegrationAsync(this, Discord, id, type, options); | |||||
| public Task DeleteIntegrationAsync(ulong id, RequestOptions options = null) | |||||
| => GuildHelper.DeleteIntegrationAsync(this, Discord, id, options); | |||||
| #endregion | #endregion | ||||
| #region Invites | #region Invites | ||||
| @@ -1370,11 +1370,11 @@ namespace Discord.Rest | |||||
| => await GetVoiceRegionsAsync(options).ConfigureAwait(false); | => await GetVoiceRegionsAsync(options).ConfigureAwait(false); | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| async Task<IReadOnlyCollection<IGuildIntegration>> IGuild.GetIntegrationsAsync(RequestOptions options) | |||||
| async Task<IReadOnlyCollection<IIntegration>> IGuild.GetIntegrationsAsync(RequestOptions options) | |||||
| => await GetIntegrationsAsync(options).ConfigureAwait(false); | => await GetIntegrationsAsync(options).ConfigureAwait(false); | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| async Task<IGuildIntegration> IGuild.CreateIntegrationAsync(ulong id, string type, RequestOptions options) | |||||
| => await CreateIntegrationAsync(id, type, options).ConfigureAwait(false); | |||||
| async Task IGuild.DeleteIntegrationAsync(ulong id, RequestOptions options) | |||||
| => await DeleteIntegrationAsync(id, options).ConfigureAwait(false); | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| async Task<IReadOnlyCollection<IInviteMetadata>> IGuild.GetInvitesAsync(RequestOptions options) | async Task<IReadOnlyCollection<IInviteMetadata>> IGuild.GetInvitesAsync(RequestOptions options) | ||||
| @@ -1,104 +0,0 @@ | |||||
| using System; | |||||
| using System.Diagnostics; | |||||
| using System.Threading.Tasks; | |||||
| using Model = Discord.API.Integration; | |||||
| namespace Discord.Rest | |||||
| { | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||||
| public class RestGuildIntegration : RestEntity<ulong>, IGuildIntegration | |||||
| { | |||||
| private long _syncedAtTicks; | |||||
| /// <inheritdoc /> | |||||
| public string Name { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public string Type { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public bool IsEnabled { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public bool IsSyncing { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public ulong ExpireBehavior { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public ulong ExpireGracePeriod { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public ulong GuildId { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public ulong RoleId { get; private set; } | |||||
| public RestUser User { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public IntegrationAccount Account { get; private set; } | |||||
| internal IGuild Guild { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public DateTimeOffset SyncedAt => DateTimeUtils.FromTicks(_syncedAtTicks); | |||||
| internal RestGuildIntegration(BaseDiscordClient discord, IGuild guild, ulong id) | |||||
| : base(discord, id) | |||||
| { | |||||
| Guild = guild; | |||||
| } | |||||
| internal static RestGuildIntegration Create(BaseDiscordClient discord, IGuild guild, Model model) | |||||
| { | |||||
| var entity = new RestGuildIntegration(discord, guild, model.Id); | |||||
| entity.Update(model); | |||||
| return entity; | |||||
| } | |||||
| internal void Update(Model model) | |||||
| { | |||||
| Name = model.Name; | |||||
| Type = model.Type; | |||||
| IsEnabled = model.Enabled; | |||||
| IsSyncing = model.Syncing; | |||||
| ExpireBehavior = model.ExpireBehavior; | |||||
| ExpireGracePeriod = model.ExpireGracePeriod; | |||||
| _syncedAtTicks = model.SyncedAt.UtcTicks; | |||||
| RoleId = model.RoleId; | |||||
| User = RestUser.Create(Discord, model.User); | |||||
| } | |||||
| public async Task DeleteAsync() | |||||
| { | |||||
| await Discord.ApiClient.DeleteGuildIntegrationAsync(GuildId, Id).ConfigureAwait(false); | |||||
| } | |||||
| public async Task ModifyAsync(Action<GuildIntegrationProperties> func) | |||||
| { | |||||
| if (func == null) throw new NullReferenceException(nameof(func)); | |||||
| var args = new GuildIntegrationProperties(); | |||||
| func(args); | |||||
| var apiArgs = new API.Rest.ModifyGuildIntegrationParams | |||||
| { | |||||
| EnableEmoticons = args.EnableEmoticons, | |||||
| ExpireBehavior = args.ExpireBehavior, | |||||
| ExpireGracePeriod = args.ExpireGracePeriod | |||||
| }; | |||||
| var model = await Discord.ApiClient.ModifyGuildIntegrationAsync(GuildId, Id, apiArgs).ConfigureAwait(false); | |||||
| Update(model); | |||||
| } | |||||
| public async Task SyncAsync() | |||||
| { | |||||
| await Discord.ApiClient.SyncGuildIntegrationAsync(GuildId, Id).ConfigureAwait(false); | |||||
| } | |||||
| public override string ToString() => Name; | |||||
| private string DebuggerDisplay => $"{Name} ({Id}{(IsEnabled ? ", Enabled" : "")})"; | |||||
| /// <inheritdoc /> | |||||
| IGuild IGuildIntegration.Guild | |||||
| { | |||||
| get | |||||
| { | |||||
| if (Guild != null) | |||||
| return Guild; | |||||
| throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object."); | |||||
| } | |||||
| } | |||||
| /// <inheritdoc /> | |||||
| IUser IGuildIntegration.User => User; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,102 @@ | |||||
| using System; | |||||
| using System.Diagnostics; | |||||
| using System.Threading.Tasks; | |||||
| using Model = Discord.API.Integration; | |||||
| namespace Discord.Rest | |||||
| { | |||||
| /// <summary> | |||||
| /// Represents a Rest-based implementation of <see cref="IIntegration"/>. | |||||
| /// </summary> | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||||
| public class RestIntegration : RestEntity<ulong>, IIntegration | |||||
| { | |||||
| private long? _syncedAtTicks; | |||||
| /// <inheritdoc /> | |||||
| public string Name { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public string Type { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public bool IsEnabled { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public bool? IsSyncing { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public ulong? RoleId { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public bool? HasEnabledEmoticons { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public IntegrationExpireBehavior? ExpireBehavior { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public int? ExpireGracePeriod { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| IUser IIntegration.User => User; | |||||
| /// <inheritdoc /> | |||||
| public IIntegrationAccount Account { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public DateTimeOffset? SyncedAt => DateTimeUtils.FromTicks(_syncedAtTicks); | |||||
| /// <inheritdoc /> | |||||
| public int? SubscriberCount { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public bool? IsRevoked { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public IIntegrationApplication Application { get; private set; } | |||||
| internal IGuild Guild { get; private set; } | |||||
| public RestUser User { get; private set; } | |||||
| internal RestIntegration(BaseDiscordClient discord, IGuild guild, ulong id) | |||||
| : base(discord, id) | |||||
| { | |||||
| Guild = guild; | |||||
| } | |||||
| internal static RestIntegration Create(BaseDiscordClient discord, IGuild guild, Model model) | |||||
| { | |||||
| var entity = new RestIntegration(discord, guild, model.Id); | |||||
| entity.Update(model); | |||||
| return entity; | |||||
| } | |||||
| internal void Update(Model model) | |||||
| { | |||||
| Name = model.Name; | |||||
| Type = model.Type; | |||||
| IsEnabled = model.Enabled; | |||||
| IsSyncing = model.Syncing.IsSpecified ? model.Syncing.Value : null; | |||||
| RoleId = model.RoleId.IsSpecified ? model.RoleId.Value : null; | |||||
| HasEnabledEmoticons = model.EnableEmoticons.IsSpecified ? model.EnableEmoticons.Value : null; | |||||
| ExpireBehavior = model.ExpireBehavior.IsSpecified ? model.ExpireBehavior.Value : null; | |||||
| ExpireGracePeriod = model.ExpireGracePeriod.IsSpecified ? model.ExpireGracePeriod.Value : null; | |||||
| User = model.User.IsSpecified ? RestUser.Create(Discord, model.User.Value) : null; | |||||
| Account = model.Account.IsSpecified ? RestIntegrationAccount.Create(model.Account.Value) : null; | |||||
| SubscriberCount = model.SubscriberAccount.IsSpecified ? model.SubscriberAccount.Value : null; | |||||
| IsRevoked = model.Revoked.IsSpecified ? model.Revoked.Value : null; | |||||
| Application = model.Application.IsSpecified ? RestIntegrationApplication.Create(Discord, model.Application.Value) : null; | |||||
| _syncedAtTicks = model.SyncedAt.IsSpecified ? model.SyncedAt.Value.UtcTicks : null; | |||||
| } | |||||
| public async Task DeleteAsync() | |||||
| { | |||||
| await Discord.ApiClient.DeleteIntegrationAsync(GuildId, Id).ConfigureAwait(false); | |||||
| } | |||||
| public override string ToString() => Name; | |||||
| private string DebuggerDisplay => $"{Name} ({Id}{(IsEnabled ? ", Enabled" : "")})"; | |||||
| /// <inheritdoc /> | |||||
| public ulong GuildId { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| IGuild IIntegration.Guild | |||||
| { | |||||
| get | |||||
| { | |||||
| if (Guild != null) | |||||
| return Guild; | |||||
| throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object."); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,29 @@ | |||||
| using Model = Discord.API.IntegrationAccount; | |||||
| namespace Discord.Rest | |||||
| { | |||||
| /// <summary> | |||||
| /// Represents a Rest-based implementation of <see cref="IIntegrationAccount"/>. | |||||
| /// </summary> | |||||
| public class RestIntegrationAccount : IIntegrationAccount | |||||
| { | |||||
| internal RestIntegrationAccount() { } | |||||
| public string Id { get; private set; } | |||||
| public string Name { get; private set; } | |||||
| internal static RestIntegrationAccount Create(Model model) | |||||
| { | |||||
| var entity = new RestIntegrationAccount(); | |||||
| entity.Update(model); | |||||
| return entity; | |||||
| } | |||||
| internal void Update(Model model) | |||||
| { | |||||
| model.Name = Name; | |||||
| model.Id = Id; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,39 @@ | |||||
| using Model = Discord.API.IntegrationApplication; | |||||
| namespace Discord.Rest | |||||
| { | |||||
| /// <summary> | |||||
| /// Represents a Rest-based implementation of <see cref="IIntegrationApplication"/>. | |||||
| /// </summary> | |||||
| public class RestIntegrationApplication : RestEntity<ulong>, IIntegrationApplication | |||||
| { | |||||
| public string Name { get; private set; } | |||||
| public string Icon { get; private set; } | |||||
| public string Description { get; private set; } | |||||
| public string Summary { get; private set; } | |||||
| public IUser Bot { get; private set; } | |||||
| internal RestIntegrationApplication(BaseDiscordClient discord, ulong id) | |||||
| : base(discord, id) { } | |||||
| internal static RestIntegrationApplication Create(BaseDiscordClient discord, Model model) | |||||
| { | |||||
| var entity = new RestIntegrationApplication(discord, model.Id); | |||||
| entity.Update(model); | |||||
| return entity; | |||||
| } | |||||
| internal void Update(Model model) | |||||
| { | |||||
| Name = model.Name; | |||||
| Icon = model.Icon.IsSpecified ? model.Icon.Value : null; | |||||
| Description = model.Description; | |||||
| Summary = model.Summary; | |||||
| Bot = RestUser.Create(Discord, model.Bot.Value); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,6 +1,8 @@ | |||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Collections.Immutable; | using System.Collections.Immutable; | ||||
| using System.Collections.ObjectModel; | |||||
| using System.Diagnostics; | using System.Diagnostics; | ||||
| using System.Linq; | |||||
| using Model = Discord.API.Connection; | using Model = Discord.API.Connection; | ||||
| namespace Discord.Rest | namespace Discord.Rest | ||||
| @@ -9,28 +11,49 @@ namespace Discord.Rest | |||||
| public class RestConnection : IConnection | public class RestConnection : IConnection | ||||
| { | { | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public string Id { get; } | |||||
| public string Id { get; private set; } | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public string Type { get; } | |||||
| public string Name { get; private set; } | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public string Name { get; } | |||||
| public string Type { get; private set; } | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public bool IsRevoked { get; } | |||||
| public bool? IsRevoked { get; private set; } | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public IReadOnlyCollection<ulong> IntegrationIds { get; } | |||||
| public IReadOnlyCollection<IIntegration> Integrations { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public bool Verified { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public bool FriendSync { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public bool ShowActivity { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public ConnectionVisibility Visibility { get; private set; } | |||||
| internal RestConnection(string id, string type, string name, bool isRevoked, IReadOnlyCollection<ulong> integrationIds) | |||||
| { | |||||
| Id = id; | |||||
| Type = type; | |||||
| Name = name; | |||||
| IsRevoked = isRevoked; | |||||
| internal BaseDiscordClient Discord { get; } | |||||
| IntegrationIds = integrationIds; | |||||
| internal RestConnection(BaseDiscordClient discord) { | |||||
| Discord = discord; | |||||
| } | } | ||||
| internal static RestConnection Create(Model model) | |||||
| internal static RestConnection Create(BaseDiscordClient discord, Model model) | |||||
| { | |||||
| var entity = new RestConnection(discord); | |||||
| entity.Update(model); | |||||
| return entity; | |||||
| } | |||||
| internal void Update(Model model) | |||||
| { | { | ||||
| return new RestConnection(model.Id, model.Type, model.Name, model.Revoked, model.Integrations.ToImmutableArray()); | |||||
| Id = model.Id; | |||||
| Name = model.Name; | |||||
| Type = model.Type; | |||||
| IsRevoked = model.Revoked.IsSpecified ? model.Revoked.Value : null; | |||||
| Integrations = model.Integrations.IsSpecified ?model.Integrations.Value | |||||
| .Select(intergration => RestIntegration.Create(Discord, null, intergration)).ToImmutableArray() : null; | |||||
| Verified = model.Verified; | |||||
| FriendSync = model.FriendSync; | |||||
| ShowActivity = model.ShowActivity; | |||||
| Visibility = model.Visibility; | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| @@ -40,6 +63,6 @@ namespace Discord.Rest | |||||
| /// Name of the connection. | /// Name of the connection. | ||||
| /// </returns> | /// </returns> | ||||
| public override string ToString() => Name; | public override string ToString() => Name; | ||||
| private string DebuggerDisplay => $"{Name} ({Id}, {Type}{(IsRevoked ? ", Revoked" : "")})"; | |||||
| private string DebuggerDisplay => $"{Name} ({Id}, {Type}{(IsRevoked.GetValueOrDefault() ? ", Revoked" : "")})"; | |||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,14 @@ | |||||
| using Newtonsoft.Json; | |||||
| namespace Discord.API.Gateway | |||||
| { | |||||
| internal class IntegrationDeletedEvent | |||||
| { | |||||
| [JsonProperty("id")] | |||||
| public ulong Id { get; set; } | |||||
| [JsonProperty("guild_id")] | |||||
| public ulong GuildId { get; set; } | |||||
| [JsonProperty("application_id")] | |||||
| public Optional<ulong> ApplicationID { get; set; } | |||||
| } | |||||
| } | |||||
| @@ -415,6 +415,32 @@ namespace Discord.WebSocket | |||||
| #endregion | #endregion | ||||
| #region Integrations | |||||
| /// <summary> Fired when an integration is created. </summary> | |||||
| public event Func<IIntegration, Task> IntegrationCreated | |||||
| { | |||||
| add { _integrationCreated.Add(value); } | |||||
| remove { _integrationCreated.Remove(value); } | |||||
| } | |||||
| internal readonly AsyncEvent<Func<IIntegration, Task>> _integrationCreated = new AsyncEvent<Func<IIntegration, Task>>(); | |||||
| /// <summary> Fired when an integration is updated. </summary> | |||||
| public event Func<IIntegration, Task> IntegrationUpdated | |||||
| { | |||||
| add { _integrationUpdated.Add(value); } | |||||
| remove { _integrationUpdated.Remove(value); } | |||||
| } | |||||
| internal readonly AsyncEvent<Func<IIntegration, Task>> _integrationUpdated = new AsyncEvent<Func<IIntegration, Task>>(); | |||||
| /// <summary> Fired when an integration is deleted. </summary> | |||||
| public event Func<IGuild, ulong, Optional<ulong>, Task> IntegrationDeleted | |||||
| { | |||||
| add { _integrationDeleted.Add(value); } | |||||
| remove { _integrationDeleted.Remove(value); } | |||||
| } | |||||
| internal readonly AsyncEvent<Func<IGuild, ulong, Optional<ulong>, Task>> _integrationDeleted = new AsyncEvent<Func<IGuild, ulong, Optional<ulong>, Task>>(); | |||||
| #endregion | |||||
| #region Users | #region Users | ||||
| /// <summary> Fired when a user joins a guild. </summary> | /// <summary> Fired when a user joins a guild. </summary> | ||||
| public event Func<SocketGuildUser, Task> UserJoined | public event Func<SocketGuildUser, Task> UserJoined | ||||
| @@ -2017,6 +2017,92 @@ namespace Discord.WebSocket | |||||
| break; | break; | ||||
| #endregion | #endregion | ||||
| #region Integrations | |||||
| case "INTEGRATION_CREATE": | |||||
| { | |||||
| await _gatewayLogger.DebugAsync("Received Dispatch (INTEGRATION_CREATE)").ConfigureAwait(false); | |||||
| var data = (payload as JToken).ToObject<Integration>(_serializer); | |||||
| // Integrations from Gateway should always have guild IDs specified. | |||||
| if (!data.GuildId.IsSpecified) | |||||
| return; | |||||
| var guild = State.GetGuild(data.GuildId.Value); | |||||
| if (guild != null) | |||||
| { | |||||
| if (!guild.IsSynced) | |||||
| { | |||||
| await UnsyncedGuildAsync(type, guild.Id).ConfigureAwait(false); | |||||
| return; | |||||
| } | |||||
| await TimedInvokeAsync(_integrationCreated, nameof(IntegrationCreated), RestIntegration.Create(this, guild, data)).ConfigureAwait(false); | |||||
| } | |||||
| else | |||||
| { | |||||
| await UnknownGuildAsync(type, data.GuildId.Value).ConfigureAwait(false); | |||||
| return; | |||||
| } | |||||
| } | |||||
| break; | |||||
| case "INTEGRATION_UPDATE": | |||||
| { | |||||
| await _gatewayLogger.DebugAsync("Received Dispatch (INTEGRATION_UPDATE)").ConfigureAwait(false); | |||||
| var data = (payload as JToken).ToObject<Integration>(_serializer); | |||||
| // Integrations from Gateway should always have guild IDs specified. | |||||
| if (!data.GuildId.IsSpecified) | |||||
| return; | |||||
| var guild = State.GetGuild(data.GuildId.Value); | |||||
| if (guild != null) | |||||
| { | |||||
| if (!guild.IsSynced) | |||||
| { | |||||
| await UnsyncedGuildAsync(type, guild.Id).ConfigureAwait(false); | |||||
| return; | |||||
| } | |||||
| await TimedInvokeAsync(_integrationUpdated, nameof(IntegrationUpdated), RestIntegration.Create(this, guild, data)).ConfigureAwait(false); | |||||
| } | |||||
| else | |||||
| { | |||||
| await UnknownGuildAsync(type, data.GuildId.Value).ConfigureAwait(false); | |||||
| return; | |||||
| } | |||||
| } | |||||
| break; | |||||
| case "INTEGRATION_DELETE": | |||||
| { | |||||
| await _gatewayLogger.DebugAsync("Received Dispatch (INTEGRATION_DELETE)").ConfigureAwait(false); | |||||
| var data = (payload as JToken).ToObject<IntegrationDeletedEvent>(_serializer); | |||||
| var guild = State.GetGuild(data.GuildId); | |||||
| if (guild != null) | |||||
| { | |||||
| if (!guild.IsSynced) | |||||
| { | |||||
| await UnsyncedGuildAsync(type, guild.Id).ConfigureAwait(false); | |||||
| return; | |||||
| } | |||||
| await TimedInvokeAsync(_integrationDeleted, nameof(IntegrationDeleted), guild, data.Id, data.ApplicationID).ConfigureAwait(false); | |||||
| } | |||||
| else | |||||
| { | |||||
| await UnknownGuildAsync(type, data.GuildId).ConfigureAwait(false); | |||||
| return; | |||||
| } | |||||
| } | |||||
| break; | |||||
| #endregion | |||||
| #region Users | #region Users | ||||
| case "USER_UPDATE": | case "USER_UPDATE": | ||||
| { | { | ||||
| @@ -847,10 +847,10 @@ namespace Discord.WebSocket | |||||
| #endregion | #endregion | ||||
| #region Integrations | #region Integrations | ||||
| public Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(RequestOptions options = null) | |||||
| public Task<IReadOnlyCollection<RestIntegration>> GetIntegrationsAsync(RequestOptions options = null) | |||||
| => GuildHelper.GetIntegrationsAsync(this, Discord, options); | => GuildHelper.GetIntegrationsAsync(this, Discord, options); | ||||
| public Task<RestGuildIntegration> CreateIntegrationAsync(ulong id, string type, RequestOptions options = null) | |||||
| => GuildHelper.CreateIntegrationAsync(this, Discord, id, type, options); | |||||
| public Task DeleteIntegrationAsync(ulong id, RequestOptions options = null) | |||||
| => GuildHelper.DeleteIntegrationAsync(this, Discord, id, options); | |||||
| #endregion | #endregion | ||||
| #region Interactions | #region Interactions | ||||
| @@ -1888,11 +1888,11 @@ namespace Discord.WebSocket | |||||
| => await GetVoiceRegionsAsync(options).ConfigureAwait(false); | => await GetVoiceRegionsAsync(options).ConfigureAwait(false); | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| async Task<IReadOnlyCollection<IGuildIntegration>> IGuild.GetIntegrationsAsync(RequestOptions options) | |||||
| async Task<IReadOnlyCollection<IIntegration>> IGuild.GetIntegrationsAsync(RequestOptions options) | |||||
| => await GetIntegrationsAsync(options).ConfigureAwait(false); | => await GetIntegrationsAsync(options).ConfigureAwait(false); | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| async Task<IGuildIntegration> IGuild.CreateIntegrationAsync(ulong id, string type, RequestOptions options) | |||||
| => await CreateIntegrationAsync(id, type, options).ConfigureAwait(false); | |||||
| async Task IGuild.DeleteIntegrationAsync(ulong id, RequestOptions options) | |||||
| => await DeleteIntegrationAsync(id, options).ConfigureAwait(false); | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| async Task<IReadOnlyCollection<IInviteMetadata>> IGuild.GetInvitesAsync(RequestOptions options) | async Task<IReadOnlyCollection<IInviteMetadata>> IGuild.GetInvitesAsync(RequestOptions options) | ||||