export const metadata = {
    title: "Polls Extension",
    description: "The Polls Extension allows users to create and vote on polls",
}

# Polls Extension

Polls (also known as surveys) are a useful tool for gathering feedback from followers and friends. The Polls Extension allows users to create and vote on polls. {{ className: 'lead' }}

## Privacy

Individual user votes on polls should **not** be visible in clients. Instead, clients should display the total number of votes for each option, and the total number of votes cast.

This is reflected in the presence of total votes as numbers and not as an array of URIs in polls.

## Extensions to Note

Note that there is no `question` field: the question should be included in the `content` of the Note itself.

<Row>
    <Col>
        <Properties name="Polls">
            <Property name="options" type="ContentFormat[]" required="true">
                Array of options for the poll. Each option is a [ContentFormat](/structures/content-format) that can contain the same properties as a Note's `content` (e.g. [Custom Emojis](/extensions/custom-emojis) or HTML hyperlinks).
            </Property>
            <Property name="votes" type="number[]" required="true" numberType="u64">
                Array of the number of votes for each option. The length of this array should match the length of the `options` array.
            </Property>
            <Property name="multiple_choice" type="boolean" required="true">
                Whether the poll allows multiple votes to be cast for different options.
            </Property>
            <Property name="expires_at" type="RFC3339" typeLink="/types#rfc3339">
                RFC 3339 timestamp of when the poll ends and no more votes can be cast. If not present, the poll does not expire.
            </Property>
        </Properties>
    </Col>

    <Col sticky>

    ```jsonc {{ title: "Example Note" }}
    {
        "id": "01902e09-0f8b-72de-8ee3-9afc0cf5eae1",
        "type": "Note", // [!code focus]
        "uri": "https://versia.social/notes/01902e09-0f8b-72de-8ee3-9afc0cf5eae1",
        "created_at": "2024-06-19T01:07:44.139Z",
        "author": "https://versia.social/users/018eb863-753f-76ff-83d6-fd590de7740a",
        "category": "microblog",
        "collections": {
            "replies": "https://versia.social/notes/01902e09-0f8b-72de-8ee3-9afc0cf5eae1/replies",
            "quotes": "https://versia.social/notes/01902e09-0f8b-72de-8ee3-9afc0cf5eae1/quotes"
        },
        "content": {
            "text/plain": {
                "content": "What is your favourite color?"
            }
        },
        "extensions": { // [!code focus:28]
            "pub.versia:polls": {
                "options": [
                    {
                        "text/plain": {
                            "content": "Red"
                        }
                    },
                    {
                        "text/plain": {
                            "content": "Blue"
                        }
                    },
                    {
                        "text/plain": {
                            "content": "Green"
                        }
                    }
                ],
                "votes": [
                    9,
                    5,
                    0
                ],
                "multiple_choice": false,
                "expires_at": "2021-01-04T00:00:00.000Z"
            }
        },
        "group": "public",
        "is_sensitive": false,
        "mentions": [],
    }

    ```
    
    </Col>
</Row>

## Vote Entity Definition

If a vote is cast to a poll that is closed, the vote should be rejected with a `422 Unprocessable Entity` error.

<Row>
    <Col>
        <Properties name="Vote">
            <Property name="type" type="string" required="true">
                Must be `pub.versia:polls/Vote`.
            </Property>
            <Property name="author" type="URI" required="true" typeLink="/types#uri">
                URI to the user who cast the vote.
            </Property>
            <Property name="poll" type="URI" required="true" typeLink="/types#uri">
                URI to the poll that the user voted on. Must link to a [Note](/entities/note) with a valid poll.
            </Property>
            <Property name="option" type="number" required="true" numberType="u64">
                Index of the option that the user voted for. This should be a valid index into the `options` array of the poll.
            </Property>
        </Properties>
    </Col>

    <Col sticky>

    ```jsonc {{ title: "Example Vote" }}
    {
        "id": "6f27bc77-58ee-4c9b-b804-8cc1c1182fa9",
        "type": "pub.versia:polls/Vote", // [!code focus]
        "uri": "https://example.com/actions/6f27bc77-58ee-4c9b-b804-8cc1c1182fa9",
        "created_at": "2021-01-01T00:00:00.000Z",
        "author": "https://example.com/users/6e0204a2-746c-4972-8602-c4f37fc63bbe", // [!code focus:3]
        "poll": "https://example.com/notes/f08a124e-fe90-439e-8be4-15a428a72a19",
        "option": 1
    }
    ```
    
    </Col>
</Row>

## Interaction Types

<Note>
    This section only applies to implementors of the [Interaction Controls Extension](/extensions/interaction-controls).
</Note>

This extension registers the following interaction types:
- `pub.versia:polls#Vote`, for voting on a Poll attached to a Note.