Reputation: 15
I've got a Problem with Discord.Net which I can't solve on my own or with Google. I'm also pretty much still a beginner, so there's that. I want to call a function which every 5 minutes does a thing and if a certain criterion is met, it should post a message to a specific channel on a specific discord server. Because it should not be triggered by a Command, I don't have the Context Variable.
public async Task MainAsync()
{
using var services = ConfigureServices();
Console.WriteLine("Ready for takeoff...");
var client = services.GetRequiredService<DiscordSocketClient>();
client.Log += Log;
services.GetRequiredService<CommandService>().Log += Log;
// Get the bot token from the Config.json file.
JObject config = Functions.GetConfig();
string token = config["token"].Value<string>();
// Log in to Discord and start the bot.
await client.LoginAsync(TokenType.Bot, token);
await client.StartAsync();
await services.GetRequiredService<CommandHandlingService>().InitializeAsync();
//This is the problematic part
var ServerID = Convert.ToUInt64(config["serverid"]?.Value<string>().ToLower());
var ChannelID = Convert.ToUInt64(config["channelid"]?.Value<string>().ToLower());
var Guild = client.GetGuild(ServerID); //The ID is filled and correct but the function always returns null
var Channel = Guild.GetTextChannel(ChannelID);
await CheckForChange(Channel);
// Run the bot forever.
await Task.Delay(-1);
}
I don't know what the problem is. It also seems that client. Guilds are empty, even tho the bot already joined two servers.
I tried giving the function CheckForChange() different parameters, like only the SocketClient, the Channel, the IDs etc. Shouldn't really make a difference (I guess) but GetGuild(ID) always returns null. Also, in the Discord Dev Portal, all Privileged Gateway Intents are enabled.
Upvotes: 0
Views: 456
Reputation: 2658
You are attempting to retrieve the guild immediately after starting the client (StartAsync
). There needs to be some delay provided for the client to connect to all available guilds before it's able to retrieve any guild or guild data. The Ready
event is fired once it's connected to all guilds. Ideally you should subscribe to the Ready
event and place your logic in there.
Note that the ready event can be triggered multiple time due to the bot needing to sometimes identify on a reconnect, so you should unsubscribe from the event within the event so you logic is only triggered once.
//make these fields so they can be accessed outside of main (in Ready)
private readonly DiscordSocketClient _client;
private readonly JObject _config;
public async Task MainAsync()
{
using var services = ConfigureServices();
Console.WriteLine("Ready for takeoff...");
_client = services.GetRequiredService<DiscordSocketClient>();
_client.Log += Log;
services.GetRequiredService<CommandService>().Log += Log;
// Get the bot token from the Config.json file.
_config = Functions.GetConfig();
string token = _config["token"].Value<string>();
// Log in to Discord and start the bot.
await _client.LoginAsync(TokenType.Bot, token);
await _client.StartAsync();
_client.Ready += Ready; //subscribe to the ready event
await services.GetRequiredService<CommandHandlingService>().InitializeAsync();
// Run the bot forever.
await Task.Delay(-1);
}
private async Task Ready()
{
_client.Ready -= Ready; //unsubscribe from the ready event
//move problematic part here (should no longer be problematic)
var ServerID = Convert.ToUInt64(_config["serverid"]?.Value<string>().ToLower());
var ChannelID = Convert.ToUInt64(_config["channelid"]?.Value<string>().ToLower());
var Guild = _client.GetGuild(ServerID);
var Channel = Guild.GetTextChannel(ChannelID);
await CheckForChange(Channel);
}
Upvotes: 1