feature: Support Gateway Intents (#1566)
* 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 update
This commit is contained in:
41
src/Discord.Net.Core/GatewayIntents.cs
Normal file
41
src/Discord.Net.Core/GatewayIntents.cs
Normal file
@@ -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,
|
LargeThreshold = largeThreshold
|
||||||
GuildSubscriptions = guildSubscriptions
|
|
||||||
};
|
};
|
||||||
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>
|
||||||
|
|||||||
Reference in New Issue
Block a user