Introducing a Multiplayer Quiz App Built on Salesforce Technology

Work can be stressful and we all need a break from time to time. What if you could take that break while having loads of fun and learn a few things at the same time? Well, here’s your chance: we’re excited to release the first multiplayer quiz app built entirely on Salesforce technology!

In this blog post, we introduce the Quiz App and share highlights about the app architecture and its deployment.

Introducing the Quiz App

The quiz app is inspired by the popular Kahoot game. Here’s how it works:
First, a game host presents questions from a shared screen or a video projector. Then, players compete by answering those questions in real-time using a mobile web app. The fastest player to give the correct answer scores the most points. As the game progresses, leaderboards are displayed so that players can keep track of scores and ranks.

The quiz app was initially launched during Developer Game Night at Dreamforce 2019 with close to a hundred players. Now it’s open source and we’re promoting it during Dreamforce Global Gatherings. That’s right, you can install it for free, inspect the code, and customize it to your liking!

Architecture Overview

The quiz is divided in two applications: a host app and a player app.

The host app is a Lightning Web Component (LWC) app running on a Salesforce Org. The org holds all of the quiz data in custom objects (players, questions, answers…). This means that you can easily import extra questions and customize them. It’s as simple as editing records—zero code change required!

The player app is a mobile app built with Lightning Web Components Open Source (LWC OSS). It runs on Node.js deployed on Heroku. There are a few reasons to have the player app on Heroku for our specific use case. First, the Heroku app scales well and can accommodate a large number of users as Heroku limits are based on processing power (dynos) rather than strict governor limits. Secondly, we can easily provide unauthenticated access to our custom app. Unlike Salesforce orgs, there are no user license considerations on Heroku.

These advantages do come at a cost: it’s up to us to build the app from the ground up. We use that to our advantage in the quiz player by implementing a lightweight mobile app.

Cross-App Communication

The two applications communicate with bidirectional REST calls.

The player app uses the JSforce library (a JavaScript Salesforce client) to authenticates on the Salesforce org with a username/password flow. The client calls the standard REST APIs as well as a couple of custom Apex REST endpoints.

The host app also sends REST requests to the Node.js server of the player app to signal game phase changes (eg: a question becomes available or game results are being displayed). These calls are secured with a shared secret API key that is configured on the two apps during setup. This technique ensures a lightweight and minimal level of security by preventing third parties from accessing the player app REST endpoints.

Client-Server Communication on the Player App

The player app consists of a client (the LWC OSS app running on a mobile device) and a server (the Node.js backend). The client calls REST APIs on the server to retrieve information like the player’s score.

We also establish a WebSocket connection between the client and the server. This allows us to push real-time updates like game phase changes to the mobile app. For example, when a new question can be answered, the Node.js backend broadcasts an WebSocket message to all mobile clients. With that, all players can see game updates at the same time on their mobile devices.

While powerful, WebSockets have an important limitation when working on mobile. WebSockets rely on a lasting network connection between the client and the server. On mobile, this connection can easily be broken when the device screen is locked or when the user switches to another app. This means that we must implement some non trivial code to handle reconnection on the client side and a keep alive mechanism to detect and eliminate broken connections on the server side.

App Deployment

One of the most challenging parts of this project is making sure that the quiz app can be easily deployed by a large number of users with different degrees of technical skill. Given the complexity of the environment (two different technology stacks), we needed to ensure that the deployment is as automated as possible. We rely on two things to achieve that: an org deployment script for the host app and a Heroku deploy button for the player app.

Note: the app setup is extensively documented and we even provide a video guide (see link at the end of this post).

Org Deployment Script

The quiz host app is deployed on a Scratch org with Salesforce DX. This allows us to create a temporary Salesforce org with a lifespan of up to 30 days with a set of commands. These commands are grouped and chained together in a deployment script that you can run with a single command in a terminal.

The deployment scripts automates the following tasks:

  1. Creating a scratch org
  2. Pushing sources to the org
  3. Assigning permissions
  4. Importing question data
  5. Generating a user password

Automating the setup process greatly reduces the risk of configuration errors and saves a lot of time.

Here’s a simplified version of the deployment script running on MacOs (there’s also an equivalent script for Windows):

echo "1. Creating scratch org..." && \
sfdx force:org:create -s -f config/project-scratch-def.json -a $ORG_ALIAS -d 30 && \
echo "" && \

echo "2. Pushing source..." && \
sfdx force:source:push -f -u $ORG_ALIAS && \
echo "" && \

echo "3. Assigning permissions..." && \
sfdx force:user:permset:assign -n Quiz_Host -u $ORG_ALIAS && \
echo "" && \

echo "4. Importing data..." && \
sfdx force:data:tree:import -p data/$DATA/plan.json -u $ORG_ALIAS && \
echo "" && \

echo "5. Generating user password..." && \
sfdx force:user:password:generate -u $ORG_ALIAS && \
echo ""

EXIT_CODE="$?"
# Check exit code
echo ""
if [ "$EXIT_CODE" -eq 0 ]; then
echo "Installation completed."
echo ""
sfdx force:org:open -p /lightning/setup/SecurityRemoteProxy/home -u $ORG_ALIAS
else
echo "Installation failed."
fi
exit $EXIT_CODE

Notice how commands are chained together with the && operator. This executes them one after the other as long as there are no errors. The \ character at the end of the line lets us introduce line breaks for readability.
At the end of the script we’re checking for the last command’s exit code with EXIT_CODE="$?". This lets us report the deployment status with a message and open the org if everything went well.

Heroku Deploy Button

The player app is even easier to install with a Heroku deploy button. The deploy button is an image with a link that the user can click to deploy a Heroku app without leaving the browser. The link URL holds a reference to the GitHub repository that contains the app source code and a deployment configuration file.

With the deploy button the user only has to enter a few configuration variables before confirming the deployment.

Summary

Now that you’ve learned about the Quiz App features and architecture, how about giving it a try? Sign up for a Dreamforce Global Gathering near you to find worthy opponents. Or, explore the code, install the apps, and customize questions by simply editing records.

Don’t hesitate to let us know how much fun you had on social media!

Resources

Quiz app installation instructions

 

Published
January 14, 2020