md-platform

poll-realtime-events.md
View raw Back to list

Poll Real-Time Socket Events

Polls broadcast three socket event types through the existing EdgeSocket connection. All messages arrive on the same WebSocket channel used for chat.

REST API

Get Poll

Fetch the current state of a poll by ID. Use this on initial load or to hydrate state after reconnecting.

GET /client/v1/polls/{id}
GET /mobile/v1/polls/{id}

Response:

{
  "id": "abc123",
  "title": "Who will win the match?",
  "image": "https://cdn.example.com/poll-banner.jpg",
  "startsAt": "2026-05-12T18:00:00Z",
  "endsAt": "2026-05-12T20:00:00Z",
  "status": 2,
  "showResults": true,
  "videoId": "vid456",
  "totalVotes": 347,
  "hasVoted": true,
  "userVotedOptionId": "opt1",
  "options": [
    { "id": "opt1", "text": "Team A", "displayOrder": 1, "voteCount": 152 },
    { "id": "opt2", "text": "Team B", "displayOrder": 2, "voteCount": 130 },
    { "id": "opt3", "text": "Draw", "displayOrder": 3, "voteCount": 65 }
  ]
}

Submit Vote

POST /client/v1/polls/{id}/vote
POST /mobile/v1/polls/{id}/vote

Body:

{
  "optionId": "opt1"
}

Socket Events

poll:started

Sent when an admin activates a poll. The client should display the poll UI.

{
  "type": "poll:started",
  "pollId": "abc123",
  "title": "Who will win the match?",
  "image": "https://cdn.example.com/poll-banner.jpg",
  "startsAt": "2026-05-12T18:00:00Z",
  "endsAt": "2026-05-12T20:00:00Z",
  "status": 2,
  "showResults": true,
  "videoId": "vid456",
  "totalVotes": 0,
  "options": [
    { "id": "opt1", "text": "Team A", "displayOrder": 1, "voteCount": 0 },
    { "id": "opt2", "text": "Team B", "displayOrder": 2, "voteCount": 0 },
    { "id": "opt3", "text": "Draw", "displayOrder": 3, "voteCount": 0 }
  ]
}

poll:vote

Sent after each vote is submitted. Use this to update vote counts in real time.

{
  "type": "poll:vote",
  "pollId": "abc123",
  "optionId": "opt1",
  "userId": "user456"
}

poll:ended

Sent when an admin ends the poll. The client should lock voting and show final results.

{
  "type": "poll:ended",
  "pollId": "abc123",
  "title": "Who will win the match?",
  "image": "https://cdn.example.com/poll-banner.jpg",
  "startsAt": "2026-05-12T18:00:00Z",
  "endsAt": "2026-05-12T20:00:00Z",
  "status": 3,
  "showResults": true,
  "videoId": "vid456",
  "totalVotes": 1204,
  "options": [
    { "id": "opt1", "text": "Team A", "displayOrder": 1, "voteCount": 540 },
    { "id": "opt2", "text": "Team B", "displayOrder": 2, "voteCount": 489 },
    { "id": "opt3", "text": "Draw", "displayOrder": 3, "voteCount": 175 }
  ]
}

Poll Status Values

Value Name Description
1 Draft Not yet visible to users
2 Active Accepting votes
3 Ended Voting closed, showing results

Implementation Flow

  1. Listen for poll:started on the socket. When received, render the poll UI with the provided options.
  2. When the user selects an option, call POST /polls/{id}/vote with { "optionId": "..." }.
  3. Listen for poll:vote messages. For each one, increment the vote count for the given optionId by 1. Only update the UI if showResults is true (from the initial poll:started data) or the current user has already voted.
  4. Listen for poll:ended. When received, disable voting and display the final results from the message payload.
  5. If the user joins late (after poll:started was already sent), call GET /polls/{id} to fetch the current poll state.