A bookmark with a reaction
Createsrc/events/bookmark.ts:
src/events/bookmark.ts
reaction and the server, guild, and takes from the reaction what it needs: emoji, member, channel, messageId. emoji is the emoji of the reaction. For a standard emoji, emoji.name is the character itself ('🔖'); a custom emoji of a server has a name and an id.
Safe by default, again
The rules of the previous page hold here: by default a reaction file runs for people, in servers. The reactions of bots are left out, yours included, so the file never reacts to what it does itself;bots: true lets them in. And because the file listens in servers, guild, and the channel and member of the reaction, are always there, with no ?. to write. where: 'dm' or where: 'both' change that exactly like for messages.
Only an id for the message
Look at what the reaction holds:messageId, not a message. When someone reacts, Discord sends who reacted and with what, but not the message: it may be years old. And your bot remembers no message. So the reaction gives its id, and reaction.message is null.
Often the id is enough: the link above is built from it, without asking Discord anything. When you really need the message, ask for it: await channel.fetchMessage(messageId). Do it after the checks, never for every reaction.
reactionRemove goes further: Discord sends only the id of who removed their reaction. ChapterJS asks Discord who it is the first time, then remembers them, so reaction.user is always there; reaction.member is only there when the bot remembers that member.
Hello in voice
Createsrc/events/greeter.ts:
src/events/greeter.ts
voice.channel is a VoiceChannel you can send to. The function receives voice (who, where, and their voice state) and the server, guild.
Discord tells a bot only that “someone’s voice state changed”. ChapterJS remembers who is in which channel, compares, and gives you four events instead of one:
And the others
Polls (pollVoteAdd), typing (typingStart), bans (banAdd), the audit log, invites, emojis, scheduled events, threads and presences all work the same way: an event() with the name of the event, and what your function receives typed from that name. The Guide has a page for each family.
Points of attention
- A reaction gives an id, not a message. Build what you can from the ids; fetch the message only when you need it.
- Reactions are frequent. Like for messages, keep the check first and cheap, and
returnearly. - Presences are privileged, and heavy.
presenceUpdateneeds the Presence Intent and arrives for every change of every member: only add it when your bot really needs it. - Voice greetings can be noisy. Someone reconnecting five times gets greeted five times: keep the message short, or write it only in some channels.
Recap
reactionAdd,reactionRemove,pollVoteAdd,typingStart, the voice events and the others are declared withevent(), likememberJoin.- Reactions ignore bots and private messages by default, like messages;
botsandwherechange it. - Every event gives what it is about and
guild:reaction,vote,voice… Some only hold ids:reaction.messageIdis always there,reaction.messageisnull;useris asked to Discord once when needed. - Four voice events tell a join, a leave, a move and a change apart.
Playing in voice
Make your bot join a voice channel and play a sound.
Guide: Reactions, polls and typing
The same events, in short.