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:
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.
1const { Client } = require('discord.js');23const client = new Client({4intents: [5'Guilds',6'GuildMembers',7'GuildMessages',8'MessageContent',9'GuildMessagePolls', // Add this intent10],11});
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.
1const data = {2name: 'create-poll',3description: 'Create a poll',4};56function run({ interaction }) {7// command logic here8}910module.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.
1const { PollLayoutType } = require('discord.js');23function run({ interaction }) {4interaction.channel.send({5poll: {6question: { text: 'What is your favorite color?' },7answers: [8{ text: 'Red', emoji: '🟥' },9{ text: 'Green', emoji: '🟩' },10{ text: 'Blue', emoji: '🟦' },11],12allowMultiselect: false,13duration: 2,14layoutType: PollLayoutType.Default,15},16});17}
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.
1client.on('ready', async () => {2// Fetch the target channel3const channel = await client.channels.fetch('channel-id');45// Fetch the target message6const message =7await channel.messages.fetch('message-id');89message.poll.end();10});
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.
1client.on('ready', async () => {2const channel = await client.channels.fetch('channel-id');3const message =4await channel.messages.fetch('message-id');56// Log the poll answers7console.log(message.poll.answers);8});
You can see the rest of the properties and methods that are
available with the poll
object
here.
8. New poll related events
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:
1client.on('messagePollVoteAdd', (pollAnswer, userId) => {2console.log(3`User with ID ${userId} voted for ${pollAnswer.text}`,4);5});
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.
1client.on('messagePollVoteRemove', (pollAnswer, userId) => {2console.log(3`User with ID ${userId} removed their vote for ${pollAnswer.text}`,4);5});