Creating Polls
In Seyfert, the ability to create polls is just around the corner!
This section will show the basic creation of polls, events, and examples.
To receive poll events, new intents are required.
This is an expanded section of the configuration file.
export default config.bot({
//... other options
intents: ['GuildMessagePolls', 'DirectMessagePolls'],
});Receiving Events
There are currently 2 events for polls: messagePollVoteAdd and messagePollVoteRemove.
If you don't have the specified intents, the bot won't be able to receive poll events.
This is tied to the section on event creation.
import { createEvent } from 'seyfert';
export default createEvent({
data: { name: 'messagePollVoteAdd' },
run: (data) => {
// You can do whatever you want with the data
console.log(`The user: ${data.userId} added a vote to the poll: ${data.messageId}`);
},
});import { createEvent } from 'seyfert';
export default createEvent({
data: { name: 'messagePollVoteRemove' },
run: (data) => {
// You can do whatever you want with the data
console.log(`The user: ${data.userId} removed a vote from the poll: ${data.messageId}`);
},
});End of Event
To check when a poll ends, use the messageUpdate event.
Here's a quick example that edits the message when a poll is completed:
import { createEvent } from 'seyfert';
export default createEvent({
data: { name: 'messageUpdate' },
// This is [newMessage, oldMessage]
// But in this example, we only need newMessage
run: ([newMessage]) => {
if (newMessage.poll?.results?.isFinalized) {
console.log(`The poll with the id: ${newMessage.id} has ended`)
}
},
});Commands
Quick examples of how to create a poll and how to end it.
The data obtained from polls seems to be unstable. Consider reading the official documentation for more information.
Proceed with caution.
This goes along with the Commands section.
Let's assume you have the following directory structure:
import { AutoLoad, Declare, Command } from 'seyfert';
@Declare({
name: 'poll',
description: 'Poll command!',
})
@AutoLoad()
export default class PollCommand extends Command {}// @exactOptionalPropertyTypes: false
import {
type CommandContext,
Declare,
type OKFunction,
Options,
PollBuilder,
SubCommand,
createStringOption,
createNumberOption,
} from 'seyfert';
import { MessageFlags } from 'seyfert/lib/types';
const options = {
question: createStringOption({
description: 'Poll question.',
required: true,
}),
answers: createStringOption({
description: 'Poll answers separated by commas.',
required: true,
// This can be improved, but it's a quick example
value: ({ value }, ok: OKFunction<string[] | null>) => {
// This is for more poll options
// Example: ganyu, supremacy
const answers = value.split(', ');
if (!answers.length) return ok(null);
return ok(answers);
},
}),
// Poll duration in hours.
// Example: 1, 2, 5...
hours: createNumberOption({
description: 'The duration of the poll.'
}),
};
@Declare({
name: 'start',
description: 'Create a new poll.',
})
@Options(options)
export default class StartPoll extends SubCommand {
async run(ctx: CommandContext<typeof options>) {
const { options } = ctx;
const { question, answers } = options;
const channel = await ctx.channel('rest');
if (!channel.isTextGuild()) return;
if (!answers)
return ctx.editOrReply({
flags: MessageFlags.Ephemeral,
content: 'Answers need to be separated by commas!',
});
const hours = options.hours ?? 1;
// We have a new poll builder.
// PollBuilder makes it easier to create polls.
const newPoll = new PollBuilder()
.allowMultiselect(true)
.setQuestion({ text: question })
.setAnswers(
// Answers have a limit of 10
answers.map((text) => ({
text,
// You can also add emojis
emoji: '🐐'
}))
)
.setDuration(hours);
await channel.messages.write({
content: 'New poll started.',
poll: newPoll
});
await ctx.editOrReply({
content: `Poll started in the channel: ${channel.toString()}`,
flags: MessageFlags.Ephemeral,
});
}
}// @exactOptionalPropertyTypes: false
import {
type CommandContext,
Declare,
Options,
SubCommand,
createStringOption
} from 'seyfert';
import { MessageFlags } from 'seyfert/lib/types';
const options = {
message: createStringOption({
description: 'The message id of the poll',
required: true,
}),
};
@Declare({
name: 'end',
description: 'End a poll.',
})
@Options(options)
export default class EndPoll extends SubCommand {
async run(ctx: CommandContext<typeof options>) {
const { options } = ctx;
const { message } = options;
const channel = await ctx.channel('rest');
if (!channel.isTextGuild()) return;
const poll = await channel.messages.fetch(message);
if (!poll?.poll)
return ctx.editOrReply({
content: 'This message is not a poll.',
flags: MessageFlags.Ephemeral,
});
await poll.endPoll();
await ctx.editOrReply({
content: 'Poll ended.',
flags: MessageFlags.Ephemeral,
});
}
}