Pular para o conteúdo

Do webhook de erro à exportação da execução

Este guia mostra como receber uma notificação de falha por webhook e consultar os dados da execução pela API do TunnelHub.

Use esse fluxo quando seu sistema precisa abrir um incidente, armazenar evidências ou encaminhar logs e traces para outra ferramenta de observabilidade.

Você precisa de:

  • uma notificação do tipo Webhook configurada na automação;
  • acesso de usuário ao tenant e ao ambiente da execução;
  • usuário e senha do TunnelHub;
  • o UUID do ambiente, enviado no header EnvironmentId.

O contrato atual usa ID token de usuário. Credenciais técnicas de CI/CD não autorizam os endpoints deste guia. A seção Autentique as chamadas mostra como obter e renovar esse token.

Todos os exemplos usam HTTPS. A base da API é https://api.tunnelhub.io/.

O TunnelHub envia notificações por webhook somente quando a execução termina com falha. O endpoint receptor deve aceitar POST com Content-Type: application/json e responder rapidamente com um status 2xx.

Exemplo de payload:

{
"account": {
"name": "Conta exemplo",
"id": "<tenant-id>"
},
"environment": {
"name": "Produção",
"id": "<environment-id>"
},
"package": {
"name": "Integrações",
"id": "<package-id>"
},
"automation": {
"name": "Pedidos",
"id": "<automation-id>"
},
"execution": {
"startedAt": "2026-08-21T10:00:00.000Z",
"finishedAt": "2026-08-21T10:05:00.000Z",
"totalSuccess": 95,
"totalErrors": 5,
"message": "Falha ao enviar pedidos"
},
"url": "https://portal.cliente.example/#/automations/<automation-id>/execution/2026-08/<execution-id>?env=<environment-id>"
}

O request também contém o header TunnelHub-Tenant-Id com o UUID do tenant.

O header identifica o tenant, mas não é uma assinatura criptográfica. Não o use sozinho para autenticar a origem do evento. Trate a URL de destino do webhook como segredo e processe o evento em uma fila antes de executar chamadas demoradas.

Use os campos abaixo para montar as chamadas à API:

DadoOrigem no webhook
automationIdautomation.id
environmentIdenvironment.id
periodtrecho da URL entre /execution/ e o próximo /
executionIdtrecho da URL após period e antes de ?env=

No exemplo acima, o period é 2026-08 e o executionId é <execution-id>.

No contrato atual, period e executionId não são campos próprios do JSON. Eles precisam ser obtidos da URL. Trate essa extração como dependência do formato atual do link e valide os valores antes de chamar a API.

Envie o ID token do usuário no header Authorization e o ambiente da execução no header EnvironmentId. Use USER_PASSWORD_AUTH para obter o token diretamente do Amazon Cognito.

Use environment.id do webhook para TUNNELHUB_ENVIRONMENT_ID. No portal, abra Conta > Informações da conta e copie:

  • Grupo de usuários para TUNNELHUB_USER_POOL_ID.
  • App Client ID para TUNNELHUB_CLIENT_ID.

O Grupo de usuários tem o formato <região>_<pool>. Por exemplo, us-east-1_AbCdEf usa a região us-east-1.

Janela do terminal
export TUNNELHUB_API_URL='https://api.tunnelhub.io'
export TUNNELHUB_ENVIRONMENT_ID='<environment-id-do-webhook>'
export TUNNELHUB_USER_POOL_ID='<grupo-de-usuarios>'
export TUNNELHUB_CLIENT_ID='<app-client-id>'
export TUNNELHUB_REGION="${TUNNELHUB_USER_POOL_ID%%_*}"

O Grupo de usuários e o App Client ID precisam pertencer ao mesmo pool.

Leia a senha sem exibi-la e exporte-a somente para a chamada de autenticação atual:

Janela do terminal
read -r -s -p 'Senha do TunnelHub: ' TUNNELHUB_PASSWORD
printf '\n'
export TUNNELHUB_PASSWORD
read -r -p 'Usuário ou e-mail do TunnelHub: ' TUNNELHUB_USERNAME
export TUNNELHUB_USERNAME

Faça a chamada HTTPS ao endpoint do Cognito. jq monta o JSON a partir das variáveis de ambiente para que a senha não apareça nos argumentos do comando ou no histórico do shell.

Janela do terminal
AUTH_RESPONSE="$(
jq -n \
'{
AuthFlow: "USER_PASSWORD_AUTH",
ClientId: env.TUNNELHUB_CLIENT_ID,
AuthParameters: {
USERNAME: env.TUNNELHUB_USERNAME,
PASSWORD: env.TUNNELHUB_PASSWORD
}
}' |
curl --fail-with-body \
-H 'Content-Type: application/x-amz-json-1.1' \
-H 'X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth' \
--data @- \
"https://cognito-idp.${TUNNELHUB_REGION}.amazonaws.com/"
)"
export TUNNELHUB_ID_TOKEN="$(jq -er '.AuthenticationResult.IdToken' <<< "${AUTH_RESPONSE}")"
export TUNNELHUB_REFRESH_TOKEN="$(jq -er '.AuthenticationResult.RefreshToken' <<< "${AUTH_RESPONSE}")"
export TUNNELHUB_TOKEN_EXPIRES_IN="$(jq -er '.AuthenticationResult.ExpiresIn' <<< "${AUTH_RESPONSE}")"
unset AUTH_RESPONSE TUNNELHUB_PASSWORD

Se a resposta contiver ChallengeName em vez de AuthenticationResult, ela não contém tokens. Resolva o desafio manualmente no Cognito antes de tentar a autenticação novamente. Não use USER_PASSWORD_AUTH para usuários autenticados por SAML.

Antes de o token expirar, use o refresh token para obter novos tokens. O refresh token permanece o mesmo no fluxo atual.

Janela do terminal
REFRESH_RESPONSE="$(
jq -n \
'{
AuthFlow: "REFRESH_TOKEN_AUTH",
ClientId: env.TUNNELHUB_CLIENT_ID,
AuthParameters: {
REFRESH_TOKEN: env.TUNNELHUB_REFRESH_TOKEN
}
}' |
curl --fail-with-body \
-H 'Content-Type: application/x-amz-json-1.1' \
-H 'X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth' \
--data @- \
"https://cognito-idp.${TUNNELHUB_REGION}.amazonaws.com/"
)"
export TUNNELHUB_ID_TOKEN="$(jq -er '.AuthenticationResult.IdToken' <<< "${REFRESH_RESPONSE}")"
export TUNNELHUB_TOKEN_EXPIRES_IN="$(jq -er '.AuthenticationResult.ExpiresIn' <<< "${REFRESH_RESPONSE}")"
unset REFRESH_RESPONSE

Proteja TUNNELHUB_REFRESH_TOKEN como uma credencial de longa duração. Não o registre, não o exponha em variáveis de CI abertas e não o inclua em tickets.

Janela do terminal
export AUTOMATION_ID='<automation-id>'
export EXECUTION_ID='<execution-id>'
export PERIOD='2026-08'

Não registre o ID token, URLs pré-assinadas de download ou o corpo completo de logs e traces em sistemas que não precisam desses dados.

Comece pelo detalhe para confirmar automação, ambiente, período, status e totais antes de aprofundar a investigação.

Janela do terminal
curl --fail-with-body \
-H "Authorization: Bearer ${TUNNELHUB_ID_TOKEN}" \
-H "EnvironmentId: ${TUNNELHUB_ENVIRONMENT_ID}" \
"${TUNNELHUB_API_URL}/integrations-service/automations/monitoring/${EXECUTION_ID}?automationId=${AUTOMATION_ID}&period=${PERIOD}"

Use logs de processamento para investigar registros de negócio e traces para investigar o comportamento técnico da execução.

Para obter todos os logs, solicite a exportação em vez de paginar a consulta de logs.

Janela do terminal
curl --fail-with-body \
-H "Authorization: Bearer ${TUNNELHUB_ID_TOKEN}" \
-H "EnvironmentId: ${TUNNELHUB_ENVIRONMENT_ID}" \
"${TUNNELHUB_API_URL}/integrations-service/automations/monitoring/${EXECUTION_ID}/executionLogs/download?automationId=${AUTOMATION_ID}&period=${PERIOD}"

Para execuções com menos de 5.000 logs, a resposta contém uma URL imediata:

{
"status": "ok",
"url": "<url-pre-assinada-do-arquivo-xlsx>"
}

Para volumes maiores, a resposta cria um job assíncrono:

{
"status": "pending",
"processingId": "<processing-id>"
}

Consulte o job conforme descrito em Acompanhe uma exportação assíncrona.

O endpoint de leitura de traces é paginado e serve para investigação interativa. Não o use para tentar recuperar a execução completa quando houver muitas páginas.

Para exportar todos os traces, inicie a exportação assíncrona sem filtros:

Janela do terminal
curl --fail-with-body \
-X POST \
-H "Authorization: Bearer ${TUNNELHUB_ID_TOKEN}" \
-H "Content-Type: application/json" \
-H "EnvironmentId: ${TUNNELHUB_ENVIRONMENT_ID}" \
-d "{\"automationId\":\"${AUTOMATION_ID}\",\"executionId\":\"${EXECUTION_ID}\",\"period\":\"${PERIOD}\",\"format\":\"ndjson\"}" \
"${TUNNELHUB_API_URL}/integrations-service/automations/monitoring/${EXECUTION_ID}/traces/export"

Uma solicitação aceita retorna 202:

{
"exportId": "<export-id>",
"status": "accepted",
"message": "Exportação iniciada"
}

Guarde exportId e use-o como o ID do job na próxima etapa. Se já existir uma exportação de traces em andamento para a execução, a API retorna 409 com EXPORT_ALREADY_IN_PROGRESS.

Embora a requisição exija format com csv ou ndjson, o artefato atual é entregue como traces-<execution-id>.gz, com o export textual do CloudWatch Logs. Não presuma um CSV ou NDJSON convertido pelo worker atual.

Use processingId para logs ou exportId para traces no endpoint de background processing:

Janela do terminal
curl --fail-with-body \
-H "Authorization: Bearer ${TUNNELHUB_ID_TOKEN}" \
-H "EnvironmentId: ${TUNNELHUB_ENVIRONMENT_ID}" \
"${TUNNELHUB_API_URL}/platform-service/backgroundProcessings/<processing-id-ou-export-id>"

Repita a consulta com intervalo progressivo enquanto o status for PENDING ou PROCESSING.

StatusAção
PENDINGAguarde o processamento iniciar.
PROCESSINGContinue aguardando.
FINISHEDBaixe a URL pré-assinada presente em message.
FAILRegistre a mensagem de erro e investigue a execução.

As URLs de download expiram em 24 horas. Baixe e armazene o arquivo em um repositório seguro antes da expiração, quando a política de retenção do cliente permitir.

  • 401: o ID token expirou ou não foi enviado.
  • 403: o usuário não tem acesso ao recurso ou ambiente informado.
  • 404: confirme automationId, executionId, period e EnvironmentId.
  • 409 EXPORT_ALREADY_IN_PROGRESS: reutilize o job de exportação em andamento em vez de iniciar outro.
  • FAIL no background processing: a exportação não foi concluída; use o resumo, logs e traces disponíveis para investigar.
  • URL de download expirada: solicite uma nova exportação.
  • responda ao webhook antes de iniciar consultas ou exports;
  • deduplique eventos pelo conjunto de automação, ambiente, período e execução;
  • valide que os IDs extraídos da URL correspondem aos campos automation.id e environment.id do payload;
  • use o endpoint assíncrono para traces completos, principalmente em execuções com milhares de páginas;
  • sanitize logs e traces antes de enviá-los para tickets, chats ou sistemas externos.

Veja também Notificações e Monitoramento.