Open wickedmachinator opened 9 months ago
Hello! Thanks for the feedback
Could you better describe your usecase? Most likely we won't alter the library structure this way in v3 but we are rewriting the library for v4 and we could probably have your usecase addressed there
Thank you for the quick answer!
I want to catch all incoming messages from the gateway for debug purposes, better understand of the API, and other stuff.
currently this is not possible:
var client = new DiscordSocketClient(config);
client.ApiClient.ReceivedGatewayEvent += ProcessMessageAsync;
I created a solution to my problem with reflection to be able to add my own message processor to ReceivedGatewayEvent:
private void AddClientReceivedGatewayEventHandler(DiscordSocketClient client)
{
var clientType = client.GetType();
var apiClientProperty = clientType.GetProperty("ApiClient", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.DeclaredOnly);
var apiClient = apiClientProperty.GetValue(_client);
var apiClientType = apiClient.GetType();
var receivedGatewayEvent = apiClientType.GetEvent("ReceivedGatewayEvent");
var del = Delegate.CreateDelegate(receivedGatewayEvent.EventHandlerType, this, GetType().GetMethod(nameof(ProcessMessageAsync), System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic));
receivedGatewayEvent.AddEventHandler(apiClient, del);
}
private async Task ProcessMessageAsync(GatewayOpCode opCode, int? sequence, string type, object payload)
{
var payloadAsToken = payload as JToken;
Console.WriteLine(opCode.ToString() + "\t" + (sequence?.ToString() ?? "no sequence") + "\t" + type + "\t" + payloadAsToken?.ToString());
}
private enum GatewayOpCode : byte
{
.....
}
You could easily expose a simple event on DiscordSocketClient, with the following parameters (GatewayOpCode opCode, int? sequence, string type, JToken payload) or (GatewayOpCode opCode, int? sequence, string type, object payload)
and invoke this event in DiscordSocketClient.ProcessMessageAsync.
Hm Thanks for the explanation I think this is something we can include in v4
one more comment: in Discord.Net.Rest, all model classes are internal. That would be extremely helpful to change them to be public. If you are worried for "noise", then adding this will solve it: [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
example:
using Newtonsoft.Json; using Newtonsoft.Json.Linq;
namespace Discord.API
{
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public class AuditLogChange
{
[JsonProperty("key")]
public string ChangedProperty { get; set; }
[JsonProperty("new_value")]
public JToken NewValue { get; set; }
[JsonProperty("old_value")]
public JToken OldValue { get; set; }
}
}
In this case, we could add low-level gateway message processing via the endpoint requested above, serializing the JToken to the corresponding model, similarly to what DiscordSocketClient.ProcessMessageAsync
I know these are edge-cases, but I can only repeat myself, they would be very useful for advanced processing.
Thank in advance!
That would be extremely helpful to change them to be public.
Yeah, that is planned in v4. All json models will be public
Hello!
It would be awesome to be able to access DiscordSocketClient.ApiClient, or at least expose an event which gets all events currently handled by DiscordSocketClient.ProcessMessageAsync.
Because everything is internal instead of being protected, I cannot solve this issue without forking Discord.Net.
I will try to add my own ReceivedGatewayEvent eventhandler with reflection to the internal ApiClient property, but even if it works, well, you know... not the best solution. Even the GatewayOpCode enum is internal...
PS: this project is a gemstone of github, congratulations!