* Support Gateway Intents Allows supplying gateway intents through DiscordSocketConfig which will be passed through the IDENTIFY payload, in order to choose what gateway events you want to receive. * Fixing enum casing * Feedback * Updating comment for GuildSubscriptions * Comment updatetags/2.3.0
| @@ -0,0 +1,41 @@ | |||||
| using System; | |||||
| namespace Discord | |||||
| { | |||||
| [Flags] | |||||
| public enum GatewayIntents | |||||
| { | |||||
| /// <summary> This intent includes no events </summary> | |||||
| None = 0, | |||||
| /// <summary> This intent includes GUILD_CREATE, GUILD_UPDATE, GUILD_DELETE, GUILD_ROLE_CREATE, GUILD_ROLE_UPDATE, GUILD_ROLE_DELETE, CHANNEL_CREATE, CHANNEL_UPDATE, CHANNEL_DELETE, CHANNEL_PINS_UPDATE </summary> | |||||
| Guilds = 1 << 0, | |||||
| /// <summary> This intent includes GUILD_MEMBER_ADD, GUILD_MEMBER_UPDATE, GUILD_MEMBER_REMOVE </summary> | |||||
| GuildMembers = 1 << 1, | |||||
| /// <summary> This intent includes GUILD_BAN_ADD, GUILD_BAN_REMOVE </summary> | |||||
| GuildBans = 1 << 2, | |||||
| /// <summary> This intent includes GUILD_EMOJIS_UPDATE </summary> | |||||
| GuildEmojis = 1 << 3, | |||||
| /// <summary> This intent includes GUILD_INTEGRATIONS_UPDATE </summary> | |||||
| GuildIntegrations = 1 << 4, | |||||
| /// <summary> This intent includes WEBHOOKS_UPDATE </summary> | |||||
| GuildWebhooks = 1 << 5, | |||||
| /// <summary> This intent includes INVITE_CREATE, INVITE_DELETE </summary> | |||||
| GuildInvites = 1 << 6, | |||||
| /// <summary> This intent includes VOICE_STATE_UPDATE </summary> | |||||
| GuildVoiceStates = 1 << 7, | |||||
| /// <summary> This intent includes PRESENCE_UPDATE </summary> | |||||
| GuildPresences = 1 << 8, | |||||
| /// <summary> This intent includes MESSAGE_CREATE, MESSAGE_UPDATE, MESSAGE_DELETE, MESSAGE_DELETE_BULK </summary> | |||||
| GuildMessages = 1 << 9, | |||||
| /// <summary> This intent includes MESSAGE_REACTION_ADD, MESSAGE_REACTION_REMOVE, MESSAGE_REACTION_REMOVE_ALL, MESSAGE_REACTION_REMOVE_EMOJI </summary> | |||||
| GuildMessageReactions = 1 << 10, | |||||
| /// <summary> This intent includes TYPING_START </summary> | |||||
| GuildMessageTyping = 1 << 11, | |||||
| /// <summary> This intent includes CHANNEL_CREATE, MESSAGE_CREATE, MESSAGE_UPDATE, MESSAGE_DELETE, CHANNEL_PINS_UPDATE </summary> | |||||
| DirectMessages = 1 << 12, | |||||
| /// <summary> This intent includes MESSAGE_REACTION_ADD, MESSAGE_REACTION_REMOVE, MESSAGE_REACTION_REMOVE_ALL, MESSAGE_REACTION_REMOVE_EMOJI </summary> | |||||
| DirectMessageReactions = 1 << 13, | |||||
| /// <summary> This intent includes TYPING_START </summary> | |||||
| DirectMessageTyping = 1 << 14, | |||||
| } | |||||
| } | |||||
| @@ -1,4 +1,4 @@ | |||||
| #pragma warning disable CS1591 | |||||
| #pragma warning disable CS1591 | |||||
| using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| @@ -17,5 +17,7 @@ namespace Discord.API.Gateway | |||||
| public Optional<int[]> ShardingParams { get; set; } | public Optional<int[]> ShardingParams { get; set; } | ||||
| [JsonProperty("guild_subscriptions")] | [JsonProperty("guild_subscriptions")] | ||||
| public Optional<bool> GuildSubscriptions { get; set; } | public Optional<bool> GuildSubscriptions { get; set; } | ||||
| [JsonProperty("intents")] | |||||
| public Optional<int> Intents { get; set; } | |||||
| } | } | ||||
| } | } | ||||
| @@ -209,7 +209,7 @@ namespace Discord.API | |||||
| await _sentGatewayMessageEvent.InvokeAsync(opCode).ConfigureAwait(false); | await _sentGatewayMessageEvent.InvokeAsync(opCode).ConfigureAwait(false); | ||||
| } | } | ||||
| public async Task SendIdentifyAsync(int largeThreshold = 100, int shardID = 0, int totalShards = 1, bool guildSubscriptions = true, RequestOptions options = null) | |||||
| public async Task SendIdentifyAsync(int largeThreshold = 100, int shardID = 0, int totalShards = 1, bool guildSubscriptions = true, GatewayIntents? gatewayIntents = null, RequestOptions options = null) | |||||
| { | { | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| var props = new Dictionary<string, string> | var props = new Dictionary<string, string> | ||||
| @@ -220,12 +220,16 @@ namespace Discord.API | |||||
| { | { | ||||
| Token = AuthToken, | Token = AuthToken, | ||||
| Properties = props, | Properties = props, | ||||
| LargeThreshold = largeThreshold, | |||||
| GuildSubscriptions = guildSubscriptions | |||||
| LargeThreshold = largeThreshold | |||||
| }; | }; | ||||
| if (totalShards > 1) | if (totalShards > 1) | ||||
| msg.ShardingParams = new int[] { shardID, totalShards }; | msg.ShardingParams = new int[] { shardID, totalShards }; | ||||
| if (gatewayIntents.HasValue) | |||||
| msg.Intents = (int)gatewayIntents.Value; | |||||
| else | |||||
| msg.GuildSubscriptions = guildSubscriptions; | |||||
| await SendGatewayAsync(GatewayOpCode.Identify, msg, options: options).ConfigureAwait(false); | await SendGatewayAsync(GatewayOpCode.Identify, msg, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| public async Task SendResumeAsync(string sessionId, int lastSeq, RequestOptions options = null) | public async Task SendResumeAsync(string sessionId, int lastSeq, RequestOptions options = null) | ||||
| @@ -44,6 +44,7 @@ namespace Discord.WebSocket | |||||
| private RestApplication _applicationInfo; | private RestApplication _applicationInfo; | ||||
| private bool _isDisposed; | private bool _isDisposed; | ||||
| private bool _guildSubscriptions; | private bool _guildSubscriptions; | ||||
| private GatewayIntents? _gatewayIntents; | |||||
| /// <summary> | /// <summary> | ||||
| /// Provides access to a REST-only client with a shared state from this client. | /// Provides access to a REST-only client with a shared state from this client. | ||||
| @@ -137,6 +138,7 @@ namespace Discord.WebSocket | |||||
| Rest = new DiscordSocketRestClient(config, ApiClient); | Rest = new DiscordSocketRestClient(config, ApiClient); | ||||
| _heartbeatTimes = new ConcurrentQueue<long>(); | _heartbeatTimes = new ConcurrentQueue<long>(); | ||||
| _guildSubscriptions = config.GuildSubscriptions; | _guildSubscriptions = config.GuildSubscriptions; | ||||
| _gatewayIntents = config.GatewayIntents; | |||||
| _stateLock = new SemaphoreSlim(1, 1); | _stateLock = new SemaphoreSlim(1, 1); | ||||
| _gatewayLogger = LogManager.CreateLogger(ShardId == 0 && TotalShards == 1 ? "Gateway" : $"Shard #{ShardId}"); | _gatewayLogger = LogManager.CreateLogger(ShardId == 0 && TotalShards == 1 ? "Gateway" : $"Shard #{ShardId}"); | ||||
| @@ -242,7 +244,7 @@ namespace Discord.WebSocket | |||||
| else | else | ||||
| { | { | ||||
| await _gatewayLogger.DebugAsync("Identifying").ConfigureAwait(false); | await _gatewayLogger.DebugAsync("Identifying").ConfigureAwait(false); | ||||
| await ApiClient.SendIdentifyAsync(shardID: ShardId, totalShards: TotalShards, guildSubscriptions: _guildSubscriptions).ConfigureAwait(false); | |||||
| await ApiClient.SendIdentifyAsync(shardID: ShardId, totalShards: TotalShards, guildSubscriptions: _guildSubscriptions, gatewayIntents: _gatewayIntents).ConfigureAwait(false); | |||||
| } | } | ||||
| //Wait for READY | //Wait for READY | ||||
| @@ -517,7 +519,7 @@ namespace Discord.WebSocket | |||||
| _sessionId = null; | _sessionId = null; | ||||
| _lastSeq = 0; | _lastSeq = 0; | ||||
| await ApiClient.SendIdentifyAsync(shardID: ShardId, totalShards: TotalShards).ConfigureAwait(false); | |||||
| await ApiClient.SendIdentifyAsync(shardID: ShardId, totalShards: TotalShards, guildSubscriptions: _guildSubscriptions, gatewayIntents: _gatewayIntents).ConfigureAwait(false); | |||||
| } | } | ||||
| break; | break; | ||||
| case GatewayOpCode.Reconnect: | case GatewayOpCode.Reconnect: | ||||
| @@ -121,9 +121,20 @@ namespace Discord.WebSocket | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets or sets enabling dispatching of guild subscription events e.g. presence and typing events. | /// Gets or sets enabling dispatching of guild subscription events e.g. presence and typing events. | ||||
| /// This is not used if <see cref="GatewayIntents"/> are provided. | |||||
| /// </summary> | /// </summary> | ||||
| public bool GuildSubscriptions { get; set; } = true; | public bool GuildSubscriptions { get; set; } = true; | ||||
| /// <summary> | |||||
| /// Gets or sets gateway intents to limit what events are sent from Discord. Allows for more granular control than the <see cref="GuildSubscriptions"/> property. | |||||
| /// </summary> | |||||
| /// <remarks> | |||||
| /// For more information, please see | |||||
| /// <see href="https://discord.com/developers/docs/topics/gateway#gateway-intents">GatewayIntents</see> | |||||
| /// on the official Discord API documentation. | |||||
| /// </remarks> | |||||
| public GatewayIntents? GatewayIntents { get; set; } | |||||
| /// <summary> | /// <summary> | ||||
| /// Initializes a default configuration. | /// Initializes a default configuration. | ||||
| /// </summary> | /// </summary> | ||||