discord-php / DiscordPHP

An API to interact with the popular messaging app Discord
MIT License
992 stars 236 forks source link

Message reactions property not filled when fetching message, cannot be freshened #1176

Closed Jamesthe1 closed 11 months ago

Jamesthe1 commented 1 year ago

Environment

Describe the bug Whenever a message is fetched, its reaction value does not contain anything but the repository exists. This repository also cannot be freshened.

To Reproduce Steps to reproduce the behavior:

$channel->messages->fetch ($msg_id)->then(function (Message $message) {
    echo count($message->reactions)."\n";
    // Prints 0; does not loop
    foreach ($message->reactions as $reaction) {
        echo 'Has reaction '.$reaction->emoji->name."\n";
    }
});
$channel->messages->fetch ($msg_id)->then(function (Message $message) {
    // Exception: "this repository cannot be freshened"
    $message->reactions->freshen()->done(function (ReactionRepository $repo) {
        echo count($repo)."\n";
        foreach ($repo as $reaction) {
            echo 'Has reaction '.$reaction->emoji->name."\n";
        }
    });
});

Expected behavior The foreach statement should print out the amount of reactions and the emoji names. Foreach has worked before on repositories.

The freshen call was an assumed attempt to get the reactions, as this is how other repositories, such as roles, retrieve missing data.

Additional context The reason for the then statement is because of a React\Async\await call, which happens because I would like to remain within the bounds of rate limits.

SQKo commented 1 year ago

Your message cache is probably outdated, please set the fresh argument to true in the $channel->messages->fetch($msg_id, true)

It is not possible to do $message->reactions->freshen() because such endpoint does not exists (Discord does not provide a Get ALL reactions), the only endpoint that do this is to fetch the message directly from the API and not from the cache.

Also please note that retrieving message reactions requires the message content intent.

About using then, we actually no longer recommends using done() due to upcoming incompatibility changes with React/Promise library, but we also don't recommend to remove them completely as you might not get errors.

So in case you do not handle promise errors (I.e. no $reject or second argument of done()`), It is recommended to do this instead:

->then(function () {
    // your code of last promise chain
})->done();

This way you can safely and easily remove the done(); later when we moved to Promise v3

Jamesthe1 commented 11 months ago

Now that I'm able to verify this, adding true to the fetch function has resolved my issue.

It's good to know this usage of done() as well; I'll have to go through my code to update this.