> ## Documentation Index
> Fetch the complete documentation index at: https://www.chapterjs.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Réactions, sondages et saisie

> Réagir aux réactions ajoutées et retirées, aux votes dans les sondages, et aux personnes qui écrivent

Quand quelqu’un ajoute une réaction à un message, les événements `reactionAdd` tournent. Ici, une réaction donne un rôle :

```ts src/lib/reaction-roles.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
// Le message auquel on réagit (clic droit dessus → Copier l’identifiant du
// message), et le rôle que donne chaque emoji.
export const ROLES_MESSAGE = '123456789012345678';
export const ROLES: Record<string, string> = { '🎮': 'Gamers', '🎨': 'Artists' };
```

```ts src/events/roles.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
import { event } from 'chapterjs';
import { ROLES, ROLES_MESSAGE } from '../lib/reaction-roles';

export default event({
  name: 'reactionAdd',
  async run({ reaction: { messageId, emoji, member }, guild }) {
    if (messageId !== ROLES_MESSAGE || !emoji.name) return;
    const name = ROLES[emoji.name];
    const role = [...guild.roles.values()].find(role => role.name === name);
    if (role) await member.addRole(role, 'Rôle par réaction');
  },
});
```

C’est tout. Comme les [événements sur les messages](https://www.chapterjs.org/fr/events/messages.md), un fichier de réactions ne tourne par défaut **que pour les personnes, sur les serveurs** : les réactions des bots, le vôtre compris, sont laissées de côté, donc `guild`, et le `channel` et le `member` de la réaction, sont toujours là.

Votre fonction reçoit la `reaction` et le serveur, `guild`. `reaction.emoji` est un [`ReactionEmoji`](https://www.chapterjs.org/fr/reference/data#reactionemoji) : `name` est le caractère d’un emoji standard (`'👍'`) ou le nom d’un emoji personnalisé, qui a aussi un `id`.

> [!NOTE]
>
> Les événements de cette page, avec tout ce qu’ils donnent, sont dans la [référence](https://www.chapterjs.org/fr/reference/events.md#reactionadd).

## Le message lui-même

Une réaction arrive avec l’identifiant de son message, pas avec le message : votre bot [ne se souvient d’aucun message](https://www.chapterjs.org/fr/memory.md), donc `message` est `null`. Pour lire ou modifier le message, demandez-le avec `fetchMessage()` :

```ts src/events/star.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
import { event } from 'chapterjs';

export default event({
  name: 'reactionAdd',
  async run({ reaction: { emoji, channel, messageId } }) {
    if (emoji.name !== '⭐') return;
    const message = await channel.fetchMessage(messageId);
    console.log(`En favori : ${message.content}`);
  },
});
```

Ne le demandez que quand vous en avez besoin, après avoir vérifié l’emoji : une requête par réaction, cela s’accumule vite.

## Réactions retirées

`reactionRemove` tourne quand quelqu’un retire sa réaction. Discord n’envoie pas le membre avec, donc `reaction.member` n’est là que quand le bot se souvient de cette personne : demandez-le avec `fetchMember()`.

```ts src/events/roles.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
import { event } from 'chapterjs';
import { ROLES, ROLES_MESSAGE } from '../lib/reaction-roles';

export default event({
  name: 'reactionRemove',
  async run({ reaction: { messageId, emoji, user }, guild }) {
    if (messageId !== ROLES_MESSAGE || !emoji.name) return;
    const name = ROLES[emoji.name];
    const role = [...guild.roles.values()].find(role => role.name === name);
    if (!role) return;
    const member = await guild.fetchMember(user);
    await member.removeRole(role, 'Rôle par réaction');
  },
});
```

`reaction.user` est toujours là : quand Discord ne donne que l’identifiant de quelqu’un que le bot ne connaît pas, il le demande une fois avant que votre fichier tourne.

`reactionClear` tourne quand toutes les réactions d’un message sont retirées d’un coup, ou toutes celles d’un emoji : il donne `reactions`, dont l’`emoji` vaut `null` dans le premier cas et cet emoji dans le second.

## Options

Les deux options des [événements sur les messages](https://www.chapterjs.org/fr/events/messages.md#où-un-fichier-écoute) fonctionnent de la même façon ici :

* `where: 'dm'` ou `'both'` pour écouter aussi en messages privés. Avec `'both'`, `guild` vaut `null` pour une réaction en privé, et un seul `if (guild)` restreint tout.
* `bots: true` (pour `reactionAdd` et `reactionRemove`) pour recevoir aussi les réactions des bots, le vôtre compris : un fichier qui réagit aux réactions pourrait sinon répondre aux siennes indéfiniment.

```ts src/events/anywhere.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
import { event } from 'chapterjs';

export default event({
  name: 'reactionAdd',
  where: 'both',
  run({ reaction: { user, emoji }, guild }) {
    console.log(`${user.username} a réagi ${emoji.name} ${guild ? `sur ${guild.name}` : 'en privé'}`);
  },
});
```

## Sondages

`pollVoteAdd` et `pollVoteRemove` tournent quand quelqu’un vote dans un sondage, ou retire son vote. Ils donnent le `vote` et le serveur ; `vote.answerId` dit pour quelle réponse : Discord les numérote dans l’ordre du sondage, `1` pour la première.

```ts src/events/log.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
import { event } from 'chapterjs';

export default event({
  name: 'pollVoteAdd',
  run({ vote: { user, answerId, channel } }) {
    console.log(`${user.username} a voté pour la réponse ${answerId} dans #${channel.name}`);
  },
});
```

Ils prennent `where` aussi. Un sondage s’envoie avec un message : voir [Envoyer des messages](https://www.chapterjs.org/fr/messages.md).

## Saisie

`typingStart` tourne quand quelqu’un commence à écrire dans un salon. Il donne `typing` et le serveur ; `typing.startedAt` dit quand.

```ts src/events/log.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
import { event } from 'chapterjs';

export default event({
  name: 'typingStart',
  run({ typing: { member, channel, startedAt } }) {
    console.log(`${member.displayName} a commencé à écrire dans #${channel.name} à ${startedAt.toLocaleTimeString()}`);
  },
});
```

Il prend `where`. Discord l’envoie souvent : gardez court ce que fait le fichier.

## Intents

Chacun de ces événements a son propre intent, pour les serveurs et pour les messages privés, et ChapterJS ne demande que ceux dont vos fichiers ont besoin : un fichier de réactions sans `where` demande les réactions des serveurs, rien d’autre. Aucun n’est privilégié.

```text theme={"theme":{"light":"github-light","dark":"vesper"}}
ℹ Intents computed from your files: GUILDS, GUILD_MESSAGE_REACTIONS
```

> [card] [Vocal](https://www.chapterjs.org/fr/events/voice.md)
>
> Qui rejoint, quitte ou change de salon vocal.

> [card] [Référence des événements](https://www.chapterjs.org/fr/reference/events.md#reactionadd)
>
> Chaque champ de chaque événement.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.