### Initialize ChatbotClient and start server (JavaScript) Source: https://context7.com/zoom/rivet-javascript/llms.txt Creates a ChatbotClient instance using client credentials and starts an HTTP server to receive webhook events. The example demonstrates asynchronous initialization and logs the server address. Requires the @zoom/rivet/chatbot package and valid Zoom credentials. ```javascript import { ChatbotClient } from \"@zoom/rivet/chatbot\"; (async () => { const chatbotClient = new ChatbotClient({ clientId: \"YOUR_CLIENT_ID\", clientSecret: \"YOUR_CLIENT_SECRET\", webhooksSecretToken: \"YOUR_WEBHOOK_SECRET\" }); // Start the server to listen for webhook events const server = await chatbotClient.start(); console.log(`Server running on: ${JSON.stringify(server.address())}`); // Output: Server running on: {\"address\":\"::\",\"family\":\"IPv6\",\"port\":8080} })(); ``` -------------------------------- ### Initialize Chatbot Client (Node.js) Source: https://github.com/zoom/rivet-javascript/blob/main/README.md Demonstrates initializing a ChatbotClient with required credentials. This is the starting point for building Zoom Rivet applications. Requires Node.js and the @zoom/rivet package. ```javascript import { ChatbotClient } from "@zoom/rivet/chatbot"; (async () => { const chatbotClient = new ChatbotClient({ clientId: "CLIENT_ID", clientSecret: "CLIENT_SECRET", webhooksSecretToken: "WEBHOOK_SECRET_TOKEN" }); // Zoom Rivet code goes here! const server = await chatbotClient.start(); console.log(`Zoom Rivet Events Server running on: ${JSON.stringify(server.address())}`); })(); ``` -------------------------------- ### Listen to Raw Webhook Events in ChatbotClient (JavaScript) Source: https://context7.com/zoom/rivet-javascript/llms.txt This code example illustrates subscribing to specific webhook events by name using the ChatbotClient for custom logic. It accesses raw event payloads for handling bot installations, interactive selects, and link shares. Requires @zoom/rivet/chatbot and webhook secrets; outputs include console logs and optional database storage. Limitations apply to event types and payload structure from Zoom. ```javascript import { ChatbotClient } from "@zoom/rivet/chatbot"; const chatbotClient = new ChatbotClient({ clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", webhooksSecretToken: "YOUR_WEBHOOK_SECRET" }); // Listen for bot installation events chatbotClient.webEventConsumer.event("bot_installed", (payload) => { console.log("Bot installed by:", payload.payload.userName); console.log("Account ID:", payload.payload.accountId); console.log("User ID:", payload.payload.userId); // Store installation data in your database // saveToDatabase({ userId: payload.payload.userId, accountId: payload.payload.accountId }); }); // Listen for interactive message select events (dropdowns) chatbotClient.webEventConsumer.event("interactive_message_select", (payload) => { const selectedValues = payload.payload.selectedItems.map(item => item.value); console.log("User selected:", selectedValues); console.log("Message ID:", payload.payload.messageId); }); // Listen for link sharing events chatbotClient.webEventConsumer.event("team_chat.link_shared", (payload) => { const link = payload.payload.object.link; console.log("Link shared:", link); console.log("Channel:", payload.payload.object.channel_name); // Implement link unfurling logic here }); (async () => await chatbotClient.start())(); ``` -------------------------------- ### Initialize TeamChatClient with OAuth (JavaScript) Source: https://context7.com/zoom/rivet-javascript/llms.txt Initializes the TeamChatClient using OAuth for authentication, supporting user and server-to-server flows. It generates an authorization URL for user redirection and starts a local server to handle OAuth callbacks and listen for events. Dependencies include the '@zoom/rivet/teamchat' package. ```javascript import { TeamChatClient } from "@zoom/rivet/teamchat"; const teamchatClient = new TeamChatClient({ clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", webhooksSecretToken: "YOUR_WEBHOOK_SECRET", installerOptions: { redirectUri: "https://yourdomain.com/oauth/callback", stateStore: "random_state_secret_key" } }); // Get OAuth authorization URL const authUrl = await teamchatClient.installerOptions.getAuthorizationUrl(); console.log("Redirect users to:", authUrl); // Output: Redirect users to: https://zoom.us/oauth/authorize?client_id=...&response_type=code&redirect_uri=... // After user authorizes, exchange code for token (handled automatically by receiver) const server = await teamchatClient.start(); console.log("Team Chat client ready on port:", server.address().port); ``` -------------------------------- ### Manage Zoom User Accounts Source: https://context7.com/zoom/rivet-javascript/llms.txt Shows how to create, retrieve, update, and list Zoom users using the UsersClient. Requires server-to-server OAuth credentials. The examples demonstrate user creation with email and type specification, retrieving user details, updating user information, and listing all users in an account with pagination support. ```javascript import { UsersClient } from "@zoom/rivet/users"; const usersClient = new UsersClient({ clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", accountId: "YOUR_ACCOUNT_ID", disableReceiver: true }); // Create a new user const createUser = async () => { const response = await usersClient.endpoints.users.createUser({ body: { action: "create", user_info: { email: "newuser@example.com", type: 2, // Licensed user first_name: "Jane", last_name: "Doe" } } }); console.log("User created:", response.data.id); console.log("Email:", response.data.email); return response.data; }; // Get user details const getUser = async (userId) => { const response = await usersClient.endpoints.users.getUser({ path: { userId: userId } }); console.log("User:", response.data.first_name, response.data.last_name); console.log("Account ID:", response.data.account_id); console.log("Type:", response.data.type === 2 ? "Licensed" : "Basic"); console.log("Status:", response.data.status); return response.data; }; // Update user information const updateUser = async (userId) => { const response = await usersClient.endpoints.users.updateUser({ path: { userId: userId }, body: { first_name: "Janet", dept: "Engineering", job_title: "Senior Developer" } }); console.log("User updated successfully"); return response; }; // List all users in account const listUsers = async () => { const response = await usersClient.endpoints.users.listUsers({ query: { status: "active", page_size: 100 } }); console.log("Total users:", response.data.total_records); response.data.users?.forEach(user => { console.log(`${user.email} - ${user.first_name} ${user.last_name}`); }); return response.data; }; createUser().catch(console.error); ``` -------------------------------- ### GET /users Source: https://context7.com/zoom/rivet-javascript/llms.txt Lists all Zoom users in the account, with optional filtering by status and pagination support. ```APIDOC ## GET /users\n\n### Description\nLists all Zoom users in the account, optionally filtered by status.\n\n### Method\nGET\n\n### Endpoint\n/users\n\n### Parameters\n#### Path Parameters\n_None_\n\n#### Query Parameters\n- **status** (string) - Optional - Filter users by status (e.g., "active").\n- **page_size** (integer) - Optional - Number of users per page (max 100).\n\n#### Request Body\n_None_\n\n### Request Example\n{\n "query": {\n "status": "active",\n "page_size": 100\n }\n}\n\n### Response\n#### Success Response (200)\n- **total_records** (integer) - Total number of users matching the query.\n- **users** (array) - List of user objects.\n\n### Response Example\n{\n "total_records": 250,\n "users": [\n {\n "email": "user1@example.com",\n "first_name": "Alice",\n "last_name": "Smith"\n },\n {\n "email": "user2@example.com",\n "first_name": "Bob",\n "last_name": "Johnson"\n }\n // ... more users\n ]\n} ``` -------------------------------- ### Manage Zoom Phone Users and Settings Source: https://context7.com/zoom/rivet-javascript/llms.txt Demonstrates how to retrieve phone user profiles, list call logs, and update phone user settings using the PhoneClient. Requires server-to-server OAuth credentials and a valid user ID. The examples show profile retrieval, call log listing with date filters, and updating calling plans and emergency addresses. ```javascript import { PhoneClient } from "@zoom/rivet/phone"; const phoneClient = new PhoneClient({ clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", accountId: "YOUR_ACCOUNT_ID", disableReceiver: true }); // Get phone user profile const getUserPhoneProfile = async (userId) => { const response = await phoneClient.endpoints.phone.getPhoneUser({ path: { userId: userId } }); console.log("User:", response.data.email); console.log("Extension:", response.data.extension_number); console.log("Phone numbers:", response.data.phone_numbers); return response.data; }; // List call logs for a user const getCallLogs = async (userId) => { const response = await phoneClient.endpoints.phone.listUserCallLogs({ path: { userId: userId }, query: { from: "2025-11-01", to: "2025-11-11", page_size: 50 } }); console.log("Total calls:", response.data.total_records); response.data.call_logs?.forEach(call => { console.log(`${call.date_time}: ${call.caller_name} -> ${call.callee_name} (${call.result})`); }); return response.data; }; // Update phone user settings const updatePhoneUser = async (userId) => { const response = await phoneClient.endpoints.phone.updatePhoneUser({ path: { userId: userId }, body: { calling_plans: [{ type: 200, billing_account_id: "billing_123" }], emergency_address: { address_line1: "123 Main St", city: "San Francisco", state_code: "CA", zip: "94105", country: "US" } } }); console.log("Phone user updated successfully"); return response; }; getUserPhoneProfile("user@example.com").catch(console.error); getCallLogs("user@example.com").catch(console.error); ``` -------------------------------- ### GET /phone/users/{userId}/call_logs Source: https://context7.com/zoom/rivet-javascript/llms.txt Lists call logs for a specified user within a date range, supporting pagination. ```APIDOC ## GET /phone/users/{userId}/call_logs\n\n### Description\nLists call logs for a specified user within a given date range.\n\n### Method\nGET\n\n### Endpoint\n/phone/users/{userId}/call_logs\n\n### Parameters\n#### Path Parameters\n- **userId** (string) - Required - The unique identifier or email of the Zoom user.\n\n#### Query Parameters\n- **from** (string) - Required - Start date in YYYY-MM-DD format.\n- **to** (string) - Required - End date in YYYY-MM-DD format.\n- **page_size** (integer) - Optional - Number of records per page (max 100).\n\n#### Request Body\n_None_\n\n### Request Example\n{\n "path": { "userId": "user@example.com" },\n "query": {\n "from": "2025-11-01",\n "to": "2025-11-11",\n "page_size": 50\n }\n}\n\n### Response\n#### Success Response (200)\n- **total_records** (integer) - Total number of call log entries.\n- **call_logs** (array) - List of call log objects.\n\n### Response Example\n{\n "total_records": 123,\n "call_logs": [\n {\n "date_time": "2025-11-10T14:23:00Z",\n "caller_name": "Alice",\n "callee_name": "Bob",\n "result": "completed"\n }\n // ... more entries\n ]\n} ``` -------------------------------- ### GET /users/{userId} Source: https://context7.com/zoom/rivet-javascript/llms.txt Retrieves detailed information for a specific Zoom user account. ```APIDOC ## GET /users/{userId}\n\n### Description\nRetrieves detailed information for a specific Zoom user.\n\n### Method\nGET\n\n### Endpoint\n/users/{userId}\n\n### Parameters\n#### Path Parameters\n- **userId** (string) - Required - The unique identifier of the Zoom user.\n\n#### Query Parameters\n_None_\n\n#### Request Body\n_None_\n\n### Request Example\n{\n "path": { "userId": "abcd1234" }\n}\n\n### Response\n#### Success Response (200)\n- **first_name** (string) - User's first name.\n- **last_name** (string) - User's last name.\n- **account_id** (string) - Account identifier.\n- **type** (integer) - User type (e.g., 2 for Licensed).\n- **status** (string) - Current user status.\n\n### Response Example\n{\n "first_name": "Jane",\n "last_name": "Doe",\n "account_id": "account_5678",\n "type": 2,\n "status": "active"\n} ``` -------------------------------- ### Send message with App Card using ChatbotClient (JavaScript) Source: https://context7.com/zoom/rivet-javascript/llms.txt Uses the ChatbotClient to send a rich App Card message to a user or channel. The example builds a message payload with headers, body sections, and action buttons, then calls the sendChatbotMessage endpoint. Requires a configured ChatbotClient and network access to Zoom APIs. ```javascript import { ChatbotClient } from \"@zoom/rivet/chatbot\"; const chatbotClient = new ChatbotClient({ clientId: \"YOUR_CLIENT_ID\", clientSecret: \"YOUR_CLIENT_SECRET\", webhooksSecretToken: \"YOUR_WEBHOOK_SECRET\" }); const messageBody = { robot_jid: \"v1abjabR_CKrhdagYwTOw@xmpp.zoom.us\", account_id: \"abc123\", to_jid: \"user@xmpp.zoom.us\", user_jid: \"user@xmpp.zoom.us\", content: { head: { text: \"Task Update\", sub_head: { text: \"Your deployment is complete\" } }, body: [ { type: \"message\", text: \"The production deployment finished successfully at 14:30 UTC\", is_markdown_support: true }, { type: \"actions\", items: [ { text: \"View Logs\", value: \"view_logs\", style: \"Primary\" }, { text: \"Rollback\", value: \"rollback\", style: \"Danger\" } ] } ] } }; chatbotClient.endpoints.messages.sendChatbotMessage({ body: messageBody }) .then(response => { console.log(\"Message sent successfully:\", response.statusCode); // Output: Message sent successfully: 200 }) .catch(error => { console.error(\"Failed to send message:\", error.message); }); ``` -------------------------------- ### Create and Manage Zoom Meetings with MeetingsClient (JavaScript) Source: https://context7.com/zoom/rivet-javascript/llms.txt Utilizes the MeetingsClient to programmatically create, update, and delete Zoom meetings. It requires OAuth authentication and an account ID. The `disableReceiver` option is set to true as this example focuses on API interactions without webhook handling. Dependencies include the '@zoom/rivet/meetings' package. ```javascript import { MeetingsClient } from "@zoom/rivet/meetings"; const meetingsClient = new MeetingsClient({ clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", accountId: "YOUR_ACCOUNT_ID", disableReceiver: true // No webhook receiver needed for API-only usage }); // Create a new meeting const createMeeting = async (userId) => { const response = await meetingsClient.endpoints.meetings.createMeeting({ path: { userId: userId }, body: { topic: "Q4 Planning Meeting", type: 2, // Scheduled meeting start_time: "2025-12-15T14:00:00Z", duration: 60, timezone: "America/New_York", agenda: "Discuss Q4 goals and objectives", settings: { host_video: true, participant_video: true, join_before_host: false, mute_upon_entry: true, waiting_room: true, audio: "both", auto_recording: "cloud" } } }); console.log("Meeting created:", response.data.id); console.log("Join URL:", response.data.join_url); console.log("Start time:", response.data.start_time); return response.data; }; // Update an existing meeting const updateMeeting = async (meetingId) => { const response = await meetingsClient.endpoints.meetings.updateMeeting({ path: { meetingId: meetingId }, body: { topic: "Q4 Planning Meeting - Updated", duration: 90, agenda: "Extended agenda with budget review" } }); console.log("Meeting updated successfully"); return response; }; // Delete a meeting const deleteMeeting = async (meetingId) => { await meetingsClient.endpoints.meetings.deleteMeeting({ path: { meetingId: meetingId } }); console.log("Meeting deleted:", meetingId); }; createMeeting("user@example.com").catch(console.error); ``` -------------------------------- ### GET /phone/users/{userId} Source: https://context7.com/zoom/rivet-javascript/llms.txt Retrieves the phone profile for a specific Zoom user, including email, extension number, and associated phone numbers. ```APIDOC ## GET /phone/users/{userId}\n\n### Description\nRetrieves the phone profile for a specific Zoom user.\n\n### Method\nGET\n\n### Endpoint\n/phone/users/{userId}\n\n### Parameters\n#### Path Parameters\n- **userId** (string) - Required - The unique identifier or email of the Zoom user.\n\n#### Query Parameters\n_None_\n\n#### Request Body\n_None_\n\n### Request Example\n{\n "path": { "userId": "user@example.com" }\n}\n\n### Response\n#### Success Response (200)\n- **email** (string) - User's email address.\n- **extension_number** (string) - Assigned phone extension.\n- **phone_numbers** (array) - List of associated phone numbers.\n\n### Response Example\n{\n "email": "user@example.com",\n "extension_number": "1234",\n "phone_numbers": ["+1 555-123-4567"]\n} ``` -------------------------------- ### Rivet Chatbot Error Handling and Logging Source: https://context7.com/zoom/rivet-javascript/llms.txt Configures custom logging for a Rivet chatbot using `ConsoleLogger` and demonstrates handling various Rivet-specific errors like `ApiResponseError`, `OAuthTokenFetchFailedError`, and `HTTPReceiverRequestError`. It includes a slash command handler that attempts an API call and gracefully handles potential errors, informing the user via an alert message. This setup ensures better diagnostics and user feedback during operation. ```javascript import { ChatbotClient, isCoreError, LogLevel, ConsoleLogger } from "@zoom/rivet/chatbot"; // Setup custom logger const logger = new ConsoleLogger(); logger.setLevel(LogLevel.DEBUG); logger.setName("ZoomBot"); const chatbotClient = new ChatbotClient({ clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", webhooksSecretToken: "YOUR_WEBHOOK_SECRET", logger: logger, logLevel: LogLevel.INFO }); chatbotClient.webEventConsumer.onSlashCommand("/test", async ({ say, payload }) => { try { await say("Processing your request..."); // Simulate API call const response = await chatbotClient.endpoints.messages.sendChatbotMessage({ body: { robot_jid: payload.robotJid, to_jid: payload.toJid, user_jid: payload.userJid, account_id: payload.accountId, content: { body: [{ type: "message", text: "Success!" }] } } }); console.log("API response:", response.statusCode); } catch (error) { // Check for Rivet-specific errors if (isCoreError(error, "ApiResponseError")) { console.error("API error:", error.message); logger.error("Status code:", error.statusCode); } else if (isCoreError(error, "OAuthTokenFetchFailedError")) { console.error("Authentication failed:", error.message); // Attempt to refresh token } else if (isCoreError(error, "HTTPReceiverRequestError")) { console.error("Receiver error:", error.message); } else { console.error("Unexpected error:", error); } // Send error message to user await say({ body: [ { type: "alert", text: "An error occurred while processing your request", level: "error", closable: true } ] }); } }); (async () => await chatbotClient.start())(); ``` -------------------------------- ### Handle slash command with ChatbotClient (JavaScript) Source: https://context7.com/zoom/rivet-javascript/llms.txt Sets up a slash command listener for "/deploy" using the ChatbotClient's webEventConsumer. When the command is received, it replies with a rich message and a progress bar, and placeholders for deployment logic are provided. Requires an active ChatbotClient instance and appropriate webhook configuration. ```javascript import { ChatbotClient } from \"@zoom/rivet/chatbot\"; const chatbotClient = new ChatbotClient({ clientId: \"YOUR_CLIENT_ID\", clientSecret: \"YOUR_CLIENT_SECRET\", webhooksSecretToken: \"YOUR_WEBHOOK_SECRET\" }); chatbotClient.webEventConsumer.onSlashCommand(\"/deploy\", async ({ say, payload }) => { const { userId, userName, cmd, channelName } = payload; console.log(`User ${userName} (${userId}) executed: ${cmd} in ${channelName}`); await say({ head: { text: \"Deployment Started\" }, body: [ { type: \"message\", text: `Deploying to production environment...` }, { type: \"progress_bar\", value: 35 } ] }); // Perform deployment logic here }); (async () => { await chatbotClient.start(); console.log(\"Bot is listening for /deploy commands\"); })(); ``` -------------------------------- ### POST /users Source: https://context7.com/zoom/rivet-javascript/llms.txt Creates a new Zoom user account with specified profile information and licensing type. ```APIDOC ## POST /users\n\n### Description\nCreates a new Zoom user account.\n\n### Method\nPOST\n\n### Endpoint\n/users\n\n### Parameters\n#### Path Parameters\n_None_\n\n#### Query Parameters\n_None_\n\n#### Request Body\n- **action** (string) - Required - Action to perform, typically "create".\n- **user_info** (object) - Required - Details of the user to be created.\n - **email** (string) - Required - User's email address.\n - **type** (integer) - Required - User type (e.g., 2 for Licensed).\n - **first_name** (string) - Required - First name.\n - **last_name** (string) - Required - Last name.\n\n### Request Example\n{\n "body": {\n "action": "create",\n "user_info": {\n "email": "newuser@example.com",\n "type": 2,\n "first_name": "Jane",\n "last_name": "Doe"\n }\n }\n}\n\n### Response\n#### Success Response (201)\n- **id** (string) - Unique identifier of the created user.\n- **email** (string) - Email of the created user.\n\n### Response Example\n{\n "id": "abcd1234",\n "email": "newuser@example.com"\n} ``` -------------------------------- ### Generate Video SDK Sessions and Tokens Source: https://context7.com/zoom/rivet-javascript/llms.txt Create Zoom Video SDK sessions and generate client tokens for embedding video functionality. Requires session configuration including topic, duration, and settings. Supports host and participant roles with JWT-based authentication. ```javascript import { VideoSDKClient } from "@zoom/rivet/videosdk"; const videoSDKClient = new VideoSDKClient({ clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", disableReceiver: true }); // Create a Video SDK session const createSession = async () => { const response = await videoSDKClient.endpoints.videoSDK.createSession({ body: { topic: "Product Demo Session", type: 1, // Video SDK session duration: 60, settings: { host_video: true, participant_video: true, enable_recording: true } } }); console.log("Session created:", response.data.id); console.log("Session name:", response.data.session_name); return response.data; }; // Generate JWT token for client const generateToken = (sessionName, roleType) => { // Token generation happens client-side with SDK credentials const token = { sessionName: sessionName, roleType: roleType, // 0 for participant, 1 for host userIdentity: "user123" }; console.log("Token payload:", token); return token; }; // Get session details const getSession = async (sessionId) => { const response = await videoSDKClient.endpoints.videoSDK.getSession({ path: { sessionId: sessionId } }); console.log("Session topic:", response.data.topic); console.log("Duration:", response.data.duration); console.log("Created at:", response.data.created_at); return response.data; }; createSession().catch(console.error); ``` -------------------------------- ### Manage Account Settings with AccountsClient Source: https://context7.com/zoom/rivet-javascript/llms.txt Configure organization-wide Zoom settings including meeting, recording, and security options. Requires client credentials and account ID. Supports retrieving current settings and updating configurations. ```javascript import { AccountsClient } from "@zoom/rivet/accounts"; const accountsClient = new AccountsClient({ clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", accountId: "YOUR_ACCOUNT_ID", disableReceiver: true }); // Get account settings const getAccountSettings = async (accountId) => { const response = await accountsClient.endpoints.accounts.getAccountSettings({ path: { accountId: accountId } }); console.log("Meeting settings:", response.data.schedule_meeting); console.log("Recording settings:", response.data.recording); console.log("Security settings:", response.data.security); return response.data; }; // Update account settings const updateAccountSettings = async (accountId) => { const response = await accountsClient.endpoints.accounts.updateAccountSettings({ path: { accountId: accountId }, body: { schedule_meeting: { host_video: true, participants_video: true, require_password_for_all_meetings: true }, security: { waiting_room: true, waiting_room_settings: { participants_to_place_in_waiting_room: 2 // Everyone except host } } } }); console.log("Account settings updated successfully"); return response; }; // Get managed domains const getManagedDomains = async (accountId) => { const response = await accountsClient.endpoints.accounts.getManagedDomains({ path: { accountId: accountId } }); console.log("Managed domains:"); response.data.domains?.forEach(domain => { console.log(`- ${domain.domain} (${domain.status})`); }); return response.data; }; getAccountSettings("YOUR_ACCOUNT_ID").catch(console.error); ``` -------------------------------- ### Respond to Slash Commands (Node.js) Source: https://github.com/zoom/rivet-javascript/blob/main/README.md Demonstrates listening for slash commands and responding using the `onSlashCommand()` method and `say()` function. Enable your application to respond to user interactions. Requires the @zoom/rivet package and a running Zoom Rivet server. ```javascript chatbotClient.webEventConsumer.onSlashCommand("SLASH_COMMAND", async ({ say, payload }) => { console.log(payload); await say("Hello World!"); }); ``` -------------------------------- ### Listen to Webhook Events (Node.js) Source: https://github.com/zoom/rivet-javascript/blob/main/README.md Shows how to listen to specific webhook events using the `webEventConsumer.event()` method. This allows your application to react to events like bot notifications. Requires the @zoom/rivet package and a running Zoom Rivet server. ```javascript chatbotClient.webEventConsumer.event("bot_notification", (response) => { const payload = response.payload; console.log(payload); }); ``` -------------------------------- ### Custom Database Token Store for Rivet Chatbot Source: https://context7.com/zoom/rivet-javascript/llms.txt Implements a `DatabaseTokenStore` class to persist OAuth tokens in a database, providing `getLatestToken` and `storeToken` methods. This avoids in-memory storage limitations and allows for token persistence across application restarts. It requires a database connection object and integrates with the `ChatbotClient` by passing an instance of this store to the `tokenStore` option. ```javascript import { ChatbotClient } from "@zoom/rivet/chatbot"; class DatabaseTokenStore { constructor(database) { this.db = database; } async getLatestToken() { try { const token = await this.db.query( "SELECT access_token, expiration_time, scopes FROM tokens WHERE app_type = 'chatbot' ORDER BY created_at DESC LIMIT 1" ); if (!token) return null; return { accessToken: token.access_token, expirationTimeIso: token.expiration_time, scopes: JSON.parse(token.scopes) }; } catch (error) { console.error("Failed to retrieve token:", error); return null; } } async storeToken(token) { try { await this.db.query( "INSERT INTO tokens (access_token, expiration_time, scopes, app_type, created_at) VALUES (?, ?, ?, 'chatbot', NOW())", [token.accessToken, token.expirationTimeIso, JSON.stringify(token.scopes)] ); console.log("Token stored successfully"); } catch (error) { console.error("Failed to store token:", error); throw error; } } } // Use custom token store const tokenStore = new DatabaseTokenStore(yourDatabaseConnection); const chatbotClient = new ChatbotClient({ clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", webhooksSecretToken: "YOUR_WEBHOOK_SECRET", tokenStore: tokenStore }); (async () => { await chatbotClient.start(); console.log("Chatbot running with database-backed token storage"); })(); ``` -------------------------------- ### Deploy Chatbot on AWS Lambda Source: https://context7.com/zoom/rivet-javascript/llms.txt Integrate Zoom webhook handlers with AWS Lambda using specialized receiver. Processes slash commands and responds with structured messages. Expects environment variables for credentials and returns formatted Lambda responses. ```javascript import { ChatbotClient, AwsLambdaReceiver } from "@zoom/rivet/chatbot"; const receiver = new AwsLambdaReceiver({ webhooksSecretToken: process.env.WEBHOOK_SECRET_TOKEN }); const chatbotClient = new ChatbotClient({ clientId: process.env.ZOOM_CLIENT_ID, clientSecret: process.env.ZOOM_CLIENT_SECRET, receiver: receiver }); // Setup event handlers chatbotClient.webEventConsumer.onSlashCommand("/lambda-test", async ({ say, payload }) => { console.log("Lambda executed by:", payload.userName); await say({ head: { text: "Lambda Response" }, body: [ { type: "message", text: "This bot is running on AWS Lambda!" } ] }); }); // Export Lambda handler export const handler = chatbotClient.start(); // Lambda will invoke: handler(event, context, callback) // Response format: { statusCode: 200, body: JSON.stringify({...}) } ``` -------------------------------- ### ChatbotClient - Handle Button Clicks Source: https://context7.com/zoom/rivet-javascript/llms.txt This section explains how to respond to interactive button clicks from app cards. You can filter by button value and update the interface based on user actions. ```APIDOC ## ChatbotClient - Handle Button Clicks ### Description Respond to interactive button clicks from app cards. Filter by button value and update the interface based on user actions. ### Method `chatbotClient.webEventConsumer.onButtonClick(buttonValue, callback)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```javascript import { ChatbotClient } from "@zoom/rivet/chatbot"; const chatbotClient = new ChatbotClient({ clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", webhooksSecretToken: "YOUR_WEBHOOK_SECRET" }); chatbotClient.webEventConsumer.onButtonClick("view_logs", async ({ say, payload }) => { const { actionItem, messageId, userName } = payload; console.log(`${userName} clicked: ${actionItem.text} (${actionItem.value})`); await say({ head: { text: "Deployment Logs" }, body: [ { type: "message", text: "```\n[14:25:32] Building application...\n[14:27:15] Running tests...\n[14:29:42] Deploying to production...\n[14:30:18] Deployment successful\n```", is_markdown_support: true } ] }); }); chatbotClient.webEventConsumer.onButtonClick("rollback", async ({ say, payload }) => { await say({ head: { text: "Rollback Initiated" }, body: [ { type: "alert", text: "Rolling back to previous version...", level: "warning", closable: false } ] }); }); (async () => await chatbotClient.start())(); ``` ### Response #### Success Response (200) This method does not directly return a value but triggers asynchronous operations (e.g., sending messages). #### Response Example N/A ``` -------------------------------- ### Handle Channel Messages with TeamChatClient (JavaScript) Source: https://context7.com/zoom/rivet-javascript/llms.txt Configures the TeamChatClient to listen for and respond to messages posted in channels. It supports filtering messages by keywords or regular expressions and provides programmatic replies with structured content. Dependencies include the '@zoom/rivet/teamchat' package and a running OAuth flow. ```javascript import { TeamChatClient } from "@zoom/rivet/teamchat"; const teamchatClient = new TeamChatClient({ clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", webhooksSecretToken: "YOUR_WEBHOOK_SECRET", installerOptions: { redirectUri: "https://yourdomain.com/oauth/callback", stateStore: "secret_state_key" } }); // Respond to messages containing specific keywords teamchatClient.webEventConsumer.onChannelMessagePosted("help", async ({ reply, payload }) => { console.log("Help requested by:", payload.payload.operator); console.log("Channel:", payload.payload.object.channel_name); await reply({ head: { text: "Available Commands" }, body: [ { type: "message", text: "• `help` - Show this message\n• `status` - Check system status\n• `report` - Generate report", is_markdown_support: true } ] }); }); // Use regex to match patterns teamchatClient.webEventConsumer.onChannelMessagePosted(/^status$/i, async ({ reply, payload }) => { await reply({ body: [ { type: "fields", items: [ { key: "System", value: "Operational", short: true }, { key: "API", value: "Healthy", short: true }, { key: "Database", value: "Connected", short: true }, { key: "Cache", value: "Running", short: true } ] } ] }); }); (async () => await teamchatClient.start())(); ``` -------------------------------- ### Handle Button Clicks in ChatbotClient (JavaScript) Source: https://context7.com/zoom/rivet-javascript/llms.txt This code snippet demonstrates how to respond to interactive button clicks from app cards using the ChatbotClient. It filters by button value and updates the interface with messages or alerts based on user actions. Requires @zoom/rivet/chatbot package and Zoom API credentials for initialization. Outputs include console logs and sent messages; limited to predefined button values. ```javascript import { ChatbotClient } from "@zoom/rivet/chatbot"; const chatbotClient = new ChatbotClient({ clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", webhooksSecretToken: "YOUR_WEBHOOK_SECRET" }); chatbotClient.webEventConsumer.onButtonClick("view_logs", async ({ say, payload }) => { const { actionItem, messageId, userName } = payload; console.log(`${userName} clicked: ${actionItem.text} (${actionItem.value})`); await say({ head: { text: "Deployment Logs" }, body: [ { type: "message", text: "```\n[14:25:32] Building application...\n[14:27:15] Running tests...\n[14:29:42] Deploying to production...\n[14:30:18] Deployment successful\n```", is_markdown_support: true } ] }); }); chatbotClient.webEventConsumer.onButtonClick("rollback", async ({ say, payload }) => { await say({ head: { text: "Rollback Initiated" }, body: [ { type: "alert", text: "Rolling back to previous version...", level: "warning", closable: false } ] }); }); (async () => await chatbotClient.start())(); ``` -------------------------------- ### ChatbotClient - Listen to Raw Webhook Events Source: https://context7.com/zoom/rivet-javascript/llms.txt Subscribe to any webhook event by name to handle custom logic beyond the built-in shortcuts. This allows access to raw event payloads for advanced use cases. ```APIDOC ## ChatbotClient - Listen to Raw Webhook Events ### Description Subscribe to any webhook event by name to handle custom logic beyond the built-in shortcuts. Access raw event payloads for advanced use cases. ### Method `chatbotClient.webEventConsumer.event(eventName, callback)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```javascript import { ChatbotClient } from "@zoom/rivet/chatbot"; const chatbotClient = new ChatbotClient({ clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", webhooksSecretToken: "YOUR_WEBHOOK_SECRET" }); // Listen for bot installation events chatbotClient.webEventConsumer.event("bot_installed", (payload) => { console.log("Bot installed by:", payload.payload.userName); console.log("Account ID:", payload.payload.accountId); console.log("User ID:", payload.payload.userId); // Store installation data in your database // saveToDatabase({ userId: payload.payload.userId, accountId: payload.payload.accountId }); }); // Listen for interactive message select events (dropdowns) chatbotClient.webEventConsumer.event("interactive_message_select", (payload) => { const selectedValues = payload.payload.selectedItems.map(item => item.value); console.log("User selected:", selectedValues); console.log("Message ID:", payload.payload.messageId); }); // Listen for link sharing events chatbotClient.webEventConsumer.event("team_chat.link_shared", (payload) => { const link = payload.payload.object.link; console.log("Link shared:", link); console.log("Channel:", payload.payload.object.channel_name); // Implement link unfurling logic here }); (async () => await chatbotClient.start())(); ``` ### Response #### Success Response (200) This method does not directly return a value but registers a callback for the specified webhook event. #### Response Example N/A ``` -------------------------------- ### PATCH /phone/users/{userId} Source: https://context7.com/zoom/rivet-javascript/llms.txt Updates phone user settings such as calling plans and emergency address information. ```APIDOC ## PATCH /phone/users/{userId}\n\n### Description\nUpdates phone user settings, including calling plans and emergency address details.\n\n### Method\nPATCH\n\n### Endpoint\n/phone/users/{userId}\n\n### Parameters\n#### Path Parameters\n- **userId** (string) - Required - The unique identifier or email of the Zoom user.\n\n#### Query Parameters\n_None_\n\n#### Request Body\n- **calling_plans** (array) - Optional - List of calling plan objects.\n - **type** (integer) - Required - Calling plan type identifier.\n - **billing_account_id** (string) - Required - Associated billing account ID.\n- **emergency_address** (object) - Optional - Emergency address information.\n - **address_line1** (string) - Required - Street address line 1.\n - **city** (string) - Required - City name.\n - **state_code** (string) - Required - Two‑letter state code.\n - **zip** (string) - Required - ZIP or postal code.\n - **country** (string) - Required - ISO country code.\n\n### Request Example\n{\n "path": { "userId": "user@example.com" },\n "body": {\n "calling_plans": [{\n "type": 200,\n "billing_account_id": "billing_123"\n }],\n "emergency_address": {\n "address_line1": "123 Main St",\n "city": "San Francisco",\n "state_code": "CA",\n "zip": "94105",\n "country": "US"\n }\n }\n}\n\n### Response\n#### Success Response (200)\n- **status** (string) - Confirmation of successful update.\n\n### Response Example\n{\n "status": "success"\n} ``` -------------------------------- ### Handle Button Clicks with onButtonClick() in JavaScript Source: https://github.com/zoom/rivet-javascript/blob/main/README.md Listens for button clicks in your application using the `onButtonClick()` method. It accepts a button action value to filter events and allows responses via the `say()` function, which can take a string or App Card JSON. Logs the payload to the console. ```javascript chatbotClient.webEventConsumer.onButtonClick("BUTTON_VALUE", async ({ say, payload }) => { console.log(payload); await say("Hello World!"); }); ``` -------------------------------- ### Handle Channel Messages with onChannelMessagePosted() in JavaScript Source: https://github.com/zoom/rivet-javascript/blob/main/README.md Listens for messages posted in a channel using the `onChannelMessagePosted()` method. It filters messages based on a keyword and allows replies using the `reply()` method, which accepts a string or App Card JSON. Logs the payload to the console. ```javascript teamchatClient.webEventConsumer.onChannelMessagePosted("KEYWORD", async ({ reply, payload }) => { console.log(payload); await reply("Hello World!"); }); ``` -------------------------------- ### Send Chatbot Message (Node.js) Source: https://github.com/zoom/rivet-javascript/blob/main/README.md Illustrates how to call the `sendChatbotMessage()` API to send messages via the Zoom Chatbot API. This requires a valid payload with the appropriate message format. Requires the @zoom/rivet package and a running Zoom Rivet server. ```javascript const reqBody = { robot_jid: payload.robotJid, account_id: payload.accountId, to_jid: payload.toJid, user_jid: payload.userJid, content: { head: { text: "I am a header", sub_head: { text: "I am a sub header" } }, body: [ { type: "message", text: "I am a message with text" } ] } }; chatbotClient.endpoints.messages.sendChatbotMessage({ body: reqBody }).then((response) => { console.log("SENT MESSAGE", response.data); }); ``` -------------------------------- ### PATCH /users/{userId} Source: https://context7.com/zoom/rivet-javascript/llms.txt Updates profile information for an existing Zoom user, such as name, department, and job title. ```APIDOC ## PATCH /users/{userId}\n\n### Description\nUpdates profile information for an existing Zoom user.\n\n### Method\nPATCH\n\n### Endpoint\n/users/{userId}\n\n### Parameters\n#### Path Parameters\n- **userId** (string) - Required - The unique identifier of the Zoom user.\n\n#### Query Parameters\n_None_\n\n#### Request Body\n- **first_name** (string) - Optional - New first name.\n- **dept** (string) - Optional - Department name.\n- **job_title** (string) - Optional - Job title.\n\n### Request Example\n{\n "path": { "userId": "abcd1234" },\n "body": {\n "first_name": "Janet",\n "dept": "Engineering",\n "job_title": "Senior Developer"\n }\n}\n\n### Response\n#### Success Response (200)\n- **status** (string) - Confirmation of successful update.\n\n### Response Example\n{\n "status": "success"\n} ```