partner-built/zoom-plugin/skills/team-chat/SKILL.md
Reference skill for Zoom Team Chat. Use after routing to a chat workflow when building user-scoped messaging integrations, chatbot experiences, rich cards, buttons, slash commands, or chat webhooks.
npx skillsauth add anthropics/knowledge-work-plugins build-zoom-team-chat-appInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
4 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Background reference for Zoom Team Chat integrations. Use this after the workflow is clear, especially when the Team Chat API versus Chatbot API distinction matters.
There are two different integration types and they are not interchangeable:
Team Chat API (user type)
authorization_code)/v2/chat/users/...Chatbot API (bot type)
client_credentials)/v2/im/chat/messagesIf you choose the wrong type early, auth/scopes/endpoints all mismatch and implementation fails.
Official Documentation: https://developers.zoom.us/docs/team-chat/
Chatbot Documentation: https://developers.zoom.us/docs/team-chat/chatbot/extend/
API Reference: https://developers.zoom.us/docs/api/rest/reference/chatbot/
New to Team Chat? Follow this path:
Reference:
Having issues?
OAuth endpoint sanity check:
https://zoom.us/oauth/authorizehttps://zoom.us/oauth/token/oauth/token returns 404/HTML, use https://zoom.us/oauth/token.Building Interactive Bots?
| Use Case | API to Use | |----------|------------| | Send notifications from scripts/CI/CD | Team Chat API | | Automate messages as a user | Team Chat API | | Build an interactive chatbot | Chatbot API | | Respond to slash commands | Chatbot API | | Create messages with buttons/forms | Chatbot API | | Handle user interactions | Chatbot API |
POST https://api.zoom.us/v2/chat/users/me/messageschat_message:write, chat_channel:readPOST https://api.zoom.us/v2/im/chat/messagesimchat:bot (auto-added)⚠️ Do NOT use Server-to-Server OAuth - S2S apps don't have the Chatbot/Team Chat feature. Only General App (OAuth) supports chatbots.
From Zoom Marketplace → Your App:
| Credential | Location | Used By | |------------|----------|---------| | Client ID | App Credentials → Development | Both APIs | | Client Secret | App Credentials → Development | Both APIs | | Account ID | App Credentials → Development | Chatbot API | | Bot JID | Features → Chatbot → Bot Credentials | Chatbot API | | Secret Token | Features → Team Chat Subscriptions | Chatbot API |
See: Environment Setup Guide for complete configuration steps.
Send a message as a user:
// 1. Get access token via OAuth
const accessToken = await getOAuthToken(); // See examples/oauth-setup.md
// 2. Send message to channel
const response = await fetch('https://api.zoom.us/v2/chat/users/me/messages', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
message: 'Hello from CI/CD pipeline!',
to_channel: 'CHANNEL_ID'
})
});
const data = await response.json();
// { "id": "msg_abc123", "date_time": "2024-01-15T10:30:00Z" }
Complete example: Send Message Guide
Build an interactive chatbot:
// 1. Get chatbot token (client_credentials)
async function getChatbotToken() {
const credentials = Buffer.from(
`${CLIENT_ID}:${CLIENT_SECRET}`
).toString('base64');
const response = await fetch('https://zoom.us/oauth/token', {
method: 'POST',
headers: {
'Authorization': `Basic ${credentials}`,
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'grant_type=client_credentials'
});
return (await response.json()).access_token;
}
// 2. Send chatbot message with buttons
const response = await fetch('https://api.zoom.us/v2/im/chat/messages', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
robot_jid: process.env.ZOOM_BOT_JID,
to_jid: payload.toJid, // From webhook
account_id: payload.accountId, // From webhook
content: {
head: {
text: 'Build Notification',
sub_head: { text: 'CI/CD Pipeline' }
},
body: [
{ type: 'message', text: 'Deployment successful!' },
{
type: 'fields',
items: [
{ key: 'Branch', value: 'main' },
{ key: 'Commit', value: 'abc123' }
]
},
{
type: 'actions',
items: [
{ text: 'View Logs', value: 'view_logs', style: 'Primary' },
{ text: 'Dismiss', value: 'dismiss', style: 'Default' }
]
}
]
}
})
});
Complete example: Chatbot Setup Guide
| Feature | Description | |---------|-------------| | Send Messages | Post messages to channels or direct messages | | List Channels | Get user's channels with metadata | | Create Channels | Create public/private channels programmatically | | Threaded Replies | Reply to specific messages in threads | | Edit/Delete | Modify or remove messages |
| Feature | Description |
|---------|-------------|
| Rich Message Cards | Headers, images, fields, buttons, forms |
| Slash Commands | Custom /commands trigger webhooks |
| Button Actions | Interactive buttons with webhook callbacks |
| Form Submissions | Collect user input with forms |
| Dropdown Selects | Channel, member, date/time pickers |
| LLM Integration | Easy integration with Claude, GPT, etc. |
| Event | Trigger | Use Case |
|-------|---------|----------|
| bot_notification | User messages bot or uses slash command | Process commands, integrate LLM |
| bot_installed | Bot added to account | Initialize bot state |
| interactive_message_actions | Button clicked | Handle button actions |
| chat_message.submit | Form submitted | Process form data |
| app_deauthorized | Bot removed | Cleanup |
See: Webhook Events Reference
Build rich interactive messages with these components:
| Component | Description | |-----------|-------------| | header | Title and subtitle | | message | Plain text | | fields | Key-value pairs | | actions | Buttons (Primary, Danger, Default styles) | | section | Colored sidebar grouping | | attachments | Images with links | | divider | Horizontal line | | form_field | Text input | | dropdown | Select menu | | date_picker | Date selection |
See: Message Cards Reference for complete component catalog
User types /command → Webhook receives bot_notification
↓
payload.cmd = "user's input"
↓
Process command
↓
Send response via sendChatbotMessage()
case 'bot_notification': {
const { toJid, cmd, accountId } = payload;
// 1. Call your LLM
const llmResponse = await callClaude(cmd);
// 2. Send response back
await sendChatbotMessage(toJid, accountId, {
body: [{ type: 'message', text: llmResponse }]
});
}
See: LLM Integration Guide
| Sample | Description | Link | |--------|-------------|------| | Chatbot Quickstart | Official tutorial (recommended start) | GitHub | | Claude Chatbot | AI chatbot with Anthropic Claude | GitHub | | Unsplash Chatbot | Image search with database | GitHub | | ERP Chatbot | Oracle ERP with scheduled alerts | GitHub | | Task Manager | Full CRUD app | GitHub |
See: Sample Applications Guide for analysis of all 10 samples
// Team Chat API
await fetch('https://api.zoom.us/v2/chat/users/me/messages', {
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` },
body: JSON.stringify({
message: 'Hello!',
to_channel: 'CHANNEL_ID'
})
});
// Webhook handler
case 'interactive_message_actions': {
const { actionItem, toJid, accountId } = payload;
if (actionItem.value === 'approve') {
await sendChatbotMessage(toJid, accountId, {
body: [{ type: 'message', text: '✅ Approved!' }]
});
}
}
function verifyWebhook(req) {
const message = `v0:${req.headers['x-zm-request-timestamp']}:${JSON.stringify(req.body)}`;
const hash = crypto.createHmac('sha256', process.env.ZOOM_VERIFICATION_TOKEN)
.update(message)
.digest('hex');
return req.headers['x-zm-signature'] === `v0=${hash}`;
}
# Install ngrok
npm install -g ngrok
# Expose local server
ngrok http 4000
# Use HTTPS URL as Bot Endpoint URL in Zoom Marketplace
# Example: https://abc123.ngrok.io/webhook
See: Deployment Guide for:
| Limit | Value | |-------|-------| | Message length | 4,096 characters | | File size | 512 MB | | Members per channel | 10,000 | | Channels per user | 500 |
x-zm-signature headeruser@domain or channel@domainSee: Security Best Practices
Need help? Start with Integrated Index section below for complete navigation.
This section was migrated from SKILL.md.
Complete navigation guide for the Zoom Team Chat skill.
For sending messages as a user account.
For building interactive chatbots with rich messages.
Essential understanding for both APIs.
| Document | Description | |----------|-------------| | API Selection Guide | Choose Team Chat API vs Chatbot API | | Environment Setup | Complete credentials and app configuration | | Authentication Flows | OAuth vs Client Credentials | | Webhook Architecture | How webhooks work (Chatbot API) | | Message Card Structure | Card component hierarchy | | Deployment Guide | Production deployment strategies | | Security Best Practices | Secure your integration |
Working code for common scenarios.
| Example | Description | |---------|-------------| | OAuth Setup | User OAuth flow implementation | | Token Management | Refresh tokens, expiration handling |
| Example | Description | |---------|-------------| | Send Message | Team Chat API message sending | | Chatbot Setup | Complete chatbot with webhooks | | List Channels | Get user's channels | | Create Channel | Create public/private channels |
| Example | Description | |---------|-------------| | Button Actions | Handle button clicks | | Form Submissions | Process form data | | Slash Commands | Create custom commands | | Dropdown Selects | Channel/member pickers |
| Example | Description | |---------|-------------| | LLM Integration | Integrate Claude/GPT | | Scheduled Alerts | Cron + incoming webhooks | | Database Integration | Store conversation state | | Multi-Step Workflows | Complex user interactions |
| Reference | Description | |-----------|-------------| | API Reference | Pointers and common endpoints | | Webhook Events | Event types and handling checklist | | Message Cards | All card components | | Error Codes | Error handling guide |
| Reference | Description | |-----------|-------------| | Sample Applications | Sample app index/notes |
| Reference | Description | |-----------|-------------| | JID Formats | Understanding JID identifiers | | Scopes Reference | Common scopes | | Rate Limits | Throttling guidance |
| Guide | Description | |-------|-------------| | Common Issues | Quick diagnostics and solutions | | OAuth Issues | Authentication failures | | Webhook Issues | Webhook debugging | | Message Issues | Message sending problems | | Deployment Issues | Production problems |
User Action → Webhook → Process → Response
User Input → Chatbot receives → Call LLM → Send response
Request → Send card with buttons → User clicks → Update status → Notify
Use this SKILL.md as the navigation hub for Team Chat API selection, setup, examples, and troubleshooting.
.env keys and where to find each value.testing
Reads a forwarded customer email or ticket, pulls order/refund status from PayPal and account history from HubSpot, drafts a tone-matched reply in the owner's writing voice, and can issue a PayPal refund with explicit owner approval. Use when the user says "draft a response," "answer this customer," "where's my order," or "I want a refund."
development
Prepares tax-season materials for small business owners — framed as deliverables for their accountant, not tax advice. Two modes: (1) quarterly estimated tax calculation — pulls YTD net income from QuickBooks and calculates the federal income tax + self-employment tax liability and quarterly payment due; (2) year-end 1099 prep — scans QuickBooks, PayPal, and Stripe for contractors paid over $600, builds a 1099-NEC candidate list with missing W-9 flags, and produces a plain-English summary a CPA can work from directly. Trigger this skill whenever the user mentions: quarterly taxes, estimated tax payment, how much to set aside for taxes, 1099s, 1099-NEC, year-end tax prep, contractor payments, W-9s, or any phrase suggesting they are preparing for a tax deadline or handing materials to an accountant. Also trigger proactively when a user asks about net profit or YTD income in a context that suggests they are worried about their tax bill.
tools
Prepares tax-season materials — quarterly estimated tax calculation or year-end 1099 prep — and produces an accountant handoff packet. Accepts optional mode and year arguments.
tools
The front door to the Small Business plugin. Listens to what the owner needs right now — vague or specific — and routes them to the best skill or slash command for the moment. Also serves as a guide: explains what's available, suggests what to try next, and adapts recommendations based on stored business context. Trigger whenever the owner asks "what can you do," "help me with my business," "what should I focus on," "I don't know where to start," or any open-ended business request that doesn't clearly match a single skill.