Skip to main content
An event is something that happens on Discord. To react to one, declare it with event() in any file of src/, and export it:
src/events/welcome.ts
That is all. chapterjs dev finds the declaration and runs your function every time someone joins your test server. Nothing to register, no list to keep up to date, and no type to write: your editor already knows that member is a GuildMember and guild a Guild. Every event gives the same two things: what it is about (member here, message, role, reaction, voice…) and the server it happened in, guild. Nothing else, plus t when your project has languages. What each event gives is listed in one table in the reference.

The name is the event

  • name is the event. It is one of the events, and your editor offers them as you type; another word is underlined, and reported with the closest event name when the file loads.
  • A declaration is one reaction. Where the file is and what it is called are yours to choose: src/events/welcome.ts, or src/welcome/welcome.ts, or src/welcome.ts, or next to the command it goes with, as the tickets template does. Declare as many as you want, in one file or several: they all run.
  • The import is the same everywhere. name is what tells event what your function receives: a member for 'memberJoin', a role for 'roleDelete'. The same line, import { event } from 'chapterjs', works in every file.

Several reactions to one event

When an event happens, every declaration of that event runs, at the same time and in no particular order. One never waits for another, and one that fails never stops the others. Use one declaration per thing your bot does: welcome, log, roles… When two steps must happen one after the other, keep them in the same function:
src/events/roles.ts
Every declaration of an event receives the same thing, and can read it but not change it: assigning to it (context.role = ...) throws, and the error is reported like any other.

What is never missing

Your function receives structures you can read and act on. In a server, what must exist is always there, with no ?. to write:
  • member.guild, role.guild, channel.guild for a channel of a server, member.highestRole;
  • guild.me (your bot as a member of the server), guild.everyoneRole;
  • message.guild, message.member and message.channel in the events about messages.
They stay there while your function runs, even if the person leaves or the channel is deleted in the meantime: your function keeps them as they were. The bot also keeps guild.me apart from what it remembers, so it is there in a server of any size. What can be null is what may really not exist: a channel without a category (channel.parent), a message that was never edited (message.editedAt), a member count Discord never sent (guild.memberCount), a deleted message the bot did not remember (message.before in messageDelete).

What was deleted

The events about something that no longer exists give the thing itself as it was:
  • roleDelete: role is always there, the bot knows every role of its servers.
  • channelDelete: channel is the channel or thread as it was.
  • guildLeave: guild is the server as it was.
  • memberLeave: user is the account of who left, always there.
src/events/goodbye.ts

The ready event

ready runs once per start, when the bot is connected and knows every server it is in. It is not an event of Discord: nothing can start it again, and saving a file in chapterjs dev never runs it a second time.
src/events/online.ts

Options

Some events take options, written next to name. Each declaration decides for itself: two reactions to the same event can have different options, and what your function receives follows them.
src/events/relay.ts
An option is true or false, or one word of a list. Your editor only offers the options of the event named, and an option that does not exist, or a wrong value, is underlined, then reported when the file loads, before the bot runs it. The events that have options are the events about messages and the reactions, polls and typing.

Intents: nothing to list

Discord only sends a bot the events it asked for, through intents. You never write them: ChapterJS works them out from the events your files declare, and tells you when it connects:
When you save a file that needs more, chapterjs dev reconnects by itself:
Three of the intents your files can need are privileged: Discord asks you to enable them yourself, in the Developer Portal. When one is missing, chapterjs dev names the files that need it and gives you the link, then waits:
The command only waits when it runs in a terminal. Started by another program, it stops with the same explanation.

When your function fails

An error in one of your functions never stops the bot, nor the other files. It is shown in your terminal with the file and the line, whether it is a bug of yours or Discord refusing what you asked:
To handle a failure yourself, use try / catch: see Errors.

In dev, only your test server

chapterjs dev runs your bot in your test server only: what happens in other servers and in private messages is ignored, and the intents that only serve private messages are not asked for. With chapterjs start, your bot hears every server it is in and private messages too.
Every event, with what your function receives, is in the reference. The types of event() are in event().

Every kind of event

Beyond members, roles, channels and the servers themselves, your files can react to:
  • Messages: sent, edited, deleted. See Messages.
  • Reactions, polls and typing: a reaction added or removed, a vote, someone writing. See Reactions, polls and typing.
  • Voice: someone joining, leaving, moving, muting or streaming. See Voice.
  • Moderation and the server: bans, the audit log, invites, emojis, scheduled events, who is in a thread, presences. See Moderation and the server.

Messages

Servers or private messages, bots or people: the events about messages and their options.

What your bot remembers

Why reading a server or a member costs nothing, and how memory stays under control.