Provedores suportados
| Provider | Auth | Join | Recordings | Transcript |
|---|---|---|---|---|
| BBB | sharedSecret | iframe | Sim, API nativa | Texto fornecido |
| Zoom | Server-to-Server OAuth | nova aba | Webhook + cron | VTT auto |
| Teams | Client Credentials | nova aba | Graph API + cron | VTT auto |
| Google Meet | OAuth + Calendar API | nova aba | Calendar API + cron | Manual no Meet |
Adapter pattern
packages/core/src/live-class/types.ts:
interface VideoProviderAdapter {
createMeeting(params): Promise<VideoMeetingResult>;
getJoinUrl(params): Promise<VideoJoinResult>;
endMeeting(meetingId, providerData?): Promise<void>;
getMeetingStatus(meetingId): Promise<VideoMeetingStatus | null>;
getRecordings(meetingId): Promise<VideoRecording[]>;
getTranscript?(meetingId): Promise<VideoTranscript | null>;
}
resolveVideoProvider(tenantId, liveClass?) cascateia:
liveClass.videoProvider(se especificado na aula)VideoProviderConfig.isDefault(provider padrao do tenant)Tenant.config.bbb(legacy backward compat)- Env vars BBB (fallback global)
Setup por provider
BBB (padrao)
Pre-requisito: instancia BBB rodando. Settings > Video Provider > BBB > URL + Shared Secret.
Zoom
- Crie Server-to-Server OAuth app no Zoom Marketplace
- Scopes:
meeting:read,meeting:write,recording:read,user:read - Settings > Video Provider > Zoom > Account ID + Client ID + Client Secret
- Webhook:
/api/webhooks/video/zoomcom HMAC SHA-256 viax-zm-signature
Teams
- Azure AD App Registration
- Permissions: Microsoft Graph
OnlineMeetings.ReadWrite.All,OnlineMeetingRecording.Read.All - Settings > Video Provider > Teams > Tenant ID + Client ID + Client Secret + Organizer email
- Webhook: Graph Change Notifications (subscription validation via
validationToken)
Google Meet
- Google Cloud Console > APIs > Calendar API + Meet REST API v2
- OAuth 2.0 Client (Web application)
- Settings > Video Provider > Google Meet > Client ID + Client Secret
- Admin consent flow via OAuth (redirect para Google)
- Limitacao: endMeeting nao suportado via API — adapter marca como completed localmente
Credenciais
Armazenadas em VideoProviderConfig com AES-256-GCM:
encryptedCredentials— JSON blob criptografadoencryptionIv+encryptionAuthTag- OAuth tokens (Teams/Meet):
accessToken,refreshToken,tokenExpiresAt
Unique: [tenantId, provider] — um config por provider por tenant.
Webhooks e recording sync
Cada provider tem padrao proprio. Studeia normaliza via webhook handlers + cron fallback:
POST /api/webhooks/video/zoom— meeting events + recording.completedPOST /api/webhooks/video/teams— Graph notificationsGET /api/cron/recording-sync— polling a cada 15min para meetings completed sem recordingUrl
Webhooks sao unreliable (delays, subscription expiry). Cron sempre como fallback.
Transcricao
Zoom e Teams fornecem VTT nativamente apos recording. Studeia cria LiveClassTranscription com:
transcriptionText(parsed do VTT)transcriptionLanguage- status: pending → transcribing → review → approved → ingested
Apos approved, admin pode disparar ingestao no RAG do curso. Detalhes em Media Transcription.
Escopo por turma
LiveClass.classGroupId opcional. Quando setado:
- Apenas alunos daquela turma veem em /live-classes/
- Apenas alunos da turma podem entrar (validado no join)
- Notificacoes apenas para turma
Sem classGroupId: course-wide (todos matriculados).
Limitacoes
- BBB: precisa de instancia auto-hospedada (ou managed BBB provider). Custos: $20-200/mes dependendo do tamanho.
- Zoom: limite de duracao por tier (free=40min, paid=ilimitado).
- Teams: endMeeting nao suportado via API.
- Google Meet: gravacao/transcricao iniciada manualmente pelo host.
- Streaming para YouTube/Twitch: nao suportado nativamente.