---
title: "Zoom 连接器"
description: "完整的 Zoom 集成指南，通过 Tajo 将会议参与者、网络研讨会出席者和互动数据与 Brevo 同步。"
url: https://tajo.io/zh-cn/docs/connectors/custom/zoom/
markdown: https://tajo.io/zh-cn/docs/connectors/custom/zoom.md
lang: zh-CN
robots: noindex
---

申请抢先体验

请输入您的名字和公司电子邮箱地址。我们会发送确认 Tajo 访问申请的链接。

# Zoom 连接器

连接器状态: 计划中 尚未构建。Tajo 目前不运行此连接器。

| 来源字段 | 目标字段 | 示例值 |
| --- | --- | --- |
| `record.id` | `source_id` | `record_1042` |
| `record.updated_at` | `updated_at` | `2026-10-18T08:00:00Z` |
| `record.value` | `value` | `sample_value` |

通过 Tajo 将 Zoom 连接到 Brevo，自动将会议参与者和网络研讨会出席者同步为联系人，触发会议后跟进序列，并追踪营销自动化的互动指标。

## 概览

| 属性 | 值 |
| --- | --- |
| **平台** | Zoom |
| **类别** | 视频会议（自定义） |
| **设置复杂度** | 中等 |
| **官方集成** | 否 |
| **同步数据** | 参与者、事件、网络研讨会、联系人 |
| **认证方式** | OAuth 2.0 / 服务器对服务器 OAuth |

## 功能

- **参与者同步** - 从会议参与者自动创建 Brevo 联系人
- **网络研讨会出席者捕获** - 同步网络研讨会注册者和出席者
- **会议事件触发** - 在会议开始、结束和录制事件时触发自动化
- **互动追踪** - 追踪出席时长和参与度指标
- **网络研讨会跟进** - 根据出席情况触发精准邮件序列
- **录制通知** - 通过 Brevo 邮件活动发送录制链接

## 前提条件

开始之前，请确保您已具备：

1. Zoom 账户（专业版或以上）
2. 通过 [Zoom 应用市场](https://marketplace.zoom.us/) 创建的 Zoom 服务器对服务器 OAuth 应用或 OAuth 应用
3. 具有 API 访问权限的 Brevo 账户
4. 具有连接器权限的 Tajo 账户

## 认证

### 服务器对服务器 OAuth（推荐）

```bash
# Create a Server-to-Server OAuth app at marketplace.zoom.us
export ZOOM_ACCOUNT_ID=your_account_id
export ZOOM_CLIENT_ID=your_client_id
export ZOOM_CLIENT_SECRET=your_client_secret
```

```javascript
// Get access token via Server-to-Server OAuth
const tokenResponse = await fetch('https://zoom.us/oauth/token', {
  method: 'POST',
  headers: {
    'Authorization': `Basic ${Buffer.from(
      `${process.env.ZOOM_CLIENT_ID}:${process.env.ZOOM_CLIENT_SECRET}`
    ).toString('base64')}`,
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  body: new URLSearchParams({
    grant_type: 'account_credentials',
    account_id: process.env.ZOOM_ACCOUNT_ID
  })
});

const { access_token } = await tokenResponse.json();
```

### OAuth 2.0（用户级）

```javascript
// Authorization URL for user-level OAuth
const authUrl = 'https://zoom.us/oauth/authorize?' +
  new URLSearchParams({
    client_id: process.env.ZOOM_CLIENT_ID,
    redirect_uri: 'https://your-app.com/callback',
    response_type: 'code'
  });

// Exchange code for tokens
const tokenResponse = await fetch('https://zoom.us/oauth/token', {
  method: 'POST',
  headers: {
    'Authorization': `Basic ${Buffer.from(
      `${process.env.ZOOM_CLIENT_ID}:${process.env.ZOOM_CLIENT_SECRET}`
    ).toString('base64')}`,
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  body: new URLSearchParams({
    grant_type: 'authorization_code',
    code: authorizationCode,
    redirect_uri: 'https://your-app.com/callback'
  })
});
```

## 配置

### 基础设置

```yaml
connectors:
  zoom:
    enabled: true
    account_id: "${ZOOM_ACCOUNT_ID}"
    client_id: "${ZOOM_CLIENT_ID}"
    client_secret: "${ZOOM_CLIENT_SECRET}"

    sync:
      participants: true
      webinars: true
      recordings: true

    webhook:
      secret_token: "${ZOOM_WEBHOOK_SECRET}"
      verification_token: "${ZOOM_VERIFICATION_TOKEN}"

    lists:
      meeting_participants: 15
      webinar_attendees: 16
      webinar_registrants: 17
```

### 字段映射

```yaml
field_mapping:
  email: email
  name: FIRSTNAME
  join_time: MEETING_JOIN_DATE
  duration: MEETING_DURATION
  webinar_title: WEBINAR_NAME
  attendance_status: ATTENDANCE_STATUS
  registration_source: UTM_SOURCE
```

## API 端点

| 端点 | 方法 | 描述 |
| --- | --- | --- |
| `https://api.zoom.us/v2/users` | GET | 列出用户 |
| `https://api.zoom.us/v2/users/{userId}/meetings` | GET | 列出会议 |
| `https://api.zoom.us/v2/meetings/{meetingId}` | GET | 获取会议详情 |
| `https://api.zoom.us/v2/past_meetings/{meetingId}/participants` | GET | 列出历史会议参与者 |
| `https://api.zoom.us/v2/users/{userId}/webinars` | GET | 列出网络研讨会 |
| `https://api.zoom.us/v2/webinars/{webinarId}/registrants` | GET | 列出网络研讨会注册者 |
| `https://api.zoom.us/v2/webinars/{webinarId}/participants` | GET | 列出网络研讨会参与者 |
| `https://api.zoom.us/v2/meetings/{meetingId}/recordings` | GET | 获取会议录制 |
| `https://api.zoom.us/v2/webhooks` | POST | 订阅 Webhook |

## 代码示例

### 初始化连接器

```javascript
import { TajoClient } from '@tajo/sdk';

const tajo = new TajoClient({
  apiKey: process.env.TAJO_API_KEY,
  brevoApiKey: process.env.BREVO_API_KEY
});

await tajo.connectors.connect('zoom', {
  accountId: process.env.ZOOM_ACCOUNT_ID,
  clientId: process.env.ZOOM_CLIENT_ID,
  clientSecret: process.env.ZOOM_CLIENT_SECRET
});
```

### 同步会议参与者

```javascript
// Retrieve past meeting participants
const response = await fetch(
  `https://api.zoom.us/v2/past_meetings/${meetingId}/participants`,
  {
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    }
  }
);

const { participants } = await response.json();

for (const participant of participants) {
  if (participant.user_email) {
    await tajo.contacts.sync({
      email: participant.user_email,
      attributes: {
        FIRSTNAME: participant.name,
        MEETING_DURATION: participant.duration,
        MEETING_JOIN_DATE: participant.join_time,
        ATTENDANCE_STATUS: 'attended'
      },
      listIds: [15]
    });
  }
}
```

### 同步网络研讨会出席者

```javascript
// Get webinar attendees and sync to Brevo
const attendeesResponse = await fetch(
  `https://api.zoom.us/v2/past_webinars/${webinarId}/participants`,
  {
    headers: { 'Authorization': `Bearer ${accessToken}` }
  }
);

const { participants: attendees } = await attendeesResponse.json();

for (const attendee of attendees) {
  await tajo.contacts.sync({
    email: attendee.user_email,
    attributes: {
      FIRSTNAME: attendee.name,
      WEBINAR_NAME: webinarTitle,
      ATTENDANCE_STATUS: 'attended',
      MEETING_DURATION: attendee.duration
    },
    listIds: [16]
  });
}
```

### 处理 Zoom Webhook

```javascript
app.post('/webhooks/zoom', async (req, res) => {
  // Handle Zoom URL validation challenge
  if (req.body.event === 'endpoint.url_validation') {
    const hashForValidation = crypto
      .createHmac('sha256', process.env.ZOOM_WEBHOOK_SECRET)
      .update(req.body.payload.plainToken)
      .digest('hex');

    return res.json({
      plainToken: req.body.payload.plainToken,
      encryptedToken: hashForValidation
    });
  }

  // Verify webhook signature
  const message = `v0:${req.headers['x-zm-request-timestamp']}:${JSON.stringify(req.body)}`;
  const hash = crypto
    .createHmac('sha256', process.env.ZOOM_WEBHOOK_SECRET)
    .update(message)
    .digest('hex');
  const signature = `v0=${hash}`;

  if (req.headers['x-zm-signature'] !== signature) {
    return res.status(401).send('Unauthorized');
  }

  const { event, payload } = req.body;

  await tajo.connectors.handleWebhook('zoom', {
    topic: event,
    payload: payload
  });

  res.status(200).send('OK');
});
```

## 速率限制

| 类别 | 限制 | 说明 |
| --- | --- | --- |
| 轻量 API 调用 | 30 请求/秒 | 获取用户、会议信息 |
| 中量 API 调用 | 20 请求/秒 | 列出参与者、网络研讨会 |
| 重量 API 调用 | 10 请求/秒 | 报告、录制 |
| 每日限制 | 5,000+ | 取决于套餐级别 |

速率限制头部

Zoom 返回 `X-RateLimit-Limit`、`X-RateLimit-Remaining` 和 `Retry-After` 头部。根据这些头部实施退避逻辑以避免 429 错误。

## 故障排除

| 问题 | 原因 | 解决方案 |
| --- | --- | --- |
| 401 Unauthorized | 令牌已过期 | 刷新服务器对服务器 OAuth 令牌 |
| 参与者缺失 | 会议尚未结束 | 等待会议结束后获取完整数据 |
| Webhook 验证失败 | 密钥错误 | 在 Zoom 应用市场中验证 Webhook 密钥 |
| 无邮箱数据 | 访客参与者 | 启用注册以捕获邮箱 |
| 速率限制 429 | 请求过多 | 实施指数退避 |

### 调试模式

```yaml
connectors:
  zoom:
    debug: true
    log_level: verbose
    log_webhooks: true
```

## 最佳实践

1. **使用服务器对服务器 OAuth** - 无需用户交互的更简单认证
2. **启用网络研讨会注册** - 捕获出席者邮箱地址所必需
3. **会议结束后处理** - 参与者数据只在会议结束后才完整
4. **按事件类型细分** - 为会议和网络研讨会分配不同的 Brevo 列表
5. **追踪互动指标** - 使用时长和加入时间进行线索评分
6. **发送录制跟进** - 通过 Brevo 自动化投递录制链接

## 安全

- **OAuth 2.0** - 服务器对服务器或用户级 OAuth 认证
- **Webhook 验证** - HMAC-SHA256 签名验证
- **URL 验证** - Webhook 端点的挑战响应验证
- **范围权限** - 请求最低所需的 OAuth 范围
- **令牌轮换** - 服务器对服务器令牌自动过期（1 小时）
- **加密传输** - 所有 API 通信使用 TLS 1.2+

## 相关资源

- [Calendly 连接器](https://tajo.io/zh-cn/docs/connectors/custom/calendly)
- [Zapier 连接器](https://tajo.io/zh-cn/docs/connectors/custom/zapier)
- [客户同步技能](https://tajo.io/zh-cn/docs/skills/data-sync/customer-sync)
- [Zoom API 文档](https://developers.zoom.us/docs/api/)
