Ppoppo Docs

Poll API

A poll is sent like a message, from a template that includes a Poll component. This page is the reference; the bulk-messaging guide shows the send flow end to end.

Create a poll template

Add a Poll component (a question and a list of options) to a template via ExternalTemplateService.CreateTemplate. Fields support {{placeholders}} so one template can be reused with per-recipient vars:

TemplateComponent {
    component_type: TemplateComponentType::Poll.into(),
    question: Some("{{question}}".to_string()),
    options: vec!["{{option_1}}".into(), "{{option_2}}".into(), "{{option_3}}".into()],
    ..Default::default()
}

Send a poll

Send with ExternalMessageService.CreateSendRequest, supplying a poll_config. Because poll sends carry a poll_config, they use the generated-stub path rather than the curated SendOnly surface:

let resp = client.create_send_request(CreateSendRequestReq {
    template_id: poll_template_id.to_string(),
    recipients: vec![RecipientInput {
        ppnum: "12312345678".to_string(),
        vars: Some(build_vars(&[("question", "How satisfied are you?"),
                                ("option_1", "Very"), ("option_2", "Somewhat"), ("option_3", "Not")])),
    }],
    poll_config: Some(PollConfig { expires_in_hours: Some(48), allow_multiple: false }),
}).await?;

Get aggregated results

ExternalAppService.GetPollResults returns the totals:

FieldTypeDescription
poll_idstringPoll identifier
questionstringThe poll question
resultsrepeatedPer-option option_text, count, percentage
total_responsesint32Total responses received

List individual responses

ExternalAppService.ListPollResponses returns per-respondent rows (responder_ppnum, selected_option, responded_at), cursor-paginated: pass limit and an optional cursor, and read has_more + next_cursor to page forward.

Receive responses in real time

Poll responses also arrive as POLL_RESPONSE_RECEIVED events on the event stream, so you can process them as they happen without polling.