Гид по технологиям

Генерация ссылок Zoom через Server-to-Server OAuth на Python

5 min read Интеграция Обновлено 21 Dec 2025
Zoom: генерировать ссылки через Server-to-Server OAuth на Python
Zoom: генерировать ссылки через Server-to-Server OAuth на Python

Код Python и рука, держащая мобильный телефон

Зачем переходить на Server-to-Server OAuth

Zoom объявил об устаревании JWT-приложений. Если ваше приложение зависит от JWT для доступа к API Zoom, вам нужно переключиться до отключения сервиса. Есть два основных варианта:

  • OAuth (user-level): требует, чтобы пользователи авторизовали ваше приложение через их Zoom-аккаунты. Подходит, если вы действуете от имени конкретного пользователя.
  • Server-to-Server OAuth (account-level): даёт приложению доступ к API от имени аккаунта Zoom без вмешательства пользователя. Подходит для автоматической генерации ссылок, планировщика встреч и интеграций на серверной стороне.

Важно: S2S — лучший выбор, когда вы создаёте ссылки на встречи централизованно и не требуете явного согласия каждого пользователя.

Создание Server-to-Server OAuth приложения в Zoom Marketplace

  1. Перейдите в Zoom Marketplace и нажмите создать новое приложение.
  2. Пролистайте до баннера Server-to-Server OAuth и нажмите Создать.

Zoom Marketplace — выбор Server-to-Server OAuth

  1. Введите название приложения и подтвердите создание. Вы попадёте на панель управления приложением.

Модальное окно для ввода названия приложения

  1. Скопируйте все учётные данные: Account ID, Client ID и Client Secret. Сохраните их в безопасном месте (например, в переменных окружения или менеджере секретов).

Панель с учётными данными приложения

  1. Заполните «Основную информацию» (Basic information) и продолжите.

Панель информации о приложении

  1. На странице функций нажмите Продолжить и затем Add Scopes. Для создания встреч добавьте минимально необходимые области (scopes): «Get a meeting’s encoded SIP URI» и «View and manage all user meetings» (эквивалент прав на просмотр и управление встречами).

Добавление scope для доступа к встречам

  1. Нажмите Continue, затем Activate your app. После активации приложение сможет запрашивать токены для аккаунта.

Страница активации приложения Zoom

Important: храните Client Secret и Account ID в защищённом хранилище. Не публикуйте их в репозиториях.

Python: реализация создания встречи через S2S OAuth

Ниже — более аккуратная и надёжная версия функции для запроса токена и создания встречи. Скрипт использует requests и стандартный модуль datetime.

import os
import requests
from datetime import datetime, timezone

# Получите эти значения из защищённых переменных окружения
CLIENT_ID = os.environ.get("ZOOM_CLIENT_ID")
CLIENT_SECRET = os.environ.get("ZOOM_CLIENT_SECRET")
ACCOUNT_ID = os.environ.get("ZOOM_ACCOUNT_ID")

AUTH_TOKEN_URL = "https://zoom.us/oauth/token"
API_BASE_URL = "https://api.zoom.us/v2"

class ZoomError(Exception):
    pass

def get_s2s_access_token(client_id: str, client_secret: str, account_id: str) -> str:
    """Получить токен доступа для Server-to-Server OAuth."""
    data = {
        "grant_type": "account_credentials",
        "account_id": account_id
    }
    # Basic auth с client_id:client_secret
    resp = requests.post(AUTH_TOKEN_URL, auth=(client_id, client_secret), data=data, timeout=10)
    if resp.status_code != 200:
        raise ZoomError(f"Не удалось получить токен: {resp.status_code} {resp.text}")
    token_data = resp.json()
    return token_data.get("access_token")

def create_meeting(topic: str, duration_minutes: int, start_dt: datetime) -> dict:
    """Создать встречу и вернуть ответ API как dict.

    start_dt должен быть timezone-aware в UTC или с указанным часовым поясом.
    """
    if start_dt.tzinfo is None:
        # Предполагаем, что переданное время локальное — переводим в UTC
        start_dt = start_dt.replace(tzinfo=timezone.utc)
    access_token = get_s2s_access_token(CLIENT_ID, CLIENT_SECRET, ACCOUNT_ID)

    headers = {
        "Authorization": f"Bearer {access_token}",
        "Content-Type": "application/json"
    }

    payload = {
        "topic": topic,
        "type": 2,  # Запланированная встреча
        "start_time": start_dt.astimezone(timezone.utc).isoformat(),
        "duration": int(duration_minutes)
    }

    resp = requests.post(f"{API_BASE_URL}/users/me/meetings", headers=headers, json=payload, timeout=10)
    if resp.status_code != 201:
        raise ZoomError(f"Не удалось создать встречу: {resp.status_code} {resp.text}")
    return resp.json()

Примеры использования:

from datetime import datetime, timezone, timedelta

# Спланируем встречу на 23 августа 2023, 18:24 (UTC+3)
local_ts = datetime(2023, 8, 23, 18, 24)
# Явно задаём часовой пояс, если нужно: UTC+3
# local_ts = local_ts.replace(tzinfo=timezone(timedelta(hours=3)))
# В демонстрации используем UTC
local_ts = local_ts.replace(tzinfo=timezone.utc)

try:
    result = create_meeting("Test Zoom Meeting", 60, local_ts)
    print("Ссылка:", result.get("join_url"))
    print("Пароль:", result.get("password"))
except Exception as e:
    print("Ошибка:", e)

Notes: Zoom ожидает start_time в ISO 8601. В примере мы приводим время к UTC и используем .isoformat(). Это снижает ошибки, связанные с часовыми поясами.

Что возвращает API

API вернёт JSON с множеством полей: join_url, start_time, duration, password, id и т. п. Выберите только те поля, которые вам нужны. Пример полезных полей:

  • join_url — публичная ссылка для присоединения
  • password — пароль к встрече (если есть)
  • start_time — время старта в ISO 8601
  • id — идентификатор встречи

Интеграция в приложение

Вы можете поместить функцию create_meeting в слой сервиса вашего приложения (Django/Flask/FastAPI). Если создаёте API-эндпоинт, обеспечьте авторизацию клиентов, логирование и лимитирование запросов.

Пример маршрута (FastAPI):

from fastapi import FastAPI, HTTPException

app = FastAPI()

@app.post('/meetings')
async def meetings_create(payload: dict):
    try:
        meeting = create_meeting(payload['topic'], payload['duration'], payload['start_dt'])
        return meeting
    except ZoomError as e:
        raise HTTPException(status_code=500, detail=str(e))

Когда этот подход НЕ подходит

  • Вам нужно действовать от имени конкретного пользователя и запрашивать его доступ — используйте OAuth с авторизацией пользователя.
  • Необходимо управлять личными настройками пользователя, доступ к которым требует явного согласия.
  • Если вы раздаёте права сторонним приложениям, S2S даёт доступ на уровне аккаунта — оцените риски.

Альтернативные подходы

  • Полноценный OAuth (консенсус пользователя) — когда нужна явная авторизация пользователя.
  • Прямые интеграции через Zoom SDK для клиентских приложений — если нужно полностью встраивать UI/AV функциональность.

Чек-лист ролей

Для ускоренной проверки развертывания:

  • Админ Zoom:

    • Создал S2S-приложение и активировал его.
    • Ограничил scopes до необходимых.
    • Сохранил Account ID, Client ID и Client Secret в безопасном хранилище.
  • Разработчик:

    • Внёс секреты в переменные окружения или секрет-менеджер.
    • Реализовал обработку ошибок и таймауты.
    • Привёл start_time к ISO 8601 (UTC) и проверил часовые пояса.
  • DevOps / SRE:

    • Настроил сеть/файрволы и HTTPS.
    • Настроил ротацию секретов и мониторинг ошибок.

Критерии приёмки

  • Эндпоинт создаёт встречу и возвращает 201/успешный JSON с join_url.
  • Секреты не хранятся в коде и доступны только через защищённое хранилище.
  • Логи не содержат Client Secret или полных токенов доступа.

Безопасность и конфиденциальность

  • Храните Client Secret и Account ID в менеджере секретов (HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager).
  • Ограничьте права S2S приложения только необходимыми scopes.
  • Логи: маскируйте чувствительные поля и храните только минимальные сведения.
  • Ротация ключей: периодически обновляйте Client Secret.
  • Для соответствия локальным требованиям безопасности (например, GDPR) минимизируйте передачу персональных данных и описывайте назначение хранения данных в политике конфиденциальности.

Уязвимости и способы их уменьшения

  • Утечка секретов — используйте менеджер секретов и IAM-права.
  • Компрометация токенов — сократите время жизни сессий и контролируйте доступ.
  • Ошибки часовых поясов — всегда храните и передавайте время в ISO 8601 (UTC).

Краткое резюме

Server-to-Server OAuth — правильный выбор, если вы хотите централизованно создавать встречи Zoom без участия пользователей. Создайте S2S-приложение в Zoom Marketplace, сохраните учётные данные в безопасном месте и используйте приведённую функцию на Python для получения токена и создания встречи. Обязательно реализуйте обработку ошибок, логирование без секретов и корректную работу с часовыми поясами.

Important: перед развёртыванием в проде протестируйте создание встреч в тестовом аккаунте и проверьте ограничения вашего тарифного плана Zoom.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Как изменить фон в браузере Brave
Руководство

Как изменить фон в браузере Brave

Язык отдельных приложений на iPhone и Mac
Руководство

Язык отдельных приложений на iPhone и Mac

Как заблокировать сабреддиты на Reddit
Инструкции

Как заблокировать сабреддиты на Reddit

Material You: тема Android по обоям
Android.

Material You: тема Android по обоям

Удаление белого фона в Adobe Illustrator
Дизайн

Удаление белого фона в Adobe Illustrator

Включение Universal Control в macOS Monterey
macOS

Включение Universal Control в macOS Monterey