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.pull/1566/head
@@ -0,0 +1,39 @@ | |||||
using System; | |||||
namespace Discord | |||||
{ | |||||
[Flags] | |||||
public enum GatewayIntents | |||||
{ | |||||
/// <summary> 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> GUILD_MEMBER_ADD, GUILD_MEMBER_UPDATE, GUILD_MEMBER_REMOVE </summary> | |||||
GUILD_MEMBERS = 1 << 1, | |||||
/// <summary> GUILD_BAN_ADD, GUILD_BAN_REMOVE </summary> | |||||
GUILD_BANS = 1 << 2, | |||||
/// <summary> GUILD_EMOJIS_UPDATE </summary> | |||||
GUILD_EMOJIS = 1 << 3, | |||||
/// <summary> GUILD_INTEGRATIONS_UPDATE </summary> | |||||
GUILD_INTEGRATIONS = 1 << 4, | |||||
/// <summary> WEBHOOKS_UPDATE </summary> | |||||
GUILD_WEBHOOKS = 1 << 5, | |||||
/// <summary> INVITE_CREATE, INVITE_DELETE </summary> | |||||
GUILD_INVITES = 1 << 6, | |||||
/// <summary> VOICE_STATE_UPDATE </summary> | |||||
GUILD_VOICE_STATES = 1 << 7, | |||||
/// <summary> PRESENCE_UPDATE </summary> | |||||
GUILD_PRESENCES = 1 << 8, | |||||
/// <summary> MESSAGE_CREATE, MESSAGE_UPDATE, MESSAGE_DELETE, MESSAGE_DELETE_BULK </summary> | |||||
GUILD_MESSAGES = 1 << 9, | |||||
/// <summary> MESSAGE_REACTION_ADD, MESSAGE_REACTION_REMOVE, MESSAGE_REACTION_REMOVE_ALL, MESSAGE_REACTION_REMOVE_EMOJI </summary> | |||||
GUILD_MESSAGE_REACTIONS = 1 << 10, | |||||
/// <summary> TYPING_START </summary> | |||||
GUILD_MESSAGE_TYPING = 1 << 11, | |||||
/// <summary> CHANNEL_CREATE, MESSAGE_CREATE, MESSAGE_UPDATE, MESSAGE_DELETE, CHANNEL_PINS_UPDATE </summary> | |||||
DIRECT_MESSAGES = 1 << 12, | |||||
/// <summary> MESSAGE_REACTION_ADD, MESSAGE_REACTION_REMOVE, MESSAGE_REACTION_REMOVE_ALL, MESSAGE_REACTION_REMOVE_EMOJI </summary> | |||||
DIRECT_MESSAGE_REACTIONS = 1 << 13, | |||||
/// <summary> TYPING_START </summary> | |||||
DIRECT_MESSAGE_TYPING = 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 = Convert.ToInt32(gatewayIntents); | |||||
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: | ||||
@@ -124,6 +124,16 @@ namespace Discord.WebSocket | |||||
/// </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 '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> | ||||