brainboxdotcc / DPP

C++ Discord API Bot Library - D++ is Lightweight and scalable for small and huge bots!
https://dpp.dev/
Apache License 2.0
1.05k stars 159 forks source link

Add an ability to tell if a message was created in a thread, or to get the thread that a message was posted in. #1099

Closed BradleyAKern closed 6 months ago

BradleyAKern commented 6 months ago

It would be nice to be able to tell if a new message in a Discord server is in a thread, or to be able to get the thread that message was posted in.

As an example, I have a Discord bot. This bot uses dpp::cluster::on_message_create() to define a callback which is run any time a new message is posted to a Discord server. Let's say this bot screens all incoming messages to the server and looks for commands it recognizes. I don't want that command to run unless the user who typed the command has certain permissions in the channel the message was posted in. Let's say the bot deletes certain messages from the channel that received the command, so I want whoever typed it to have permissions to delete messages in that channel, or else I will not accept the command. Furthermore, I want to define an extra behavior that is only run if the channel that this command was posted to is actually a Discord thread.

This is where the problem comes in: From the information we are given by the dpp::message_create_t event in the callback, there is no way to deduce whether the message created was in a thread, or to get a reference to that thread. I can look at the channel_id which was given to me by event.msg, but trying to get a reference to the thread like so yields nothing: bot.thread_get(event.msg.channel_id, [&bot, &event](const dpp::confirmation_callback_t& result) { //Code goes here });

My suspicion in the particular case of the above code is that it yields nothing because dpp::cluster::thread_get() expects the snowflake of a thread_id but I am passing in the snowflake of the channel_id the message was posted to, and I was hoping the channel_id of a thread would be identical to the thread_id of that thread. If it's not, this raises the question of how I am supposed to get the thread_id of the thread a message was posted to. Or how to tell it is in a thread at all. The dpp::message class has a way to tell if there is a thread attached to that message, but not if the message is in a thread.

It would be nice to be able to retrieve this information from the dpp::message_create_t event.

For reference, I have been primarily working out of the 10.0 release of DPP, but have been checking against the latest documentation to see if new tools have been added to cover what I'm describing.

braindigitalis commented 6 months ago

this is because a thread is just a channel with extra metadata, the IDs are interchangable

BradleyAKern commented 6 months ago

@braindigitalis I thought that might be the case, but I became unconvinced because of some inconsistent behaviors I was getting between regular text channels VS threads. If they really are interchangeable, maybe this is a bug rather than a feature request.

To give an example of one such inconsistency, here is one line of code (here, "event" is our message_create_t: const dpp::channel* commandChannel = dpp::find_channel(event.msg.channel_id); The above code gets me a valid reference to the channel that the message was posted in every time, so long as the channel is not a thread. If the channel the message was posted to is a thread, this will be a null reference.

Jaskowicz1 commented 6 months ago

@braindigitalis I thought that might be the case, but I became unconvinced because of some inconsistent behaviors I was getting between regular text channels VS threads. If they really are interchangeable, maybe this is a bug rather than a feature request.

To give an example of one such inconsistency, here is one line of code (here, "event" is our message_create_t: const dpp::channel* commandChannel = dpp::find_channel(event.msg.channel_id); The above code gets me a valid reference to the channel that the message was posted in every time, so long as the channel is not a thread. If the channel the message was posted to is a thread, this will be a null reference.

Is this tested on latest?

BradleyAKern commented 6 months ago

It's only been tested on the 10.0 release, perhaps it's time to finally upgrade.

BradleyAKern commented 6 months ago

@Jaskowicz1 Okay, I have made certain that my project is upgraded to the latest DPP release.

Unfortunately, the problem persists. Here is an example snippet of code:

bot.on_message_create([&bot](const dpp::message_create_t& event)
{
    std::cout << "New on_message_create event.\n"; 
    if (event.msg.author.id == bot.me.id)
    {
        std::cout << "Bot detected message from itself. Do nothing to avoid recursion.\n";
        return;
    }

    const dpp::channel* commandChannel = dpp::find_channel(event.msg.channel_id);
    if (commandChannel)
    {
        std::cout << "We were able to succesfully look up the channel this message says it is from.\n";
    }
    else
    {
        std::cout << "Could not find the channel this message says it is from.\n";
    }
});

I am running a Discord bot with the above on_message_create() callback. If I make a post to a text channel (like the default #general in my test server), I get the following output:

New on_message_create event.
We were able to successfully look up the channel this message says it is from.

However, if I make a post to any thread that is in this same Discord server, I get the following output:

New on_message_create event.
Could not find the channel this message says it is from.

If it looks like everything here should be working, I can change this into an issue 👍

raxyte commented 6 months ago

@BradleyAKern find_channel looks up the ID in the channel cache. Threads are not cached in DPP.

BradleyAKern commented 6 months ago

@BradleyAKern find_channel looks up the ID in the channel cache. Threads are not cached in DPP.

That makes sense! In that case, I am now trying this approach:

bot.on_message_create([&bot, &subscriptionMap](const dpp::message_create_t& event)
{
    std::cout << "New on_message_create event.\n"; 
    if (event.msg.author.id == bot.me.id)
    {
        std::cout << "Bot detected message from itself. Do nothing to avoid recursion.\n";
        return;
    }
    bot.thread_get(event.msg.channel_id, [&bot, &event](const dpp::confirmation_callback_t& result)
    {
        if (result.is_error())
        {
            std::string threadNotFoundString = "There was an error finding this thread id: " + event.msg.channel_id.str() + "\n";
            std::cout << threadNotFoundString;
        }
        else
        {
            std::string threadFoundString = "We DID find this thread ID: " + event.msg.channel_id.str() + "\n";
            std::cout << threadFoundString;
        }
    });
});

Here is the output from the above when I post in the same thread as earlier:

New on_message_create event.
We DID find this thread ID: 1036946199168

It seems like that solves the question of how to find the thread! I appreciate your help and support very much. 🙏