Tipos de Webhook
O Kinescope suporta webhooks de saída — notificações sobre eventos que ocorrem com seus vídeos, streams ou reuniões do Speak. Quando ocorre um evento (por exemplo, um vídeo é processado ou um stream termina), o Kinescope envia uma solicitação HTTP para a URL que você especificou.
Para quem é este artigo
- Desenvolvedores — precisam automatizar processos em seu sistema quando ocorrem eventos do Kinescope
- Administradores de plataforma — precisam receber notificações sobre o status de processamento de vídeos
- Engenheiros DevOps — precisam integrar o Kinescope com sistemas de monitoramento
Quais problemas os webhooks resolvem
Os webhooks permitem automatizar processos em seu sistema:
- Rastreamento do processamento de vídeos — saiba quando um vídeo está pronto para assistir ou ocorreu um erro
- Monitoramento de streams — receba notificações sobre conexões de streamers, fins de streams e outros eventos
- Acompanhamento de reuniões no Speak — saiba quando as chamadas começam e terminam, quando os participantes entram e saem e quando a reunião é gravada
- Integração com seu sistema — atualize automaticamente os status em seu banco de dados ou envie notificações para os usuários
Como funciona
- Você configura uma URL para receber webhooks (via API ou interface do Kinescope)
- Quando ocorre um evento, o Kinescope envia uma solicitação HTTP POST para sua URL com dados JSON
- Seu servidor manipula a solicitação e executa as ações necessárias (atualizações de status, envio de notificações, etc.)
Webhooks de vídeo
media.update.status
Enviado quando o status do vídeo é atualizado. Usado para rastrear processamento de vídeo, erros ou conclusão de publicação.
Exemplo 1: Atualização de status bem-sucedida
{
"event": "media.update.status",
"data": {
"id": "7127f2d7-0e96-40d0-9a03-2e987c096466",
"status": "done"
}
}
Exemplo 2: Erro de processamento
{
"event": "media.update.status",
"data": {
"id": "12706830-0e96-40d0-9a03-2e987c096466",
"status": "error",
"message": "import error: code=610100, message=cannot download link: https://example.ru/test.mp4, http_code=404"
}
}
Status possíveis:
pending— vídeo aguardando processamentouploading— vídeo sendo enviadopre-processing— pré-processamento do vídeoprocessing— vídeo sendo processadoaborted— processamento foi interrompidodone— vídeo pronto para assistirerror— ocorreu um erro durante o processamentosuspended— processamento/upload pausado
Webhooks de stream
live.created
Notificação sobre a criação de um novo evento de stream (via API ou interface).
{
"event": "live.created",
"data": {
"event_id": "abc123-def456-ghi789"
}
}
live.connected
Streamer conectado — stream RTMP começou a chegar ao servidor.
{
"event": "live.connected",
"data": {
"event_id": "abc123-def456-ghi789"
}
}
live.disconnected
Streamer desconectado — stream RTMP parou.
{
"event": "live.disconnected",
"data": {
"event_id": "abc123-def456-ghi789"
}
}
live.finished
Stream encerrado. O corpo do webhook também inclui video_id — o ID do vídeo de gravação do stream. Se o stream não foi gravado, é um UUID nulo 00000000-0000-0000-0000-000000000000.
{
"event": "live.finished",
"data": {
"event_id": "abc123-def456-ghi789",
"video_id": "7127f2d7-0e96-40d0-9a03-2e987c096466"
}
}
live.cancelled
Stream foi cancelado.
{
"event": "live.cancelled",
"data": {
"event_id": "abc123-def456-ghi789"
}
}
live.enabled
Stream está disponível para visualização pelos clientes.
{
"event": "live.enabled",
"data": {
"event_id": "abc123-def456-ghi789"
}
}
Webhooks do Speak
Eventos sobre chamadas nas salas do Speak: início e fim da reunião, entrada e saída de participantes e gravação. Para recebê-los, liste os eventos desejados no campo events ao criar ou atualizar o webhook.
Todos os eventos do Speak trazem dois identificadores:
room_id— ID da sala. A sala é permanente e pode receber muitas reuniõescall_id— ID da chamada, ou seja, de uma reunião nesta sala
São os mesmos IDs da referência da API do Speak: com eles você pode consultar os dados da sala e da chamada.
speak.call.started
Uma chamada começou na sala.
{
"event": "speak.call.started",
"data": {
"room_id": "0f8c3a52-6b1e-4c2d-9a47-3e5b8d1f2c60",
"call_id": "5d2e9b14-7a3c-4f8e-b061-92c4a7e3d815"
}
}
speak.call.finished
A chamada na sala terminou.
{
"event": "speak.call.finished",
"data": {
"room_id": "0f8c3a52-6b1e-4c2d-9a47-3e5b8d1f2c60",
"call_id": "5d2e9b14-7a3c-4f8e-b061-92c4a7e3d815"
}
}
speak.participant.joined
Um participante entrou na chamada. O objeto participant traz:
id— ID do participante da salaidentity— identificador da conexão à chamada; use-o para relacionar a entrada e a saída de um mesmo participantename— nome com que o participante entrourole— função do participante na sala
id e role podem vir vazios — por exemplo, se a sessão do participante já tiver sido encerrada no momento do envio. Participantes de serviço, como o bot de gravação, não geram eventos speak.participant.*.
{
"event": "speak.participant.joined",
"data": {
"room_id": "0f8c3a52-6b1e-4c2d-9a47-3e5b8d1f2c60",
"call_id": "5d2e9b14-7a3c-4f8e-b061-92c4a7e3d815",
"participant": {
"id": "c41f7e28-3b9d-4a65-8e12-6f0d5b9a7c33",
"identity": "8e3b5a17-2c4d-4f90-a6e1-7d9c0b3f5a24",
"name": "Ana Souza",
"role": "admin"
}
}
}
speak.participant.left
Um participante saiu da chamada. O objeto participant é o mesmo de speak.participant.joined.
{
"event": "speak.participant.left",
"data": {
"room_id": "0f8c3a52-6b1e-4c2d-9a47-3e5b8d1f2c60",
"call_id": "5d2e9b14-7a3c-4f8e-b061-92c4a7e3d815",
"participant": {
"id": "c41f7e28-3b9d-4a65-8e12-6f0d5b9a7c33",
"identity": "8e3b5a17-2c4d-4f90-a6e1-7d9c0b3f5a24",
"name": "Ana Souza",
"role": "admin"
}
}
}
speak.record.started
A gravação da reunião começou. O objeto record traz o ID da gravação (id) e o seu status (status).
{
"event": "speak.record.started",
"data": {
"room_id": "0f8c3a52-6b1e-4c2d-9a47-3e5b8d1f2c60",
"call_id": "5d2e9b14-7a3c-4f8e-b061-92c4a7e3d815",
"record": {
"id": "3a9e6c21-5f7b-4d18-9c0e-b2a4d6f8e137",
"status": "starting"
}
}
}
speak.record.finished
A gravação da reunião foi interrompida. O evento não traz o ID do vídeo: a gravação é salva no catálogo e processada como qualquer outro vídeo.
{
"event": "speak.record.finished",
"data": {
"room_id": "0f8c3a52-6b1e-4c2d-9a47-3e5b8d1f2c60",
"call_id": "5d2e9b14-7a3c-4f8e-b061-92c4a7e3d815",
"record": {
"id": "3a9e6c21-5f7b-4d18-9c0e-b2a4d6f8e137",
"status": "complete"
}
}
}
Status possíveis:
complete— gravação concluída com sucessofailed— gravação terminou com erroaborted— gravação abortadalimit_reached— gravação interrompida ao atingir um limite
A retransmissão a partir do Speak sem gravação não gera eventos speak.record.*.
Exemplos de manipulação de webhooks
Exemplo 1: Atualizando o status do vídeo no banco de dados
Aqui está como manipular o webhook media.update.status e atualizar o status em seu banco de dados:
package main
import (
"encoding/json"
"log"
)
type MediaStatusEvent struct {
Event string `json:"event"`
Data struct {
ID string `json:"id"`
Status string `json:"status"`
Message string `json:"message,omitempty"`
} `json:"data"`
}
func handleMediaStatusUpdate(event MediaStatusEvent) error {
videoID := event.Data.ID
status := event.Data.Status
// Atualizar status no banco de dados
// db.Exec("UPDATE videos SET status = ?, error_message = ?, updated_at = ? WHERE kinescope_id = ?",
// status, event.Data.Message, time.Now(), videoID)
if status == "done" {
notifyUser(videoID, "Seu vídeo está pronto para assistir!")
}
if status == "error" {
log.Printf("Erro de processamento do vídeo %s: %s", videoID, event.Data.Message)
}
if status == "aborted" {
notifyUser(videoID, "O processamento do vídeo foi interrompido")
}
return nil
}
Exemplo 2: Manipulando o fim do stream
Quando um stream termina, você pode processar automaticamente a gravação:
package main
type LiveFinishedEvent struct {
Event string `json:"event"`
Data struct {
EventID string `json:"event_id"`
VideoID string `json:"video_id,omitempty"`
} `json:"data"`
}
func handleLiveFinished(event LiveFinishedEvent) error {
eventID := event.Data.EventID
videoID := event.Data.VideoID
// Atualizar status do stream
// db.Exec("UPDATE live_events SET status = ?, recording_video_id = ?, finished_at = ? WHERE kinescope_event_id = ?",
// "finished", videoID, time.Now(), eventID)
// Sem gravação, video_id é um UUID nulo
if videoID != "" && videoID != "00000000-0000-0000-0000-000000000000" {
notifyViewers(eventID, "A gravação do stream está disponível: "+videoID)
}
return nil
}
Exemplo 3: Manipulador universal de webhook
Aqui está um exemplo de um manipulador universal que pode processar diferentes tipos de webhook:
package main
import (
"encoding/json"
"log"
"net/http"
)
type WebhookEvent struct {
Event string `json:"event"`
Data json.RawMessage `json:"data"`
}
func handleWebhook(event WebhookEvent) error {
switch event.Event {
case "media.update.status":
var e MediaStatusEvent
json.Unmarshal(event.Data, &e.Data)
e.Event = event.Event
return handleMediaStatusUpdate(e)
case "live.finished":
var e LiveFinishedEvent
json.Unmarshal(event.Data, &e.Data)
e.Event = event.Event
return handleLiveFinished(e)
default:
log.Printf("Tipo de evento desconhecido: %s", event.Event)
}
return nil
}
func webhookHandler(w http.ResponseWriter, r *http.Request) {
var event WebhookEvent
if err := json.NewDecoder(r.Body).Decode(&event); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if err := handleWebhook(event); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]bool{"success": true})
}
Configurando webhooks
Os webhooks são configurados via API do Kinescope. Especifique a URL do seu endpoint que receberá as notificações.
Importante: Seu endpoint deve retornar HTTP 200 em resposta ao tratamento bem-sucedido do webhook. Se o Kinescope receber um erro (4xx, 5xx), pode tentar novamente a solicitação.
Segurança
É recomendado verificar a autenticidade dos webhooks:
- Verifique a origem da solicitação — certifique-se de que a solicitação vem do Kinescope
- Use HTTPS — os webhooks devem ser enviados para URLs seguras
- Valide os dados — verifique o formato e os campos obrigatórios na solicitação
Pronto! Agora você pode configurar webhooks e automatizar processos em seu sistema.
O que fazer a seguir?
- Regras gerais da API — autorização e formato de solicitação
- Referência da API — documentação completa da API para configuração de webhooks
- Upload de arquivos via API — upload automatizado de vídeos
Ainda tem dúvidas? Escreva para o chat de suporte na interface do Kinescope — nossos especialistas vão ajudar!