Skip to main content

Overview

These utility functions help you work with poll messages by identifying poll types and extracting structured data from the raw payload.

Check if Message is a Poll

isPollMessage(message: MessageResponse): boolean
Determines if a message is a poll message (either poll definition or vote).

Parameters

message
MessageResponse
required
The message to check

Returns

boolean
boolean
true if the message is a poll (either definition or vote), false otherwise

Example

import { isPollMessage } from "@photon-ai/advanced-imessage-kit";

sdk.on("message", (message) => {
  if (isPollMessage(message)) {
    console.log("Received a poll message!");
  }
});

Check if Message is a Poll Vote

isPollVote(message: MessageResponse): boolean
Determines if a message is a poll vote (as opposed to the original poll definition).

Parameters

message
MessageResponse
required
The message to check

Returns

boolean
boolean
true if the message is a poll vote, false otherwise

Example

import { isPollMessage, isPollVote } from "@photon-ai/advanced-imessage-kit";

sdk.on("message", (message) => {
  if (isPollMessage(message)) {
    if (isPollVote(message)) {
      console.log("Someone voted on a poll");
    } else {
      console.log("A new poll was created");
    }
  }
});

Parse Poll Definition

parsePollDefinition(message: MessageResponse): ParsedPoll | null
Extracts the poll definition from a poll message, including title, creator, and all options with their identifiers.

Parameters

message
MessageResponse
required
The poll message to parse (must be a poll definition, not a vote)

Returns

ParsedPoll | null
object | null
Parsed poll data, or null if the message is not a poll definition

Example

import { parsePollDefinition, isPollVote } from "@photon-ai/advanced-imessage-kit";

sdk.on("message", (message) => {
  if (isPollMessage(message) && !isPollVote(message)) {
    const pollData = parsePollDefinition(message);
    
    if (pollData) {
      console.log(`Poll: ${pollData.title}`);
      console.log(`By: ${pollData.creatorHandle}`);
      console.log("Options:");
      
      pollData.options.forEach((option, index) => {
        console.log(`  ${index + 1}. ${option.text}`);
        console.log(`     ID: ${option.optionIdentifier}`);
      });
    }
  }
});

Parse Poll Votes

parsePollVotes(message: MessageResponse): ParsedPollVote | null
Extracts vote information from a poll vote message.

Parameters

message
MessageResponse
required
The vote message to parse (must be a poll vote)

Returns

ParsedPollVote | null
object | null
Parsed vote data, or null if the message is not a poll vote

Example

import { parsePollVotes, isPollVote, getOptionTextById } from "@photon-ai/advanced-imessage-kit";

sdk.on("message", (message) => {
  if (isPollMessage(message) && isPollVote(message)) {
    const voteData = parsePollVotes(message);
    
    if (voteData) {
      voteData.votes.forEach((vote) => {
        const optionText = getOptionTextById(vote.voteOptionIdentifier);
        const display = optionText ? `"${optionText}"` : vote.voteOptionIdentifier;
        
        console.log(`${vote.participantHandle} voted for ${display}`);
      });
    }
  }
});

Complete Example: Poll Monitoring

import {
  iMessageSDK,
  isPollMessage,
  isPollVote,
  parsePollDefinition,
  parsePollVotes,
} from "@photon-ai/advanced-imessage-kit";

const sdk = new iMessageSDK({ serverUrl: "http://localhost:3000" });

sdk.on("ready", () => {
  console.log("Monitoring polls...");
});

sdk.on("message", (message) => {
  // Check if this is a poll-related message
  if (!isPollMessage(message)) {
    return;
  }
  
  if (isPollVote(message)) {
    // Handle vote messages
    const voteData = parsePollVotes(message);
    
    if (voteData && voteData.votes.length > 0) {
      console.log("\n[POLL VOTE]");
      
      voteData.votes.forEach((vote) => {
        console.log(`  ${vote.participantHandle} voted`);
        console.log(`  Option: ${vote.voteOptionIdentifier}`);
        
        if (vote.serverVoteTime) {
          console.log(`  Time: ${new Date(vote.serverVoteTime).toLocaleString()}`);
        }
      });
    }
  } else {
    // Handle poll definition messages
    const pollData = parsePollDefinition(message);
    
    if (pollData) {
      console.log("\n[NEW POLL]");
      console.log(`Title: ${pollData.title || "(no title)"}`);
      console.log(`Creator: ${pollData.creatorHandle}`);
      console.log(`Options (${pollData.options.length}):`);
      
      pollData.options.forEach((option, index) => {
        console.log(`  ${index + 1}. ${option.text}`);
        console.log(`     ID: ${option.optionIdentifier}`);
        console.log(`     Can edit: ${option.canBeEdited}`);
      });
    }
  }
});

await sdk.connect();

Helper Constants

import { POLL_BALLOON_BUNDLE_ID } from "@photon-ai/advanced-imessage-kit";

console.log(POLL_BALLOON_BUNDLE_ID);
// "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.messages.Polls"
The balloon bundle ID used to identify poll messages.

Notes

  • isPollMessage() returns true for both poll definitions and votes
  • isPollVote() only returns true for vote messages (checks if associatedMessageType === "4000")
  • parsePollDefinition() returns null for vote messages - only use it on poll definitions
  • parsePollVotes() returns null for poll definitions - only use it on vote messages
  • Poll data is automatically cached when parsed, making subsequent lookups faster
  • Option identifiers are required for voting and are unique to each poll option
  • All parsing functions safely handle invalid or malformed poll messages by returning null

cachePoll

Cache a parsed poll for later lookup by option ID.

Method Signature

import { cachePoll, type ParsedPoll } from "@photon-ai/advanced-imessage-kit";

cachePoll(messageGuid: string, poll: ParsedPoll): void

Parameters

messageGuid
string
required
GUID of the poll message
poll
ParsedPoll
required
The parsed poll object to cache

Example

import { parsePollDefinition, cachePoll } from "@photon-ai/advanced-imessage-kit";

const pollData = parsePollDefinition(message);
if (pollData) {
  cachePoll(message.guid, pollData);
}
Poll definitions are automatically cached when parsed. Manual caching is only needed for custom scenarios.

getCachedPoll

Retrieve a previously cached poll by message GUID.

Method Signature

import { getCachedPoll, type ParsedPoll } from "@photon-ai/advanced-imessage-kit";

getCachedPoll(messageGuid: string): ParsedPoll | null

Parameters

messageGuid
string
required
GUID of the poll message

Returns

Returns the cached ParsedPoll object, or null if not found.

Example

import { getCachedPoll } from "@photon-ai/advanced-imessage-kit";

const poll = getCachedPoll("poll-message-guid");
if (poll) {
  console.log(`Poll: ${poll.title}`);
  poll.options.forEach(opt => {
    console.log(`- ${opt.text}`);
  });
}

getPollOneLiner

Get a one-line summary of a poll message.

Method Signature

import { getPollOneLiner } from "@photon-ai/advanced-imessage-kit";

getPollOneLiner(message: MessageResponse): string | null

Parameters

message
MessageResponse
required
The poll message

Returns

Returns a one-line string summary, or null if not a poll message.

Example

import { isPollMessage, getPollOneLiner } from "@photon-ai/advanced-imessage-kit";

sdk.on("new-message", (message) => {
  if (isPollMessage(message)) {
    const summary = getPollOneLiner(message);
    console.log(summary);
    // Output: "Poll: What's for dinner? (3 options)"
  }
});

getPollSummary

Get a detailed summary of a poll message including options.

Method Signature

import { getPollSummary } from "@photon-ai/advanced-imessage-kit";

getPollSummary(message: MessageResponse): string | null

Parameters

message
MessageResponse
required
The poll message

Returns

Returns a multi-line formatted summary, or null if not a poll message.

Example

import { isPollMessage, getPollSummary } from "@photon-ai/advanced-imessage-kit";

sdk.on("new-message", (message) => {
  if (isPollMessage(message)) {
    const summary = getPollSummary(message);
    console.log(summary);
    /* Output:
    Poll: What's for dinner?
    Created by: [email protected]
    Options:
      - Pizza
      - Sushi
      - Tacos
    */
  }
});

Build docs developers (and LLMs) love