zoom-apps-sdk

Par anthropics · knowledge-work-plugins

Compétence de référence pour le SDK Zoom Apps. À utiliser après le routage vers un workflow d'application in-client lors de la création d'applications web s'exécutant dans des réunions Zoom, des webinaires, le client principal ou Zoom Phone.

npx skills add https://github.com/anthropics/knowledge-work-plugins --skill zoom-apps-sdk

SDK Zoom Apps

Référence de base pour les applications web qui s'exécutent dans le client Zoom. Préférez d'abord choose-zoom-approach, puis naviguez ici pour l'API Layers, le mode Collaborate, OAuth intégré et les contraintes runtime.

SDK Zoom Apps

Construisez des applications web qui s'exécutent dans le client Zoom - réunions, webinaires, client principal et Zoom Phone.

Documentation Officielle : https://developers.zoom.us/docs/zoom-apps/ Référence SDK : https://appssdk.zoom.us/ Package NPM : https://www.npmjs.com/package/@zoom/appssdk

Liens Rapides

Nouveau pour les Zoom Apps ? Suivez ce chemin :

  1. Architecture - Motif frontend/backend, navigateur intégré, deep linking
  2. Démarrage Rapide - Application Express + SDK complète et fonctionnelle
  3. Contextes d'Exécution - Où votre app s'exécute (inMeeting, inMainClient, etc.)
  4. Zoom Apps vs Meeting SDK - Arrêtez de mélanger les types d'apps
  5. OAuth Intégré - Autorisation transparente avec PKCE
  6. Référence API - Plus de 100 méthodes SDK
  7. Index Intégré - voir la section ci-dessous dans ce fichier
  8. Runbook 5 Minutes - Vérifications préalables avant débogage approfondi

Référence :

Vous avez des problèmes ?

Créer des expériences immersives ?

Besoin d'aide avec OAuth ? Consultez la compétence zoom-oauth pour les flux d'authentification.

Aperçu du SDK

Le SDK Zoom Apps (@zoom/appssdk) fournit des APIs JavaScript pour les applications web s'exécutant dans le navigateur intégré de Zoom :

  • APIs Contexte - Obtenir les informations de réunion, d'utilisateur et de participants
  • Actions de Réunion - Partager l'app, inviter des participants, ouvrir des URLs
  • Autorisation - OAuth intégré avec PKCE (pas de redirection de navigateur)
  • API Layers - Dispositions vidéo immersives et superpositions de caméra virtuelle
  • Mode Collaborate - État d'app partagé entre participants
  • Communication d'App - Passage de messages entre instances d'app (client principal <-> réunion)
  • Contrôles Media - Arrière-plans virtuels, liste de caméras, contrôle d'enregistrement
  • Contrôles UI - Développer l'app, notifications, fenêtre contextuelle
  • Événements - Réagir aux changements d'état de réunion, participants, partage et plus

Prérequis

  • App Zoom configurée en tant que type "Zoom App" sur le Marketplace
  • Identifiants OAuth (Client ID + Secret) avec les portées Zoom Apps
  • Application web (Node.js + Express recommandé)
  • Votre domaine sur la liste blanche dans la liste de domaines autorisés du Marketplace
  • ngrok ou tunnel HTTPS pour le développement local
  • Node.js 18+ (pour le serveur backend)

Démarrage Rapide

Option A : NPM (Recommandé pour les frameworks)

npm install @zoom/appssdk
import zoomSdk from '@zoom/appssdk';

async function init() {
  try {
    const configResponse = await zoomSdk.config({
      capabilities: [
        'shareApp',
        'getMeetingContext',
        'getUserContext',
        'openUrl'
      ],
      version: '0.16'
    });

    console.log('Running context:', configResponse.runningContext);
    // 'inMeeting' | 'inMainClient' | 'inWebinar' | 'inImmersive' | ...

    const context = await zoomSdk.getMeetingContext();
    console.log('Meeting ID:', context.meetingID);
  } catch (error) {
    console.error('Not running inside Zoom:', error.message);
    showDemoMode();
  }
}

Option B : CDN (Vanilla JS)

<script src="https://appssdk.zoom.us/sdk.js"></script>

<script>
// CRITICAL: Do NOT declare "let zoomSdk" - the SDK defines window.zoomSdk globally
// Using "let zoomSdk = ..." causes: SyntaxError: redeclaration of non-configurable global property
let sdk = window.zoomSdk;  // Use a different variable name

async function init() {
  try {
    const configResponse = await sdk.config({
      capabilities: ['shareApp', 'getMeetingContext', 'getUserContext'],
      version: '0.16'
    });

    console.log('Running context:', configResponse.runningContext);
  } catch (error) {
    console.error('Not running inside Zoom:', error.message);
    showDemoMode();
  }
}

function showDemoMode() {
  document.body.innerHTML = '<h1>Preview Mode</h1><p>Open this app inside Zoom to use.</p>';
}

document.addEventListener('DOMContentLoaded', () => {
  init();
  setTimeout(() => { if (!sdk) showDemoMode(); }, 3000);
});
</script>

Critique : Conflit de Variable Globale

Le script CDN définit window.zoomSdk globalement. Ne le redéclarez PAS :

// WRONG - causes SyntaxError in Zoom's embedded browser
let zoomSdk = null;
zoomSdk = window.zoomSdk;

// CORRECT - use different variable name
let sdk = window.zoomSdk;

// ALSO CORRECT - NPM import (no conflict)
import zoomSdk from '@zoom/appssdk';

Ceci ne s'applique qu'à l'approche CDN. L'importation NPM crée une variable à portée de module, aucun conflit.

Aperçu Navigateur / Mode Démo

Le SDK fonctionne uniquement dans le client Zoom. Lors de l'accès dans un navigateur régulier :

  • window.zoomSdk existe mais sdk.config() lève une erreur
  • Implémentez toujours try/catch avec interface de secours
  • Ajoutez un délai d'attente (3 secondes) au cas où le SDK se bloquerait

Liste de Domaines Autorisés (Obligatoire)

Votre app ne chargera PAS dans Zoom à moins que le domaine soit sur la liste blanche.

  1. Allez sur le Marketplace Zoom
  2. Ouvrez votre app -> onglet Feature
  3. Sous Zoom App, trouvez Add Allow List
  4. Ajoutez votre domaine (par ex. yourdomain.com pour la production, xxxxx.ngrok.io pour le dev)

Sans cela, le client Zoom affiche un panneau vide sans message d'erreur.

Portées OAuth (Obligatoire)

Les capacités nécessitent les portées OAuth correspondantes activées sur le Marketplace :

Capacité Portée Requise
getMeetingContext zoomapp:inmeeting
getUserContext zoomapp:inmeeting
shareApp zoomapp:inmeeting
openUrl zoomapp:inmeeting
sendAppInvitation zoomapp:inmeeting
runRenderingContext zoomapp:inmeeting
authorize zoomapp:inmeeting
getMeetingParticipants zoomapp:inmeeting

Pour ajouter des portées : Marketplace -> Votre App -> onglet Scopes -> Ajoutez les portées requises.

Les portées manquantes = la capacité échoue silencieusement ou lève une erreur. Les utilisateurs doivent se réautoriser si vous ajoutez de nouvelles portées.

Contextes d'Exécution

Votre app s'exécute dans différentes surfaces dans Zoom. Le configResponse.runningContext vous indique où :

Contexte Surface Description
inMeeting Barre latérale de réunion Plus courant. APIs de réunion complètes disponibles
inMainClient Panneau du client principal Onglet Accueil. Pas d'APIs de contexte de réunion
inWebinar Barre latérale webinaire Animateur/panéliste. APIs réunion + webinaire
inImmersive API Layers Rendu personnalisé plein écran
inCamera Mode caméra Superposition de caméra virtuelle
inCollaborate Mode Collaborate Contexte d'état partagé
inPhone Zoom Phone App d'appel téléphonique
inChat Team Chat Barre latérale chat

Consultez Contextes d'Exécution pour le comportement et les APIs spécifiques au contexte.

Motif d'Initialisation du SDK

Chaque Zoom App commence par config() :

import zoomSdk from '@zoom/appssdk';

const configResponse = await zoomSdk.config({
  capabilities: [
    // List ALL APIs you will use
    'getMeetingContext',
    'getUserContext',
    'shareApp',
    'openUrl',
    'authorize',
    'onAuthorized'
  ],
  version: '0.16'
});

// configResponse contains:
// {
//   runningContext: 'inMeeting',
//   clientVersion: '5.x.x',
//   unsupportedApis: []  // APIs not supported in this client version
// }

Règles :

  1. config() DOIT être appelée avant toute autre méthode SDK
  2. Seules les capacités listées dans config() sont disponibles
  3. Les capacités doivent correspondre aux portées OAuth sur le Marketplace
  4. Vérifiez unsupportedApis pour la dégradation gracieuse

OAuth Intégré (Résumé)

Meilleure UX pour l'autorisation - pas de redirection de navigateur :

// 1. Get code challenge from your backend
const { codeChallenge, state } = await fetch('/api/auth/challenge').then(r => r.json());

// 2. Trigger in-client authorization
await zoomSdk.authorize({ codeChallenge, state });

// 3. Listen for authorization result
zoomSdk.addEventListener('onAuthorized', async (event) => {
  const { code, state } = event;
  // 4. Send code to backend for token exchange
  await fetch('/api/auth/token', {
    method: 'POST',
    body: JSON.stringify({ code, state })
  });
});

Consultez Guide OAuth Intégré pour l'implémentation complète.

API Layers (Résumé)

Construisez des dispositions vidéo immersives et des superpositions de caméra :

// Start immersive mode - replaces gallery view
await zoomSdk.runRenderingContext({ view: 'immersive' });

// Position participant video feeds
await zoomSdk.drawParticipant({
  participantUUID: 'user-uuid',
  x: 0, y: 0, width: 640, height: 480, zIndex: 1
});

// Add overlay images
await zoomSdk.drawImage({
  imageData: canvas.toDataURL(),
  x: 0, y: 0, width: 1280, height: 720, zIndex: 0
});

// Exit immersive mode
await zoomSdk.closeRenderingContext();

Consultez Layers Immersive et Mode Caméra.

Variables d'Environnement

Variable Description Où le Trouver
ZOOM_APP_CLIENT_ID ID client de l'app Marketplace -> App -> App Credentials
ZOOM_APP_CLIENT_SECRET Secret client de l'app Marketplace -> App -> App Credentials
ZOOM_APP_REDIRECT_URI URL de redirection OAuth URL de votre serveur + /auth
SESSION_SECRET Secret de signature des cookies Générez une chaîne aléatoire
ZOOM_HOST URL hôte Zoom https://zoom.us (ou https://zoomgov.com)

APIs Courantes

API Description
config() Initialiser le SDK, demander les capacités
getMeetingContext() Obtenir l'ID de réunion, le sujet, l'état
getUserContext() Obtenir le nom d'utilisateur, le rôle, l'ID de participant
getRunningContext() Obtenir le contexte d'exécution actuel
getMeetingParticipants() Lister les participants
shareApp() Partager l'écran de l'app avec les participants
openUrl({ url }) Ouvrir une URL dans un navigateur externe
sendAppInvitation() Inviter les utilisateurs à ouvrir votre app
authorize() Déclencher OAuth Intégré
connect() Se connecter à d'autres instances d'app
postMessage() Envoyer un message à des instances connectées
runRenderingContext() Démarrer l'API Layers (immersif/caméra)
expandApp({ action }) Développer/réduire le panneau de l'app
showNotification() Afficher une notification dans Zoom

Bibliothèque Complète de Documentation

Concepts Fondamentaux

  • Architecture - Motif frontend/backend, navigateur intégré, deep linking, X-Zoom-App-Context
  • Contextes d'Exécution - Tous les contextes, APIs spécifiques au contexte, communication multi-instance
  • Sécurité - En-têtes OWASP, CSP, sécurité des cookies, PKCE, stockage de tokens

Exemples Complets

Dépannage

Références

Exemples de Dépôts

Officiels (par Zoom)

Dépôt Type Dernière Mise à Jour Statut Version SDK
zoomapps-sample-js Hello World (Vanilla JS) Dec 2025 Actif ^0.16.26
zoomapps-advancedsample-react Avancé (React + Redis) Oct 2025 Actif 0.16.0
zoomapps-customlayout-js API Layers Nov 2023 Obsolète ^0.16.8
zoomapps-texteditor-vuejs Collaborate (Vue + Y.js) Oct 2023 Obsolète ^0.16.7
zoomapps-serverless-vuejs Serverless (Firebase) Aug 2024 Obsolète ^0.16.21
zoomapps-cameramode-vuejs Mode Caméra - - -
zoomapps-workshop-sample Atelier - - -

Recommandé pour les nouveaux projets : Utilisez @zoom/appssdk version ^0.16.26.

Communauté

Type Dépôt Description
Bibliothèque harvard-edtech/zaccl Zoom App Complete Connection Library

Liste complète : Consultez general/references/community-repos.md

Chemin d'Apprentissage

  1. Commencer : zoomapps-sample-js - Plus simple, plus à jour
  2. Avancé : zoomapps-advancedsample-react - Compréhensif (OAuth Intégré, Mode Invité, Collaborate)
  3. Spécialisé : Choisissez en fonction de la fonctionnalité (Layers, Serverless, Mode Caméra)

Pièges Critiques (Tiré du Développement Réel)

1. Conflit de Variable Globale

Le script CDN définit window.zoomSdk. Déclarer let zoomSdk dans votre code cause SyntaxError: redeclaration of non-configurable global property. Utilisez let sdk = window.zoomSdk ou l'importation NPM.

2. Liste de Domaines Autorisés

Votre URL d'app doit être dans la liste de domaines autorisés du Marketplace. Sans cela, Zoom affiche un panneau vide sans erreur. Ajoutez aussi appssdk.zoom.us et tous les domaines CDN que vous utilisez.

3. Les Capacités Doivent Être Listées

Seules les APIs listées dans config({ capabilities: [...] }) sont disponibles. Appeler une API non listée lève une erreur. C'est aussi vrai pour les écouteurs d'événements.

4. Le SDK Fonctionne Uniquement Dans Zoom

zoomSdk.config() lève une erreur en dehors du client Zoom. Enveloppez toujours dans try/catch avec fallback navigateur :

try { await zoomSdk.config({...}); } catch { showBrowserPreview(); }

5. Les URLs ngrok Changent

Les URLs ngrok gratuites changent au redémarrage. Vous devez mettre à jour 4 endroits sur le Marketplace : Home URL, Redirect URL, OAuth Allow List, Domain Allow List. Envisagez un plan payant ngrok pour un sous-domaine stable.

6. OAuth Intégré vs Web OAuth

Utilisez zoomSdk.authorize() (Intégré) pour la meilleure UX - pas de redirection de navigateur. Ne retombez sur la redirection web que pour l'installation initiale depuis le Marketplace.

7. Course CEF en Mode Caméra

Le mode caméra utilise CEF qui prend du temps pour s'initialiser. drawImage/drawWebView peuvent échouer s'il est appelé trop tôt. Implémentez une réessai avec backoff exponentiel.

8. Configuration des Cookies

Le navigateur intégré de Zoom nécessite des cookies avec SameSite=None et Secure=true. Sans cela, les sessions échouent silencieusement.

9. Validation d'État

Validez toujours le paramètre OAuth state pour prévenir les attaques CSRF. Générez un état aléatoire cryptographiquement, stockez-le et vérifiez le callback.

Ressources


Besoin d'aide ? Commencez par la section Index Intégré ci-dessous pour la navigation complète.


Index Intégré

Cette section a été migrée depuis SKILL.md.

Chemin de Démarrage Rapide

Si vous êtes nouveau pour les Zoom Apps, suivez cet ordre :

  1. Exécutez d'abord les vérifications préalables -> RUNBOOK.md

  2. Lisez l'architecture -> concepts/architecture.md

    • Motif frontend/backend, navigateur intégré, deep linking
    • Comprendre comment Zoom charge et communique avec votre app
  3. Construisez votre première app -> examples/quick-start.md

    • Express + SDK Hello World complet
    • Configuration ngrok pour le développement local
  4. Comprenez les contextes d'exécution -> concepts/running-contexts.md

    • Où votre app s'exécute (inMeeting, inMainClient, inWebinar, etc.)
    • APIs et limitations spécifiques au contexte
  5. Implémentez OAuth -> examples/in-client-oauth.md

    • OAuth Intégré avec PKCE (meilleure UX)
    • Échange et stockage de tokens
  6. Ajoutez des fonctionnalités -> references/apis.md

    • 100+ méthodes SDK organisées par catégorie
    • Exemples de code pour chacune
  7. Dépannage -> troubleshooting/common-issues.md

    • Diagnostics rapides pour les problèmes courants

Structure de Documentation

zoom-apps-sdk/
├── SKILL.md                           # Aperçu de la compétence principale
├── SKILL.md                           # Ce fichier - guide de navigation
│
├── concepts/                          # Motifs architecturaux fondamentaux
│   ├── architecture.md               # Frontend/backend, navigateur intégré, flux OAuth
│   ├── running-contexts.md           # Où votre app s'exécute + APIs spécifiques au contexte
│   └── security.md                   # En-têtes OWASP, CSP, couches d'accès aux données
│
├── examples/                          # Code de travail complet
│   ├── quick-start.md                # Hello World - app Express + SDK minimale
│   ├── in-client-oauth.md            # OAuth Intégré avec PKCE
│   ├── layers-immersive.md           # API Layers - mode immersif (dispositions personnalisées)
│   ├── layers-camera.md              # API Layers - mode caméra (caméra virtuelle)
│   ├── collaborate-mode.md           # Mode Collaborate (état partagé)
│   ├── guest-mode.md                 # Mode Invité (non authentifié -> autorisé)
│   ├── breakout-rooms.md             # Intégration de salle de sous-groupe
│   └── app-communication.md          # connect + postMessage entre instances
│
├── troubleshooting/                   # Guides de dépannage
│   ├── common-issues.md              # Diagnostics rapides, codes d'erreur
│   ├── debugging.md                  # Configuration dev local, ngrok, aperçu navigateur
│   └── migration.md                  # Notes de migration de version SDK
│
└── references/                        # Documentation de référence
    ├── apis.md                        # Référence API complète (100+ méthodes)
    ├── events.md                      # Tous les événements SDK
    ├── layers-api.md                  # Référence détaillée de l'API Layers
    ├── oauth.md                       # Flux OAuth pour les Zoom Apps
    └── zmail-sdk.md                   # Intégration Zoom Mail

Par Cas d'Usage

Je veux construire une Zoom App de base

  1. Architecture - Comprendre le motif
  2. Démarrage Rapide - Construire Hello World
  3. OAuth Intégré - Ajouter l'autorisation
  4. Sécurité - En-têtes requis

Je veux des dispositions vidéo immersives (API Layers)

  1. Layers Immersive - Positions de vidéo personnalisées
  2. Référence API Layers - Toutes les méthodes de dessin
  3. Communication d'App - Synchroniser la disposition entre participants

Je veux une superposition de caméra virtuelle

  1. Mode Caméra - Rendu du mode caméra
  2. Référence API Layers - Méthodes de dessin

Je veux une collaboration en temps réel

  1. Mode Collaborate - APIs d'état partagé
  2. Communication d'App - Messagerie entre instances

Je veux un accès invité/anonyme

  1. Mode Invité - Trois états d'autorisation
  2. OAuth Intégré - Flux promptAuthorize

Je veux le support des salles de sous-groupe

  1. Salles de Sous-Groupe - Détection de salle et synchronisation d'état

Je veux synchroniser le client principal et la réunion

  1. Communication d'App - connect + postMessage
  2. Contextes d'Exécution - Comportement multi-instance

Je veux un déploiement serverless

  1. Démarrage Rapide - Comprendre d'abord le motif de base
  2. Exemple : zoomapps-serverless-vuejs - Motif Firebase

Je veux ajouter l'intégration Zoom Mail

  1. Référence Zoom Mail - API REST + plugins mail

J'obtiens des erreurs

  1. Problèmes Courants - Tableau de diagnostic rapide
  2. Débogage - Configuration dev local, DevTools
  3. Migration - Compatibilité de version

Documents les Plus Critiques

1. Architecture (FONDATION)

concepts/architecture.md

Comprenez comment fonctionnent les Zoom Apps : Frontend dans le navigateur intégré, backend pour OAuth/API, SDK comme le pont. Sans cela, rien d'autre n'a de sens.

2. Démarrage Rapide (PREMIÈRE APP)

examples/quick-start.md

Code de travail complet. Obtenez quelque chose de fonctionnant avant de plonger dans les fonctionnalités avancées.

3. Problèmes Courants (PROBLÈMES LES PLUS COURANTS)

troubleshooting/common-issues.md

90% des problèmes de Zoom Apps sont : liste de domaines autorisés, conflit de variable globale, ou capacités manquantes.


Apprentissages Clés

Découvertes Critiques :

  1. Le Conflit de Variable Globale est le #1 Piège

    • Le script CDN définit window.zoomSdk globalement
    • let zoomSdk = ... cause SyntaxError dans le navigateur de Zoom
    • Utilisez let sdk = window.zoomSdk ou l'importation NPM
  2. La Liste de Domaines Autorisés est Non-Négociable

    • L'app affiche un panneau vide sans erreur si le domaine n'est pas sur la liste blanche
    • Doit inclure votre domaine ET appssdk.zoom.us ET tous les domaines CDN
    • Les URLs ngrok changent au redémarrage - doivent être mises à jour sur le Marketplace chaque fois
  3. config() Contrôle Tout

    • Doit être appelée en premier, doit lister toutes les capacités
    • Les capacités non listées lèvent des erreurs
    • Vérifiez unsupportedApis pour la compatibilité de version client
  4. OAuth Intégré > OAuth Web pour l'UX

    • authorize() garde l'utilisateur dans Zoom (pas de redirection de navigateur)
    • La redirection web est seulement nécessaire pour l'installation initiale depuis le Marketplace
    • Implémentez toujours PKCE (code_verifier + code_challenge)
  5. Deux Instances d'App Peuvent S'Exécuter Simultanément

    • Instance client principal + instance de réunion
    • Utilisez connect() + postMessage() pour synchroniser entre elles
    • Configuration pré-réunion dans le client principal, utilisation en réunion
  6. Le Mode Caméra a des Quirks CEF

    • L'initialisation CEF prend du temps
    • Les appels de dessin peuvent échouer s'ils sont trop tôt
    • Utilisez une réessai avec backoff exponentiel
  7. Les Paramètres de Cookie Sont Importants

    • SameSite=None + Secure=true requis
    • Sans cela, les sessions échouent silencieusement dans le navigateur intégré

Référence Rapide

« L'app affiche un panneau vide »

-> Liste de Domaines Autorisés - ajouter le domaine au Marketplace

« SyntaxError: redeclaration »

-> Variable Globale - utilisez let sdk = window.zoomSdk

« config() lève une erreur »

-> Aperçu Navigateur - le SDK fonctionne uniquement dans Zoom

« L'appel API échoue silencieusement »

-> Portées OAuth - ajouter les portées requises au Marketplace

« Comment implémenter [fonctionnalité] ? »

-> Référence API - trouvez la méthode, vérifiez les capacités requises

« Comment tester localement ? »

-> Guide de Débogage - ngrok + configuration Marketplace


Version du Document

Basé sur @zoom/appssdk v0.16.x (dernière : 0.16.26+)


Bon codage !

Commencez par Architecture pour comprendre le motif, puis Démarrage Rapide pour construire votre première app.

Skills similaires