From 737ae1cdec12f52cf0b6f5e2a6a96b4e0004364c Mon Sep 17 00:00:00 2001 From: Pranav Katariya Date: Tue, 27 Jan 2026 19:40:57 -0800 Subject: [PATCH] fix: improve Zoom onboarding UX and add defensive null handling - Add defensive String(value ?? '') wrapper to trim() calls in channel.ts - Show both webhook and OAuth redirect URLs after credential entry - Update docs with clear URL configuration (removed confusing :3001 port) - Match Slack's URL pattern with gateway-host placeholder - Clarify local dev (ngrok) vs production (reverse proxy) setup --- docs/channels/zoom.md | 22 ++++++++++++++-------- extensions/zoom/src/channel.ts | 4 ++-- src/channels/plugins/onboarding/zoom.ts | 22 +++++++++++++++++++++- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/docs/channels/zoom.md b/docs/channels/zoom.md index 787689678..18199a0bf 100644 --- a/docs/channels/zoom.md +++ b/docs/channels/zoom.md @@ -10,10 +10,12 @@ Status: production-ready plugin for Zoom Team Chat direct messages via Team Chat ## Quick setup -1) Create a 'General App; in [Zoom App Marketplace](https://marketplace.zoom.us/develop/create) +1) Create a 'General App' in [Zoom App Marketplace](https://marketplace.zoom.us/develop/create) 2) Enable the Team Chat surface and note your credentials (Client ID, Client Secret, Bot JID, Webhook Secret Token) 3) Install the plugin: `pnpm install` (the zoom extension is included in the workspace) -4) Configure webhook URL pointing to your gateway (see Webhook Setup below) +4) Configure URLs (see URL Configuration below): + - Webhook URL: `https://gateway-host/webhooks/zoom` + - OAuth Redirect URL: `https://gateway-host/api/zoomapp/auth` 5) Set credentials in config: ```json5 { @@ -52,20 +54,24 @@ Status: production-ready plugin for Zoom Team Chat direct messages via Team Chat - **Bot JID** (e.g., `bot@xmppdev.zoom.us`) - **Secret Token** (for webhook verification) -### 2. Configure Webhooks +### 2. Configure URLs -The bot receives messages through webhooks. Configure the webhook URL in your Zoom app settings: +Configure these URLs in your Zoom app settings: -**Development (using tunnel):** +**Webhook URL** (for receiving messages): ``` -https://YOUR-SUBDOMAIN.frp.zoomappgo.cloud/webhooks/zoom +https://gateway-host/webhooks/zoom ``` -**Production:** +**OAuth Redirect URL** (for app installation): ``` -https://your-domain.com/webhooks/zoom +https://gateway-host/api/zoomapp/auth ``` +Replace `gateway-host` with: +- **Local development**: Use ngrok (`ngrok http 3001`) or another tunnel service to expose port 3001 +- **Production**: Your server's public domain (configure reverse proxy to forward to port 3001) + Subscribe to these event types: - `bot_notification` - Required for receiving messages diff --git a/extensions/zoom/src/channel.ts b/extensions/zoom/src/channel.ts index 6c835336b..e0c78eba9 100644 --- a/extensions/zoom/src/channel.ts +++ b/extensions/zoom/src/channel.ts @@ -75,12 +75,12 @@ export const zoomPlugin: ChannelPlugin = { allowFrom: account.config.dm?.allowFrom ?? [], allowFromPath: "channels.zoom.dm.", approveHint: "Send a message to the bot to get started", - normalizeEntry: (raw) => raw.trim(), + normalizeEntry: (raw) => String(raw ?? "").trim(), }), collectWarnings: () => [], }, messaging: { - normalizeTarget: (target) => target.trim(), + normalizeTarget: (target) => String(target ?? "").trim(), targetResolver: { looksLikeId: (input) => input.includes("@xmpp") || input.includes("@xmppdev"), hint: "", diff --git a/src/channels/plugins/onboarding/zoom.ts b/src/channels/plugins/onboarding/zoom.ts index 6b30f0c36..8cb7f1288 100644 --- a/src/channels/plugins/onboarding/zoom.ts +++ b/src/channels/plugins/onboarding/zoom.ts @@ -35,7 +35,7 @@ async function noteZoomHelp(prompter: WizardPrompter): Promise { "1) Go to Zoom App Marketplace (marketplace.zoom.us/develop/create)", "2) Create a Team Chat App and enable Bot feature", "3) Copy Client ID, Client Secret, Bot JID, and Secret Token", - "4) Configure webhook URL to point to your gateway", + "4) You'll configure webhook and OAuth redirect URLs after setup", `Docs: ${formatDocsLink("/channels/zoom")}`, "Website: https://molt.bot", ].join("\n"), @@ -150,6 +150,26 @@ export const zoomOnboardingAdapter: ChannelOnboardingAdapter = { }, }; + // Show URL configuration instructions + await prompter.note( + [ + "IMPORTANT: Configure these URLs in your Zoom app:", + "", + "Webhook URL (for receiving messages):", + " https://gateway-host/webhooks/zoom", + "", + "OAuth Redirect URL (for app installation):", + " https://gateway-host/api/zoomapp/auth", + "", + "Replace gateway-host with:", + "- For local dev: Use ngrok (ngrok http 3001)", + "- For production: Your server's public domain", + "", + "Subscribe to event type: bot_notification", + ].join("\n"), + "Zoom URL Configuration Required", + ); + return { cfg: next }; }, dmPolicy,