Voting

For basic voting behavior, Muxy provides a vote endpoint. Every poll has a ‘namespace’, which consists of lower-case alphanumeric characters and the hyphen ‘-’ character. All votes sent to a single namespace will be counted towards the results.

Polls expire automatically 1 day after the last vote is cast. After that point, all vote values will be removed and sending votes with the same vote ‘name’ will act as a new poll.

Sending Votes

To vote in a poll, simply use the SDK’s vote method. This method takes a poll name and a numeric value. The value must be in the range [-1000, 1000] and may be a floating point.

NOTE: Prefixing a vote name with global will create an extension wide vote more info here

Votes are unique per user; a user may only cast one vote per poll ‘name’. Repeated requests to the vote endpoint with the same poll name will change the user’s vote.

NOTE: We attempt to use the viewer’s real ID if it is known at the time the vote is cast, but will fall back to using their opaque ID. If your extension depends on absolutely correct voting behavior, you should only allow viewers who have shared their ID to vote. Otherwise, it is possible for viewers to vote multiple times by repeatedly sharing and unsharing their ID (this gives them a new opaque ID each time).

const sdk = new Muxy.SDK();
sdk.vote('poll-number-1', 1);

Getting Votes

A viewer or broadcaster can get the current status of a running poll using the getVoteData method.

const opts = new Muxy.DebuggingOptions();
opts.role('viewer');
Muxy.debug(opts);

const sdk = new Muxy.SDK();
sdk.getVoteData('poll-number-1').then(voteData => {
  console.log(voteData.sum);
});

This method returns a promise that will resolve with a json blob with information about the poll:

{
    mean: 1,
    sum: 1,
    stddev: 0,
    specific: [0, 1, 0, 0, 0, 0],
    count: 1
    vote: 1
}

The mean field is the average of all the votes cast in this poll. sum is the sum of all the values cast, and stddev is an approximate standard deviation of all the votes cast in this poll.

The specific field captures the number of votes cast with the integer values between 0 and 31, inclusive. The number of votes cast for such a value is stored in the array at the index of that value. That is, the number of votes cast for the integer value 12 can be found in specific[12].

The count field is the number of users that have voted.

The vote field is the value of the vote that the current user cast. This may not exist if the user has not cast a vote yet.

Automatic Vote Updates

While votes are being sent to the voting system, the server will periodically send update events to all viewers. These update events are sent at most every 5 seconds and so may include data for multiple “votes.”

We suggest using the vote update events to refresh your interface in real-time, but if no update events have been seen in over 5 seconds, you may wish to request the vote data directly for the most recent data.

The automatic updates can be listened to by using:

const opts = new Muxy.DebuggingOptions();
opts.role('viewer');
Muxy.debug(opts);

const sdk = new Muxy.SDK();
sdk.listen('vote_update:poll-number-1', voteData => {
  console.log(voteData.sum);
});

The voteData callback value returns the event id and a value param that has the same structure and fields as the getVoteData

{
    "id": "poll-number-1",
    "stats": {
        "stddev": 0,
        "mean": 0,
        "sum": 0,
        "specific": [0, 1, 0, 0, 0, 0],
        "count": 1,
    }
}

Extension-Wide Votes

If keys are prefixed with global the vote will be shared across all instances of the extensions.

This is useful if multiple broadcasters are co-streaming an event with an extension so that every viewers votes count for the entire event.

const opts = new Muxy.DebuggingOptions();
opts.role('viewer');
Muxy.debug(opts);

const sdk = new Muxy.SDK();
sdk.vote('global-12345', 1);

Getting Voting Logs

Voting logs are maintained per poll. Admin-tier jwts may use the getFullVoteLogs method to obtain a log of all votes cast by users. The log is returned in a JSON object in the form

{
  "result": [
    { "identifier": "U1235161", "value": 1 }
  ]
}

The objects in the result array are ordered from least recent to most recent. A given identifier may have more than one entry in the result list, if your extension allows users to change their vote by voting more than once.

const opts = new Muxy.DebuggingOptions();
opts.role('admin');
Muxy.debug(opts);

const sdk = new Muxy.SDK();
sdk.getFullVoteLogs('global-12345').then(logs => {
  const audit = logs.result;

  // ... process the audit logs ...
  const valueToUsersMapping = {};
  for (const i = 0; i < audit.length; ++i) {
    const value = audit[i].value;
    const identifier = audit[i].identifier;

    const list = valueToUsersMapping[value] || [];
    list.append(identifier);

    valueToUsersMapping[value] = list;
  }
});