Build It: How to Crowdsource Questions at Live Events

October 01, 2019
Written by
Angelo Stavrow
Opinions expressed by Twilio contributors are their own

Glitch Twilio SIGNAL

Angelo Stavrow from Glitch joins us on the blog today for this guest post about how Glitch surfaced live audience questions using Twilio APIs during a SIGNAL 2019 interview.

Have you ever attended a live interview and wished there was a way you could communicate your great questions to the host? And that the host would have a way to review your questions and ask them, too?

Glitch often works with partners to develop apps that help them engage in meaningful conversations with their communities, or showcase their APIs. Twilio hosted Mindy Kaling for their SIGNAL conference keynote this year, and had Glitch CEO Anil Dash interview her on stage. We wanted to find a way to create an engaging experience for the audience and for Mindy while showcasing how Twilio APIs work, so we built a tool with Twilio so you could do just that.

194 questions were asked by the audience, and Anil ended up asking Mindy about ten percent during the hour-long interview.

Here’s how we collected, managed, and shared live questions from conference event attendees and other audiences using our customizable, free app.

The plan

We decided to build an “Ask Mindy Anything”-style app that lets hosts solicit live questions from the audience, without compromising user privacy. We baked in a human curation element to control for abuse, and voilà! You have an app that lets you engage with hundreds of people.

The app presents a landing page that explains how to send in your questions for Mindy, an administrator area where incoming questions could be curated, and a presenter area that Anil would use onstage. We knew that limited time meant only a certain number of questions could be asked, so Glitch and Twilio staff would log in to the admin area, select which questions to feature, and send them to the “presenter” section of the app.

We primarily leveraged Twilio’s Programmable SMS service, but we also included a form on the landing page — some users might not have a roaming plan that includes text messages at a reasonable cost, so we wanted to ensure there was an alternate way of submitting a question.

The app

The Glitch project is a Node.js app that can be broken down into three main areas. You can view the source code in Glitch’s editor.

The front end

Going to the live app gives users instructions on how to send in questions for the keynote. It’s a straightforward HTML page, with a single-input form to send in questions. In the lead up to the keynote, the FlipDown library was used to generate a countdown.

(Developer note: a countdown clock can drum up excitement amongst users, but if you’re working on a tight deadline… maybe try to avoid looking at it.)

The form sends the submitted question to the app’s back-end server, which returns a success or error message.

A big ol' text input on the internet for submitting content to a live event can be a little… scary. Beyond being a vector for abuse, it’s possible someone accidentally submits a password or other sensitive information. We decided against displaying questions live as they came in. Instead, they’re fetched and displayed at a password-protected /admin page. On this page, a teammate can click/tap a question that they’d like to send to the interviewer.

The interviewer accesses this subset of questions at a different /curated page, which is also password-protected.

The back end

The back end of the app consists of two files: an Express server in server.js, and the methods for storing, fetching, and manipulating submitted questions in storageController.js. Let’s look at the key features of each.

server.js handles the back-and-forth between the app and your browser. It’s set up to parse incoming questions and to always use secure HTTPS connections, and then it sets up the GET and POST endpoints. GET endpoints fetch data from the server, and POST endpoints provide a place to send data.

We serve the three pages mentioned in the front end description:

  • the landing page, at /
  • the admin page, at /admin
  • the presenter page, at /curated

We also set up a /questions endpoint, which is where the admin and presenter pages GET the list of submitted questions. This endpoint is what’s password-protected on those pages.

There are also three POST endpoints for submitting data:

  • we set up /sms to listen for questions being submitted via Twilio’s Programmable SMS service
  • we set up /form to listen for questions being submitted via the form on the landing page
  • we set up /toggleSelection to listen for staff selecting (or un-selecting) a question on the admin page

storageController.js, on the other hand, is what handles the back-and-forth between server.js and the data file where the questions are stored, using three methods:

  • getQuestionList fetches the list of questions from the data file
  • addQuestion adds a question to the end of the data file
  • toggleSelection changes the selected property of a given question in the data file

So how does all this work together? When you send an SMS or use the form to submit a question, that question gets added to the end of the data file with a selected value of false. When a teammate goes to the admin page, they log in and get the list of all questions in the data file; if they tap or click on a question in the list, it toggles the selected property of that specific question.

On the other hand, when the interviewer goes to the curated page, they log in and get a subset of all the questions in the data file — specifically, they only see the questions where the selected property is true.

Integrating the Twilio API

We built the form-based functionality first so that we could test the back end independently of what the Twilio service might require. However, we also stubbed out what the /sms endpoint would look like, using Twilio’s excellent guide. The form-based approach pretty much copies this — including returning TwiML (Twilio’s extension of XML) rather than, say, JSON. Eagle-eyed readers will see that the only difference between the /sms and /form endpoints is the twilio.webhook() middleware. This validates incoming requests to make sure that incoming requests are coming from Twilio by checking them against the TWILIO_AUTH_TOKEN value in the .env file (which we get from our Twilio developer account). Then, it’s just a matter of telling Twilio where to send SMS messages.

As mentioned in Twilio’s guide, this is done by setting up webhooks (in the Twilio Cloud Console’s “Active Numbers” area, choose a phone number and look under Messaging).

Glitch app webhook settings in the console

Under “a message comes in,” we set up a webhook pointing to the /sms endpoint (using HTTP POST). And in case that fails, we set another webhook pointing to the /form endpoint (again using HTTP POST). This is why we set up the form handling logic to return TwiML. Our webpage can parse the response as XML, but Twilio can also use this to reply to an incoming text message, too. We’ve already got that endpoint open to the world via the form, so using it here as a fallback is convenient.

Wrapping up

By leveraging the Twilio Programmable SMS API, we were able to very quickly build an app that creates an exciting and engaging live experience. Working on a very short deadline meant that we had to make some design tradeoffs to reduce complexity, but the ease of integration of the API —as well as Glitch’s zero-setup development environment and near-instant feedback loop for rapid iteration— allowed us to go from new project to live app in no time flat.

Are you running a live event and looking to increase audience engagement? Remix the app and make it yours!

Angelo Stavrow works with the Solutions Engineering team at Glitch. Find out what he's up to here.