Reputation: 33
I'm playing around with Discord.net and I can not get this code to work...
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Discord;
using Discord.WebSocket;
namespace NetflixManager
{
class Program
{
private readonly DiscordSocketClient _client;
static void Main(string[] args)
{
new Program().MainAsync().GetAwaiter().GetResult();
}
public Program()
{
_client = new DiscordSocketClient();
_client.Log += LogAsync;
_client.Ready += ReadyAsync;
_client.MessageReceived += MessageReceivedAsync;
}
public async Task MainAsync()
{
await _client.LoginAsync(TokenType.Bot, File.ReadAllText("Token.txt"));
await _client.StartAsync();
await Task.Delay(-1);
}
private Task LogAsync(LogMessage log)
{
Console.WriteLine(log.ToString());
return Task.CompletedTask;
}
private Task ReadyAsync()
{
Console.WriteLine($"{_client.CurrentUser} is connected!");
return Task.CompletedTask;
}
private async Task MessageReceivedAsync(SocketMessage message)
{
// The bot should never respond to itself.
if (message.Author.Id == _client.CurrentUser.Id)
return;
// The bot should not reply to private messages
if (message.Channel.Name.StartsWith("@"))
return;
// The bot should not reply to bots
if (message.Author.IsBot)
return;
// The bot should not reply to a webhook
if (message.Author.IsWebhook)
return;
// Commands
if (message.Content.StartsWith("!create"))
{
if (message.Author is SocketGuildUser socketUser)
{
SocketGuild socketGuild = socketUser.Guild;
SocketRole socketRole = socketGuild.GetRole(772788208500211724);
if (socketUser.Roles.Any(r => r.Id == socketRole.Id))
{
await message.Channel.SendMessageAsync("The user '" + socketUser.Username + "' already has the role '" + socketRole.Name + "'!");
}
else
{
await socketUser.AddRoleAsync(socketRole);
await message.Channel.SendMessageAsync("Added Role '" + socketRole.Name + "' to '" + socketUser.Username + "'!");
}
}
}
if (message.Content == "!ping")
await message.Channel.SendMessageAsync("pong!");
}
}
}
I want to monitor if someone writes "!create" in any of the chats in a guild and then check if the person who sent the message has the role called "Game Notify" (Id: 772788208500211724). If the person does have the role it should output this to the channel where the original message was sent in:
"The user '<Username>' already has the role '<RoleName>'!"
If the person does not have the role it should give the person the role and output this to the channel where the original message was sent in:
"Added Role '<RoleName>' to '<Username>'!"
If I start the bot when I don't have the role and I write !create one chat it successfully gives me the role. When I execute the command a second time it gives me the role again. It does not say that I already have the role.
It also works the other way around: If I have the role when I start the bot and execute the command it correctly says that I have the role. When I now manually remove the role from me and execute the command again, it still says that I have the role.
Any ideas how to fix this?
Using Discord.net Nu-Get Packet v2.2.0
Upvotes: 3
Views: 1515
Reputation: 447
Firstly, instead of your current method, you should be using the built-in commands service. However, doing this won't fix your issue.
If you're noticing strange behaviour in relation to users, which you are, then it's most likely down to the recent Privileged Intents update. Discord.NET caches (downloads) users and uses events such as GuildUserUpdated to keep this cache up to date in the background. Without the Guild Members intent, Discord.NET can not keep its user cache up to date, causing problems such as this.
To fix the problem, enable the Guild Members privileged intent on the Bot tab of your bot's page on the Discord developer's portal.
If that doesn't work then use the nightly versions of Discord.NET and specify all of the intents that you need in the DiscordSocketConfig. To use the nightly versions, add https://www.myget.org/F/discord-net/api/v3/index.json as a package source on NuGet package manager.
Here's my DiscordSocketConfig which specifies gateway intents (only available on nightly):
new DiscordSocketConfig
{
TotalShards = _totalShards,
MessageCacheSize = 0,
ExclusiveBulkDelete = true,
AlwaysDownloadUsers = _config.FillUserCache,
LogLevel = Discord.LogSeverity.Info,
GatewayIntents =
GatewayIntents.Guilds |
GatewayIntents.GuildMembers |
GatewayIntents.GuildMessageReactions |
GatewayIntents.GuildMessages |
GatewayIntents.GuildVoiceStates
});
If you require more assistance I recommend joining the Unofficial Discord API server and asking in the #dotnet-discord-net channel.
Upvotes: 2