
Compartilhar:
Lorna é engenheira de software e tem um vício incurável por escrever em blogs. Ela tenta domar as palavras e o código na mesma medida.
Baixar gravações da Voice API da Vonage com Golang
Tempo de leitura: 2 minutos
Nós adoramos a Voice API e todas as coisas legais que você pode fazer com ela. Hoje vou mostrar a vocês um aplicativo em Golang que estou usando para baixar as gravações das chamadas.
Quando faço uma ligação e a gravo, a API envia um webhook ao final da ligação com todas as informações sobre a gravação. Meu aplicativo recebe esse webhook e baixa o arquivo da gravação por conta própria.
Configurar a URL de gravação
Quando eu adiciono um ação de registro a um NCCO da Voice API, posso definir o eventUrl para receber a notificação da gravação. Esse webhook de entrada chega quando a chamada é encerrada e inclui informações sobre a gravação e um link para baixá-la.
Minha ação de registro fica assim:
{
"action": "record",
"eventUrl": ["https://76b239af.ngrok.io/recording"]
}Há duas coisas a serem observadas aqui:
Isso
eventUrlna verdade é um array (isso me confunde mais ou menos uma vez a cada três!)Estou usando o Ngrok para disponibilizar uma URL pública para minha plataforma de desenvolvimento local. Você pode ler sobre o Ngrok no Portal do Desenvolvedor , caso queira saber mais sobre como usar essa abordagem.
Receber o Webhook
O webhook recebido está no formato JSON e tem uma aparência mais ou menos assim:
{
"start_time": "2020-05-06T13:34:21Z",
"recording_url": "https://api.nexmo.com/v1/files/6d29bd8d-e6ff-45b9-9379-2843fe7b37fe",
"size": 15822,
"recording_uuid": "692100cb-e4ef-4f18-ab90-2a09573aecb5",
"end_time": "2020-05-06T13:34:25Z",
"conversation_uuid": "CON-55970ffd-a6b7-4d18-b3b6-088c03ea49f1",
"timestamp": "2020-05-06T13:34:25.771Z"
}No meu código em Golang, vou processar uma solicitação recebida para /recording e baixar o arquivo, salvando-o no disco.
Para se autenticar, você precisará de um (JWT)[/Concepts/Guides/Authentication#json-web-tokens-jwt), que pode ser gerado programaticamente ou pela linha de comando. Este exemplo espera que ele esteja em uma variável de ambiente
JWT.
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
type RecordingWebhook struct {
StartTime string `json:"start_time"`
RecordingURL string `json:"recording_url"`
Size float64 `json:"size"`
RecordingUUID string `json:"recording_uuid"`
EndTime string `json:"end_time"`
ConversationUUID string `json:"conversation_uuid"`
Timestamp string `json:"timestamp"`
}
func downloadRecording(w http.ResponseWriter, r *http.Request) {
jwt := os.Getenv("JWT")
// Get data from incoming webhook
data := RecordingWebhook{}
err := json.NewDecoder(r.Body).Decode(&data)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
fmt.Println("Recording URL: " + data.RecordingURL)
}
func main() {
http.HandleFunc("/recording", downloadRecording)
if err := http.ListenAndServe(":8080", nil); err != nil {
panic(err)
}
}
O ponto de entrada aqui é a main() função no final do exemplo de código. Ela registra uma /recording rota e, em seguida, inicia um servidor web rodando na porta 8080.
Quando executo o código pela primeira vez com go run main.go, não acontece quase nada! Isso porque o servidor web está em execução e aguardando a chegada de uma solicitação. Quando ela chega, se a rota corresponder, ele chama a downloadRecording() função e a ação começa!
Este código primeiro analisa os dados recebidos; trata-se de uma POST solicitação com um corpo em JSON, então defini uma estrutura na qual pudesse decodificar os dados. Assim que obtivermos a URL, o programa a exibe.
Baixe e salve a gravação
Se tudo correu bem até aqui, podemos prosseguir e adicionar as etapas para baixar a gravação e salvar o arquivo. Quando estiver concluída, a função completa downloadRecording() função fica assim:
func downloadRecording(w http.ResponseWriter, r *http.Request) {
jwt := os.Getenv("JWT")
// Get data from incoming webhook
data := RecordingWebhook{}
err := json.NewDecoder(r.Body).Decode(&data)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
fmt.Println("Recording URL: " + data.RecordingURL)
// prepare and download the recording, with auth
req, err := http.NewRequest("GET", data.RecordingURL, nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+jwt)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
// now write to a local file
filename := data.RecordingUUID + ".mp3"
out, err := os.Create(filename)
if err != nil {
panic(err)
}
defer out.Close()
_, fileErr := io.Copy(out, resp.Body)
if fileErr != nil {
panic(fileErr)
}
// Good! acknowledge it
w.Write([]byte("OK"))
}
O download de gravações exige credenciais; portanto, este código mostra como adicionar um JWT à solicitação antes de enviá-la.
Por fim, a resposta à solicitação de download é gravada em um arquivo local. Usei o ID da gravação como nome do arquivo, pois sei que ele será único; se fizer mais sentido nomear os arquivos com carimbos de data e hora ou algo semelhante, você certamente poderá fazer isso em seu próprio aplicativo.
Como lidar com gravações em suas próprias Applications
O exemplo de hoje é básico, mas mostra alguns elementos-chave do trabalho com a Voice API: receber webhooks em resposta a eventos e enviar credenciais para baixar as gravações. Se você estiver usando algo semelhante em seus próprios aplicativos ou se estiver desenvolvendo algo com base neste exemplo, conte para a gente! Sempre gostamos de saber no que vocês estão trabalhando.