Native polls
Native poll access has its own disabled-by-default audit toggle and exact channel or thread allowlist. A parent channel never grants poll scope to a child thread. Supported targets are text, announcement, voice, stage, public-thread, private-thread, and announcement-thread channels; voice and stage access additionally requires CONNECT. Creation requires VIEW_CHANNEL, READ_MESSAGE_HISTORY, SEND_POLLS, and either SEND_MESSAGES or the thread-specific SEND_MESSAGES_IN_THREADS. A target thread must be active and unlocked. Reading a poll also depends on Discord making poll message data available to the application, including the Message Content intent where Discord requires it.
get_poll returns one exact transient poll with question and answer text, optional Unicode or custom emoji metadata supplied by Discord, non-sequential answer IDs preserved as identifiers, and an explicit lifecycle and result state. Missing results are unknown, not zero. When Discord supplies a results object, an omitted answer count is normalized to zero as Discord specifies, unfinished counts are labeled approximate, and finalized counts are labeled final. Applications cannot vote. list_poll_answer_voters is behind a second opt-in gate and returns bounded ascending user-ID pages only; it omits every profile field and persists neither IDs nor page state.
The polls toolset exposes a guided native lifecycle without adding another service or credential. review_poll_creation validates flat prompt arguments plus one strict answersJson array through the production request normalizer, makes the 24-hour and single-select defaults explicit, calls only plan_poll_creation, and stops before execution. inspect_discord_poll calls get_poll exactly once, explains aggregate result semantics, and refuses voter enumeration or repeated polling. review_poll_end calls only plan_poll_end, binds review to the complete live counts, warns that another vote invalidates the digest, and stops before irreversible execution even for a verified no-op. Rendering any of these prompts performs no Discord call, persists nothing, and grants no authority.
Creation accepts one question of at most 300 characters, two through ten logically distinct answers of at most 55 characters, an integer duration from one through 768 hours, optional multiselect, and at most one Unicode grapheme per answer. Custom emoji creation is intentionally excluded because it introduces separate availability and external-emoji permission ambiguity. Poll messages are immutable after creation. Planning binds the exact transient question, answers, settings, channel, identity, role and overwrite evidence, and a one-shot operation-key hash. Execution requires a fresh matching plan, signed interactive confirmation, write-aware host approval, a pending content-free record, and the shared interaction limiter. It sends one non-retried nonce-enforced create request, validates the complete response, and reads back the exact message.
Ending is separately gated, irreversible, and limited to an exact non-webhook poll message authored by the verified bot. A plan binds the complete poll structure, lifecycle, and live counts, so any vote before confirmation invalidates the digest and requires renewed review. Unknown future poll fields or an unknown lifecycle block the write. An already-ended poll returns a verified no-op without elicitation or a write. Otherwise execution reserves its one-shot key, records pending activity, sends one non-retried end request, and performs finalization-aware exact readback. Discord may continue final tallying asynchronously, so a successful result distinguishes pending from final rather than pretending the first response is settled.
Creation serializes per exact channel and ending serializes per exact message inside one process. The production facade additionally acquires durable exact channel claims for creation and exact channel-and-message claims for ending, so connector processes sharing the activity-state root exclude overlapping poll writes. Every reserved key remains spent after success, known failure, local record failure, or uncertainty. A transport failure, Discord 5xx response, malformed success, or failed post-write verification is uncertain and may represent a completed mutation; the connector neither retries nor compensates and retains the durable claims for operator review. Activity and receipt records contain only exact Discord IDs, plan digests, operation-key hashes, timestamps, fixed outcomes, and sanitized error categories. They never contain poll text, emoji, counts, voter identities, raw operation keys, permission evidence, or raw Discord responses. See Discord's poll resource, message endpoints, and permission flags.
Canonical source: docs/reference.md
Documentation generated for guildcontrol@0.0.0. Canonical source and edit history remain in the public repository. GuildControl is an independent project and is not affiliated with or endorsed by Discord Inc. Discord is used only to identify the platform that GuildControl connects to.