Canvas Quiz is a starter kit for developers to make custom, voice-enabled question-answer games for the Google Assistant. It uses Interactive Canvas, so you can create your own custom graphics and animations. Just deploy the code, put your questions and answers in a Google Sheet, and you’ll have your own quiz up and running.
This is not an official Google product. It’s just an experiment designed to help developers get started building with Interactive Canvas. If you want to learn more about Interactive Canvas, check out the official docs.
Prerequisites: Node.js and npm. A bit of familiarity with Actions on Google and Interactive Canvas is helpful.
- Make a copy of the example Google Sheet.
- Create a new Firebase project.
- Enable Blaze billing (necessary to use Sheets API and Dialogflow API).
- Create a new Dialogflow project. When it asks you for your Google Cloud Project, choose the Firebase project you just created.
- Install the Firebase command line tools.
- Run
npm run setup
from the root of this repo. You'll need the gcloud command line tools installed. (MacOS/Linux only)
If you ran the setup command successfully, you can skip all the steps below!
- Run
npm run installall
to install npm packages for the frontend and backend. - In Google Cloud Console, create a service account. Name it whatever you want.
- For the service account’s role, choose Project > Owner.
- Click “CREATE KEY”. Choose JSON. Click CREATE. This will download a json file.
- Move the file into
deploy/functions/modules/auth
. - Share the spreadsheet with the email address you just created (needs view access)
- In the Google Cloud APIs library, find the “Google Sheets API” and enable it.
- Also find the "Dialogflow API" and make sure its enabled.
- In the (Dialogflow Console) [https://console.dialogflow.com] for your agent, click the gear icon in the upper left by your agent’s name. The click “Export and Import”.
- Click “RESTORE FROM ZIP”. Choose the file
canvas-quiz-starter-agent.zip
from the root of this repo. This will overwrite anything in this agent, and cannot be undone. - Open
deploy/functions/modules/config.js
in an editor. Update these variables:SERVICE_KEY
should be the filename of the JSON key you downloaded.CANVAS_URL
should be your firebase hosting url + “/canvas”AUDIO_URL
should be where you want to store any sound effects (can use firebase hosting for this)IMAGE_URL
should be where you want to store any images (can use firebase hosting for this)SHEET_ID
should be the id of your Google Sheet. It's in the url: https://docs.google.com/spreadsheets/d/[ID_IS_HERE]/edit
- Open
deploy/.firebaserc
. Update $PROJECTID to your GCP project.
npm run build
will build the frontend into the deploy/public/canvas
directory.
npm run watch
will watch for any changes and build automatically.
npm run deploy
will deploy the frontend and backend to Firebase. It will also run a predeploy script that will parse the Google Sheet, update staticquiz.json, and update answer entities on Dialogflow.
Make sure to change your Dialogflow agent’s fulfillment URL to the URL of your cloud function.
Frontend
The front end can be tested by running npm run frontend
. The client/debug-helpers.js
file exposes functions that simulate states sent from the backend, so you can see how the frontend looks and responds to backend changes by calling these functions from the console of your browser.
Backend The first time you want to run your action, go to your Dialogflow agent, and then click “See how it works in Google Assistant” in the right hand column. This will open the Actions on Google simulator.
In the Actions on Google console, go to Deploy > Additional Information. Set the category as “Games & Fun” and scroll down check the box labeled “Interactive Canvas”.
You can customize fonts, colors, spacing, and more in client/config.js
.
Make sure to build the frontend afterwards.
Frontend source files are in the client
directory. They use LitElement to build HTML components.
Game.js is the primary controller that takes the state from the backend, sends data to components, and handles transitions.
Animations are handled using Greensock.
Backend source files are in the deploy/functions
directory. Index.js handles the main logic of the quiz.
Primary modules:
- config.js: Holds important info like your project ID, url of the frontend, quiz settings, and spreadsheet settings.
- DataManager.js: Handles reading the spreadsheet, putting answers into Dialogflow API, and making data available to the quiz at runtime.
- History.js: Tracks what questions a user has seen and how many times they’ve gotten each question right and wrong. Persists across conversations. Used to prioritize questions the user hasn’t seen and questions the user has gotten wrong frequently.
- Replier.js: Handles sending replies to the frontend. Detects device capabilities and adjusts for audio-only, screens without Interactive Canvas support, and screens with Interactive Canvas support. Generally better to use this than
conv.ask()
.- You can chain spoken replies like this:
conv.replier.addReply(“I want to say this!”); conv.replier.addReply(“And this!”); conv.replier.send(“One last thing”);
- You can send state updates to the frontend like this:
conv.replier.addCanvasUpdate({foo: “bar”});
- You can access arbitrary rows in the spreadsheet like this:
conv.replier.getMisc(‘value from id column’)
- If a spreadsheet row selected with the
conv.replier.getMisc
function contains a value in the audio column, replier will look for the corresponding audio file indeploy/firebase/public/audio
.
- You can chain spoken replies like this:
In the Actions on Google console, go to Deploy > Additional Information. Set the category as “Games & Fun” and scroll down check the box labeled “Interactive Canvas”.
These aren’t directly exposed to the user but could be useful for navigation or testing. If you don’t want them, delete the intents from the Dialogflow agent and delete the corresponding intent-handlers in deploy/functions/index.js
.
- “Delete history” - This will clear everything in user storage, like what questions you’ve seen, your location, etc. If you start another conversation, it’ll be like your first time using the app.
- “Go to question ___” - Jumps to a question number. Might mess up your progress, but useful for debugging content without having to reorder the spreadsheet. The number will be the row of the spreadsheet minus 2. So to go to the question on row 44 of the spreadsheet, say “go to question 42”
- “Debug order linear” - If said on the homescreen, will force user to go through questions in linear order (useful for testing)
- “Restart / start over” - Restarts the quiz
- “What is this” - triggers an about page for the quiz
- “Next question / last question” - Skips back and forth. Skipped questions are marked as wrong.