Polls Commands
Updated 3/28/2026
What the Poll system provides (short)
Create simple multi-choice polls (2–4 choices) or default Yes/No polls.
Optionally run timed polls that update an embed with a countdown and automatically close.
Store active polls on disk (
data/polls.json) and store poll defaults inpollSettings.json.Reacts to the poll message with letter emojis (🇦 🇧 🇨 🇩) so members vote by reacting.
Administrative controls to end, view results, delete, list, pin polls, and toggle anonymous voting.
Commands & examples
Note: the
/pollcommand is a slash command with the following subcommands implemented in the bot. See each subsection for examples and notes.
/poll create <question> [choice1 choice2 choice3 choice4] [channel:#channel] [duration:1h30m]
Purpose — Create a new poll and post it to the specified channel (or current channel). By default, if you only provide a question, the poll will be a Yes/No poll (Yes / No). You may provide up to 4 choices. Optionally supply a duration (e.g., “1h30m”, “10m20s”) to make a timed poll that auto-closes.
Key behavior
Defaults:
choice1→Yes,choice2→Noif not supplied. The command maps choices to emojis 🇦/🇧/🇨/🇩 and reacts to the created message so users can vote. A poll object is saved todata/polls.json. If a duration is provided the bot runs a countdown that edits the embed periodically and closes the poll when time expires.
Example
/poll create question:"Favorite color?" choice1:"Red" choice2:"Blue" choice3:"Green" channel:#polls duration:"10m"
/poll create question:"Do you want the event on Friday?" # creates a Yes/No poll in current channel
Notes
Duration parsing accepts patterns like
1h,30m,45sand combinations (1h30m). The implementation parses H/M/S and converts to seconds. If invalid the poll will be created without a timer.Timed polls edit the embed periodically (the implementation updates every 5 seconds for performance) and remove the poll from active storage when time expires.
/poll end <message_id>
Purpose — Manually end a poll early. Removes the poll entry from active storage so it’s no longer considered active.
Example
/poll end message_id:123456789012345678
Notes
The command deletes the poll record from
polls.jsonand acknowledges success. Ending a poll does not automatically delete the message — it simply marks the poll closed on the server side.
/poll results <message_id>
Purpose — Show the current results for an active poll.
Example
/poll results message_id:123456789012345678
Notes & limitation
The command returns an embed with the poll question and the list of choices. The current implementation does not compute and display per-choice vote counts — it provides a results summary placeholder (staff can extend this if you need precise counts). If you need vote counts immediately, you can fetch the poll message and inspect reactions, or add a short extension to the bot to aggregate reaction counts on demand.
/poll delete <message_id>
Purpose — Remove the poll entry from storage. This will forget the poll (it does not necessarily delete the message from Discord).
Example
/poll delete message_id:123456789012345678
Notes
Deleting simply removes the poll from
polls.jsonand replies with confirmation. If you want the message removed too, delete it in Discord.
/poll list
Purpose — Show all active poll IDs the bot currently tracks.
Example
/poll list
Behavior
Returns an ephemeral (staff-only) embed that lists active poll message IDs, or
No active polls.if none. Useful to find the message IDs you need forresults,end, ordelete.
/poll pin <message_id>
Purpose — Pin the poll message to the channel (makes it easier for members to find).
Example
/poll pin message_id:123456789012345678
Notes
The implementation attempts to fetch the message from the current channel and pin it. If the message is in a different channel, the pin will fail — supply the message ID from the channel where the poll was posted, or pin manually in Discord. The command responds ephemerally with success/failure.
/poll anonymous on|off
Purpose — Toggle anonymous voting as a global poll setting (affects the footer on newly created polls and how the bot records polls). This is a server-wide default stored in pollSettings.json.
Examples
/poll anonymous mode:on
/poll anonymous mode:off
Notes
The command updates
pollSettings.jsonand replies with a confirmation. When anonymous mode is enabled, poll embeds show a “🔒 Anonymous Voting” footer. This is a global default — you might want per-poll anonymous control in the future, but today this code toggles the server default.
/poll settings
Purpose — Show current poll defaults such as whether anonymous voting is on and the default duration.
Example
/poll settings
Notes
Returns an ephemeral embed that reads
pollSettings.jsonand displaysAnonymous VotingandDefault Duration. Use this to audit server defaults.
Implementation notes & details
Where data is stored — Active polls are persisted to
data/polls.jsonand defaults are stored indata/pollSettings.json. This makes polls survive restarts.Choice/emoji mapping — The bot maps up to 4 choices to emojis
🇦, 🇧, 🇨, 🇩and reacts with those on the poll message so members vote with reactions. Keep your choice count ≤ 4.Timed polls & countdown — Durations are parsed into seconds (supports
h,m,s), and if a duration is given the poll displays a countdown. The timed logic updates the embed (every ~5s) and removes the poll record when the countdown ends. The timer loop usessetIntervaland will clear itself when finished.Anonymous mode — The server-wide
anonymoussetting influences the embed footer and the poll’sanonymousflag stored with each poll. It does not automatically hide reaction voters (Discord reactions always show who reacted unless you implement a more advanced collection method). The current implementation’s “anonymous” is primarily a UI flag.
Best practices
Pick short, clear choices so the label plus the emoji fits the embed nicely. Use no more than 4 options.
Test a timed poll in a staff channel before using it with a long-running audience — the embed updates frequently and long durations may create many edits. Timed polls update the embed every 5 seconds when the remaining time is divisible by 5.
Use
/poll listto find poll message IDs forresults,end,delete, orpin. The list command is ephemeral, making it safe for staff use.Pin only from the poll’s channel or manually pin in the channel owner’s UI — the
/poll pincommand fetches from the interaction channel. If pinning a poll from another channel, do it in Discord or run the command in that channel.
Troubleshooting checklist
Poll not posting — confirm the bot has
Send Messages,Add Reactions, andEmbed Linkspermissions in the target channel. The bot reacts to the message immediately after posting, soAdd Reactionsis required.Countdown not updating — timed polls rely on an in-process interval. If the bot restarts, the stored
endsAtis persisted, but the in-memory interval would be lost; currently the code does not rehydrate running timers on restart. For long-lived production polls you may want to extend the code to re-spawn timers from storedendsAton boot. (At present the code persistsendsAt, but only the in-process interval performs the live countdown edits.)Results do not show vote counts — the
resultssubcommand currently returns the question and choices but does not calculate reaction counts. To get counts now, fetch the poll message and inspect reaction counts or update the bot to aggregate reaction counts for the poll.Pin fails —
/poll pinfetches the message from the command’s current channel; ensure you run the command in the same channel the poll message was posted or pin manually.
Quick cheatsheet
/poll create question:"Favorite map?" choice1:"Map A" choice2:"Map B" choice3:"Map C" channel:#polls duration:"10m"
/poll create question:"Do you want voice chat?" # Yes/No (defaults)
/poll end message_id:123456789012345678
/poll results message_id:123456789012345678
/poll delete message_id:123456789012345678
/poll list
/poll pin message_id:123456789012345678
/poll anonymous mode:on|off
/poll settings