Skip to content

5. Filtered events

Exanlv edited this page Mar 27, 2023 · 2 revisions

Sometimes it may be useful to filter events coming in, such as when you're making a poll and want to listen to all incoming reactions for only one message.

For this, you can use Ragnarok\Fenrir\FilteredEventListener. The FilteredEventListener has the ability to relay filtered events from the main EventHandler (though you can use anything that implements EventEmitterInterface).

The constructor takes 5 parameters,

  1. $eventEmitter, this is the object which you'd like to filter events from. This would usually be $discord->events
  2. $event, the event you'd like to filter
  3. $filter, a Closure which serves as your filter, should return a bool or Promise<bool>
  4. $seconds, the amount of seconds the filter should be active for (optional)
  5. $maxItems, the amount of events you'd like to be emitted by the filter, this counts the amount of items that pass $filter

In the example below you can see a filtered listener is created for the MESSAGE_REACTION_ADD event. If the !createListener message receives a reaction within 20 seconds, it will announce what the reaction was in the channel. Note that this does not happen if the reaction is added to a different message.

use Ragnarok\Fenrir\Bitwise\Bitwise;
use Ragnarok\Fenrir\Constants\Events;
use Ragnarok\Fenrir\Discord;
use Ragnarok\Fenrir\Enums\Gateway\Intents;
use Ragnarok\Fenrir\FilteredEventEmitter;
use Ragnarok\Fenrir\Rest\Helpers\Channel\MessageBuilder;
use Ragnarok\Fenrir\Websocket\Events\MessageCreate;
use Ragnarok\Fenrir\Websocket\Events\MessageReactionAdd;

require './vendor/autoload.php';

$discord = (new Discord(
    'TOKEN',
))->withGateway(Bitwise::from(
    Intents::GUILD_MESSAGES,
    Intents::DIRECT_MESSAGES,
    Intents::MESSAGE_CONTENT,
    Intents::GUILD_MESSAGE_REACTIONS,
    Intents::DIRECT_MESSAGE_REACTIONS,
))->withRest();

$discord->gateway->events->on(Events::MESSAGE_CREATE, function (MessageCreate $message) use ($discord) {
    if ($message->content === '!createListener') {
        $filteredListener = new FilteredEventEmitter(
            $discord->gateway->events, // Fenrir's `EventHandler`. This can be any `EventEmitterInterface`
            Events::MESSAGE_REACTION_ADD, // The event to listen to
            fn (MessageReactionAdd $messageReactionAdd) => $messageReactionAdd->message_id === $message->id, // The filter for the event
            20, // Stops the listener automatically after 20 seconds
            1 // Only allow 1 event to go through
        );

        $filteredListener->on(Events::MESSAGE_REACTION_ADD, function (MessageReactionAdd $messageReactionAdd) use ($discord) {
            $discord->rest->channel->createMessage(
                $messageReactionAdd->channel_id,
                (new MessageBuilder())
                    ->setContent(sprintf(
                        'Reaction %s was added',
                        $messageReactionAdd->emoji->name ?? $messageReactionAdd->emoji->id
                    ))
            );
        });

        $filteredListener->start(); // Activate the filtered listener, time starts ticking from now on
    }
});

$discord->gateway->connect();

Clone this wiki locally