DocumentationBlogSupport
Log inSign up
Log inSign up
BlogSupport

Pollbot is Open Source

March 3, 2023
Jeff Marshall
Jeff MarshallCustomer Support Engineer
Pollbot is Open Source

We're pleased to announce that Pollbot is now available as an open-source project that developers can modify to fit their own needs.

How it works

Pollbot is used for creating polls within Webex spaces. In its current design, if the bot is added to a group space, then it will include every member of that space in any polls that are created in there. If the bot is used in a 1:1 space, then you will be given the option to provide emails for any users you want to have included in the poll. Polls are created using Buttons and Cards that allow for easier user interaction than sending text commands, though that is possible as well.

Example of creating a poll in a 1:1 space:

Image described in surrounding text.

Image described in surrounding text.

Image described in surrounding text.

Example of creating a poll in a group space:

Image described in surrounding text.

Image described in surrounding text.

Pollbot Code Examples

To use this code, you will need to create your own bot and configure its access token in the .env file. The example.env file has a list of required environment variables, both ones you will need to define as well as some universal ones. Once you've provided them in the file you can simply rename it to .env and the app will be able to read those variables when you start it.

The app requires three webhooks as well, be sure to use your bot token to create them.

  1. Resource: messages, Event: created - pointed to the root of where you're hosting the app.
    This webhook is triggered when someone sends the bot a message. The payload contains the messageId so the bot is able to retrieve the message content in order to process the command.
    Example: "targetUrl":"https://example.com"
  2. Resource: attachmentActions, Event: created - pointed to /cards.
    This webhook is triggered when someone clicks an action button the cards, such as the “Create Poll” button. The payload contains an attachmentActionsId so the data that was enter into the card and options that were select can be retrieved and processed.
    Example: "targetUrl":"https://example.com/cards"
  3. Resource: memberships, Event: all - pointed to /memberships.
    This is used to track membership changes in a space, such as the bot being added/removed to/from spaces and if there is a moderation change in a space.
    Example: "targetUrl":"https://example.com/memberships"

This is an example of how the bot currently works when a user clicks the Create Poll button on the initial card that's sent, which triggers this code:

else:
    room_type = room_details.body.get("type")
    card_json = self.application.settings['card_builder'].build_question_card(room_id, room_type, person_id)

This will then call the build_question_card function within /pollbot/src/card_builder.py to build the actual card that will ask the user for their question and the possible answers they want to accept.

def build_question_card(self, room_id, room_type, person_id):
    card_json = self.load_card(Settings.create_card)
    if room_type != "direct":
        self.add_options_card(card_json, person_id)
        card_json["body"][4]["actions"][0]["data"].update({"person_id":person_id})
    else:
        container = card_json["body"][1]["items"]
        container[0]["text"] = "**Step 1: What do you want to ask?**"
        container[1]["text"] = "Enter your question and answer choices"
        actions = card_json["body"][3]["actions"]
        actions[0]["title"] = "Next: Select Recipients"
        actions[0]["data"] = {"submit":"next", "person_id":person_id}
        actions.pop(1)
    return self.finalize_card_json(room_id, "Adaptive Card - Create Poll", card_json)

It pulls in the create_card.json file from /pollbot/src/cards and then adds additional details to it that are specific to the user so it can be stored in the database and be tracked by the creators personId. After this it returns the updated card_json variable and then finalizes the JSON based on if the bot is being use in a group or 1:1/direct space.

    def finalize_card_json(self, room_id, markdown, card_json, direct=False):
        card = {
                "markdown": markdown,
                "attachments": [
                    {
                        "contentType": "application/vnd.microsoft.card.adaptive",
                        "content": card_json
                    }
                ]
            }
        if direct:
            card.update({"toPersonId": room_id})
        else:
            card.update({"roomId": room_id})
        return card

Then the card is posted to the space here:

elif card_json != {}:
    yield self.application.settings['spark'].post_with_retries('https://webexapis.com/v1/messages', card_json)

Which uses the post_with_retries function in /pollbot/src/spark.py to handle any errors if they were to occur, such as being rate limited.

In addition to any code changes you'd like to do, there are also card files that you can modify as well. In them there is a place to define a support link, so your users can contact you should they run into any issues. Feel free to change them to fit your needs. To get started, head over to the Pollbot OpenSource repo on Github.

Blog Categories
  • Product Announcements
  • How To
  • Events
  • Developer Stories
Share This Article

Connect

Support

Developer Community

Developer Events

Contact Sales

Handy Links

Webex Ambassadors

Webex App Hub

Resources

Open Source Bot Starter Kits

Download Webex

DevNet Learning Labs

Terms of Service

Privacy Policy

Cookie Policy

Trademarks

© 2025 Cisco and/or its affiliates. All rights reserved.