This repo contains a Zoom Chatbot used to retrieve a randomized list of your current meeting's participants:
The bot will work for any logged-in meeting participant.
The app is an HTTP server (using Fastify) backed by a Postgres database for persisting data.
The server has three public endpoints:
/authorize
- called when the app is installed in a Zoom account, here we fetch an initial OAuth token for accessing Zoom's API/hook
- used for handling event subscriptions (participant joined, participant left, meeting ended) and stores the state of active meetings in the database - when a meeting ends it's removed/bot
- used for handling Chatbot calls (when a slash command is used or a direct message is sent to the bot), and responds with the randomized list of participants
Meeting participants might not necessarily be logged in, that's why the app is storing both the usernames (which may be set for the current meeting only) and user ids of the logged-in users for looking up their active meetings.
To avoid privacy issues usernames stored in the database are encrypted using SHA256.
- Node LTS
-
Create the env file
cp .env.sample .env
the missing environment variables will come from the Zoom Chatbot setup in the next steps👇
-
Install packages
npm install
-
Startup the Firestore emulator
npm run db:up
-
Startup the local server with nodemon
npm run dev
node debugger is available on the default port 9229
-
Use ngrok to expose the local app
If you don't have ngrok installed, here you can find the setup instructions: Ngrok install
make sure to create an account and log in before proceeding with the following steps.
ngrok http 3000
- run this command to expose your local app running on port 3000 -
Keep note of your public ngrok https url
-
Visit Zoom Marketplace and create a new Chatbot in a private account (follow the instructions below and visit docs for reference).
Some issues found with accounts created with a gmail.com email, refer to the troubleshooting paragraph.
-
In the
App credentials
tab:- copy the development
Client ID
andClient secret
to your local.env
file - fill in the
Redirect URL for OAuth
field with$PUBLIC_URL/authorize
replacing$PUBLIC_URL
with the ngrok http url - in you
.env
file setREDIRECT_URL
to the same value - add the
$PUBLIC_URL
to theOAuth allow list
- this is necessary for OAuth to work
- copy the development
-
In the
Information
tab fill in theDeveloper Contact Information
section -
In the
Feature
tab:- fill in the
Bot endpoint URL
field - this is the$PUBLIC_URL/bot
endpoint - add a slash command (note: this has to be a value that is unique for the entire Zoom Marketplace)
- add a "usage hint" named "skipme" and add its description: "Do not include me in the random list of participants"
- enable
Events subscription
for all users in the account and subscribe to the following events:- End Meeting
- Participant/Host joined meeting
- Participant/Host left meeting
- fill in the
Event notification endpoint URL
- this is the$PUBLIC_URL/hook
endpoint - copy the
Secret Token
to your local.env
file - copy the
Bot JID
to your local.env
file (it will be generated when settings are saved)
- fill in the
-
In the
Scopes
tab add theuser:read:admin
scope - here's a reference description of the used scopes: -
Move on to the
Local test
tab and try installing the app locally (make sure that your app is running, publicly available and using the development secrets). You will be asked to authorize the app and if everything goes well you will be redirected to a new Zoom chat with your bot. You can re-install the app locally as many times as you need. -
You can test the Chatbot in Zoom by:
- sending any message directly to the bot (anything you send here will trigger the bot, you can also type
skipme
) - sending messages to a new/existing channel (
/SLASH_COMMAND_FROM_STEP_4
or/SLASH_COMMAND_FROM_STEP_4 skipme
)
- sending any message directly to the bot (anything you send here will trigger the bot, you can also type
-
For development purposes, don't submit the app in the
Submit
tab. Keep it as a draft.
GitHub Actions are used for running tests in a controlled environment
Github Actions deploy the master
branch to
Google Cloud Platform.
The Continuous Delivery workflow can be triggered manually in the Actions
tab (the test database and Run instance have
to be removed manually).
To make the CD pipeline work, you need to set up the following variables:
GCP_WORKLOAD_IDENTITY_PROVIDER
,GCP_PROJECT_ID
,GCP_SERVICE_ACCOUNT
,RUN_CPU
,RUN_MEM
,RUN_SERVICE_NAME
,FIRESTORE_COLLECTION
,ZOOM_CLIENT_ID
,ZOOM_REDIRECT_URL
,
To make the CD pipeline work, you need to set up the following secrets:
ZOOM_BOT_JID
,ZOOM_CLIENT_SECRET
,ZOOM_SECRET_TOKEN
If deployed with GCP using the Continuous Delivery pipeline, the application metrics can be monitored in the Cloud Run service details page.
The app utilizes Fastify's default logger, and the production logs are easily accessible using GCP's Logs Explorer.
Logs can be easily narrowed down to a specific commit deployment by filtering on revision names which consist of
${SERVICE_NAME}-${COMMIT_SHA}
.
During the setup and installation phase you can come across a few problems:
Since February 2022 are occurring some problems creating the bot using an account registered with the @gmail.com domain. The returned error is a generic fail_register_robot_to_robot_service
. Using an account made using a non-Gmail account everything works well. https://devforum.zoom.us/t/getting-fail-register-robot-to-robot-service-error-while-saving-bot-url-in-features/64742
Another little problem comes when the app is locally tested using Linux. Authorizing the device redirects you to an unsupported page, and the bot is not added to your account. In this case, try using windows or mac.
If the bot stops working and always responds with "Sorry, you don't seem to be participating in any of the ongoing meetings", it can depend on a problem with the webhooks, in fact, the tracking of the join and left of the meeting is tracked using the webhooks.
For local testing, it is enough to re-authorize the bot by clicking on the Add button in the Local test tab and trying again.
For the production environment, you can try to open the publishable url
in a browser. The publishable url is available in the submit tab of the app configuration.