Back to tutorials
Avraj GitHub icon
By AvrajPosted on Sun Jun 09 2024

A Guide to Discord Polls with Discord.js v14

With Discord.js v14.15, you can now create and manage polls using your Discord bot.

1. Updating to Discord.js v14.15

Firstly, it is important to ensure you are using the version of Discord.js that supports polls. You can install it by running the following command:

bash
npm install [email protected]

2. Setting up a basic discord.js project

There's a lot of ways to create a discord.js project. If you don't have an existing one, you can use this GitHub repository as a template.

3. Ensure your bot has the necessary intents

There's a new intent (GuildMessagePolls) with the above discord.js version. This will ensure we get the necessary data when fetching polls and listening to certain events.

js
// src/index.js
const { Client } = require('discord.js');
 
const client = new Client({
  intents: [
    'Guilds',
    'GuildMembers',
    'GuildMessages',
    'MessageContent',
    'GuildMessagePolls', // Add this intent
  ],
});

You can also use the GatewayIntentBits enum if you prefer that. I just find using the string names easier to read.

4. Basic command structure

For this example, we can use a slash command to trigger the creation of a poll. I'm using a slash command as the trigger here because we can just make use of interaction.channel to send back a message with the poll.

js
// src/commands/create-poll.js
const data = {
  name: 'create-poll',
  description: 'Create a poll',
};
 
function run({ interaction }) {
  // command logic here
}
 
module.exports = { data, run };

5. Sending a poll

Sending a poll is similar to sending an embed. We can use the interaction.channel.send method to send a message with the poll.

js
const { PollLayoutType } = require('discord.js');
 
function run({ interaction }) {
  interaction.channel.send({
    poll: {
      question: { text: 'What is your favorite color?' },
      answers: [
        { text: 'Red', emoji: '🟥' },
        { text: 'Green', emoji: '🟩' },
        { text: 'Blue', emoji: '🟦' },
      ],
      allowMultiselect: false,
      duration: 2,
      layoutType: PollLayoutType.Default,
    },
  });
}

Let's quickly go over each property inside the poll object:

question

This is the structure of the question you want to ask in the poll. It currently only has a text property that is required.

answers

An array of objects, each representing an answer in the poll. Each object has the text and emoji property. The text property is required, while the emoji property is optional.

allowMultiselect

A boolean value that determines whether users can select multiple answers.

duration

This is the duration of the poll in hours.

layoutType

This is the layout type of the poll. You can use the PollLayoutType enum from the discord.js library to set this value. At the moment the only option that exists is Default. Discord may add more options in the future, so you may want to keep an eye out for that.

6. Fetching and ending polls

As long as you have the channel ID and message ID of the poll, you can fetch and end the poll. In the example below, I'm fetching the poll and ending it as soon as the "ready" event is emitted.

js
client.on('ready', async () => {
  // Fetch the target channel
  const channel = await client.channels.fetch('channel-id');
 
  // Fetch the target message
  const message = await channel.messages.fetch('message-id');
 
  message.poll.end();
});

7. Fetching the poll answers

As long as you have access to the message object which contains the poll, you can access the poll answers using the message.poll.answers property.

js
client.on('ready', async () => {
  const channel = await client.channels.fetch('channel-id');
  const message = await channel.messages.fetch('message-id');
 
  // Log the poll answers
  console.log(message.poll.answers);
});

You can see the rest of the properties and methods that are available with the poll object here.

There are new events that you can listen to with the new discord.js v14.15 version:

The names are pretty self-explanatory. The messagePollVoteAdd event is emitted when a user votes in a poll, while the messagePollVoteRemove event is emitted when a user removes their vote.

Here's an example of how you can listen to the messagePollVoteAdd event:

js
client.on('messagePollVoteAdd', (pollAnswer, userId) => {
  console.log(`User with ID ${userId} voted for ${pollAnswer.text}`);
});

There's 2 arguments that are passed to the callback function. The first argument is the pollAnswer object, and the second argument is the user ID of the user who voted.

The same applies to the messagePollVoteRemove event.

js
client.on('messagePollVoteRemove', (pollAnswer, userId) => {
  console.log(
    `User with ID ${userId} removed their vote for ${pollAnswer.text}`,
  );
});