DiscordApi/Discord.API/DiscordClient.cs

65 lines
2.4 KiB
C#

using System.Reactive.Subjects;
using Discord.API.Rest;
using Serilog;
namespace Discord.API;
public class DiscordClient
{
private static readonly string ApiBaseUrl = "https://discord.com/api/v10"; //TODO Export version number to a separate constant
private string ApiKey;
private readonly Intents Intents;
private RestClient Rest;
private GatewayClient? Gateway;
private TimeProvider TimeProvider;
private readonly Subject<GatewayPacket> PacketStream = new Subject<GatewayPacket>();
public IObservable<GatewayPacket> PacketReceived => PacketStream;
private IDisposable? Subscription;
public DiscordClient(string api_key, Intents intents){
TimeProvider = TimeProvider.System;
this.Intents=intents;
this.ApiKey = api_key;
Rest = new RestClient(ApiBaseUrl, ApiKey);
Task.Run(ConnectGateway);
}
internal DiscordClient(string api_key, TimeProvider time_provider, HttpMessageHandler msg_handler){
this.TimeProvider=time_provider;
this.ApiKey=api_key;
Rest = new RestClient(ApiBaseUrl, ApiKey, msg_handler);
Task.Run(ConnectGateway);
}
private async Task ConnectGateway(){
RestResponse<GetGatewayResponse> resp = await Rest.GetGateway();
while(resp is not RestSuccessResponse<GetGatewayResponse>){
Log.Debug("DiscordClient: Failed to get gateway url");
if(resp is RestErrorResponse<GetGatewayResponse> error){
Log.Error("DiscordClient: Get gateway returned error: {error_msg}", error.Error.Message);
break;
}else{
Log.Information("DiscordClient: Get gateway failed: {ex}; Retrying later", (resp as RestFailResponse<GetGatewayResponse>)!.Exception?.Message);
}
await Task.Delay(TimeSpan.FromMilliseconds(2000), TimeProvider, cancellationToken: default);
resp = await Rest.GetGateway();
}
Log.Information("DiscordClient: Gateway url: {gateway_url}", resp.Value.Url);
Gateway = new GatewayClient(resp.Value.Url, ApiKey, TimeProvider, (ulong)Intents);
Subscription = Gateway.PacketReceived.Subscribe(PacketStream);
Log.Information("DiscordClient: Started gateway");
}
public async Task Close(){
if(Gateway is not null)
await Gateway.Close();
Subscription?.Dispose();
}
}