discord-net / Discord.Net

An unofficial .Net wrapper for the Discord API (https://discord.com/)
https://discordnet.dev
MIT License
3.33k stars 737 forks source link

[Bug]: Unknown Channel for DiscordSocketClient.MessageReceived #2795

Open BakersDozenBagels opened 12 months ago

BakersDozenBagels commented 12 months ago

Check The Docs

Verify Issue Source

Check your intents

Description

The DiscordSocketClient.MessageReceived event is never fired. Instead, a log message similar to 13:20:41 Gateway Unknown Channel (MESSAGE_CREATE Channel=1174775482668027995). is generated.

Steps to reproduce: 1 Create a new application 2 Get the bot's token 3 Set the "Message Content" intent 3 Under OAuth2, set "Authorization Method" to "In-app Authorization" 4 Set "Scopes" to "bot" 5 Set "Bot Permissions" to "Read Messages/View Channels" 6 Invite bot to server 7 Create a new public text channel 8 Run provided program 9 Send a message in the text channel

Version

3.12.0

Working Version

No response

Logs

13:20:08 Discord     Discord.Net v3.12.0 (API v10)
13:20:08 Gateway     Connecting
13:20:10 Gateway     Connected
13:20:20 Gateway     Ready
13:20:41 Gateway     Unknown Channel (MESSAGE_CREATE Channel=1174775482668027995).

Sample

using Discord.WebSocket;
using Discord;

internal class Program
{
    public static async Task Main(string[] args)
    {
        var client = new DiscordSocketClient(new DiscordSocketConfig() { GatewayIntents = GatewayIntents.GuildMessages | GatewayIntents.MessageContent });
        client.Log += Log;
        client.MessageReceived += OnMessageReceivedAsync;

        // Insert bot's token here.
        var token = ;
        await client.LoginAsync(TokenType.Bot, token);
        await client.StartAsync();

        await Task.Delay(-1);
    }

    private static Task OnMessageReceivedAsync(SocketMessage message)
    {
        // Never called
        Console.WriteLine($"Received message.");
        return Task.CompletedTask;
    }
    private static Task Log(LogMessage msg)
    {
        Console.WriteLine(msg.ToString());
        return Task.CompletedTask;
    }
}

Packages

N/A

Environment

Misha-133 commented 12 months ago

You also need to enable GatewayIntents.Guilds intent. DNet needs one to cache channels, hence the error appears if one is not enabled.

BakersDozenBagels commented 12 months ago

Surely, then, GatewayIntents.GuildMessages should imply GatewayIntents.Guilds, unless I'm missing something about how this works.

Misha-133 commented 12 months ago

It shouldn't? These are two separate intents. Forcing one to be enabled with another one would be counterintuitive.

/// <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,

https://github.com/discord-net/Discord.Net/blob/dev/src/Discord.Net.Core/GatewayIntents.cs#L10-L11

/// <summary> This intent includes MESSAGE_CREATE, MESSAGE_UPDATE, MESSAGE_DELETE, MESSAGE_DELETE_BULK </summary>
GuildMessages = 1 << 9,

https://github.com/discord-net/Discord.Net/blob/dev/src/Discord.Net.Core/GatewayIntents.cs#L30-L31

BakersDozenBagels commented 12 months ago

What I'm trying to get at is that my application doesn't need to use anything in GatewayIntents.Guilds. It sounds like the library implicitly does to provide functionality for what I am actually using. I would appreciate at least getting a warning that the library needs to use this intent instead of a very difficult to search error message.

jtwhitehd commented 11 months ago

You also need to enable GatewayIntents.Guilds intent. DNet needs one to cache channels, hence the error appears if one is not enabled.

This resolved the issue for me. Thank you!

Serpensin commented 6 months ago

I have the same problem. Even with this example: https://github.com/discord-net/Discord.Net/blob/dev/samples/BasicBot/Program.cs

DMs work just fine.

Serpensin commented 6 months ago

I just found the solution: https://github.com/discord-net/Discord.Net/issues/2704#issuecomment-2002545384

In the *.csproj file, you need to change <InvariantGlobalization>true</InvariantGlobalization> into <InvariantGlobalization>false</InvariantGlobalization>.

rpendleton commented 6 months ago

I just found the solution: #2704 (comment)

In the *.csproj file, you need to change <InvariantGlobalization>true</InvariantGlobalization> into <InvariantGlobalization>false</InvariantGlobalization>.

Thanks for calling out globalization as a potential cause for this issue!

While I wasn't modifying the InvariantGlobalization property in my csproj file, I was using a chiseled Docker image that didn't include ICU data. This led to the same exception being thrown, and changing to a version of the chiseled image that includes ICU data fixed the exceptions.

BakersDozenBagels commented 6 months ago

Both of these problems are, in my opinion, indications of a leaky abstraction which is the actual problem I was trying to bring up originally.

To put it more completely:

The library needs the Guilds intent to do its work, which is fine, but this implementation detail leaked to the user causing errors when using an unrelated part of the API.

The library needs non-invariant globalization to do its work, which is fine, but this implementation detail leaked to the user causing errors when using an unrelated part of the API.

Neither of these is technically a bug, per se, but they both impact usability.