Para testar um webhook de bot do Telegram no host local, exponha seu servidor local com um túnel HTTPS público, chame setWebhook com esse URL e valide o cabeçalho do token secreto do Telegram em cada solicitação. Isso fornece mensagens reais, consulta de retorno de chamada e atualizações de associação sem implantação após cada alteração de código. O loop completo é: execute o manipulador de bot, inicie npx portpreview 3000, registre a URL resultante, envie uma mensagem ao seu bot e inspecione a solicitação localmente.
Por que o Telegram não pode enviar atualizações diretamente para localhost
A API Bot do Telegram envia atualizações de webhook da infraestrutura do Telegram para um URL acessível pela Internet. localhost, 127.0.0.1 e endereços de LAN privados não são roteáveis a partir dessa infraestrutura. Um túnel localhost termina HTTPS em um endereço público e encaminha a solicitação HTTP inalterada para sua porta local.
Os bots do Telegram podem receber atualizações de duas maneiras mutuamente exclusivas: pesquisas longas por meio de getUpdates ou webhooks. A referência oficial setWebhook afirma que getUpdates está indisponível enquanto um webhook de saída está configurado. Se um processo de pesquisa ainda estiver em execução, interrompa-o antes de julgar o fluxo do webhook.
Construa um endpoint de webhook local
Este exemplo Express mantém o manipulador intencionalmente pequeno. Ele verifica o segredo compartilhado antes de tocar na atualização, confirma rapidamente e move o trabalho para fora do caminho de resposta.
import express from 'express';
import crypto from 'node:crypto';
const app = express();
app.use(express.json({ limit: '1mb' }));
function sameSecret(received = '', expected = '') {
const a = Buffer.from(received);
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
app.post('/webhooks/telegram', (req, res) => {
const received = req.get('x-telegram-bot-api-secret-token') || '';
if (!sameSecret(received, process.env.TELEGRAM_WEBHOOK_SECRET)) {
return res.sendStatus(401);
}
const update = req.body;
res.sendStatus(200);
queueMicrotask(() => handleUpdate(update));
});
app.listen(3000, () => console.log('Listening on http://localhost:3000'));
Telegram envia um Update serializado em JSON. Ao contrário dos provedores baseados em HMAC, o recurso secret_token do Telegram não assina o corpo. Ele coloca o valor escolhido em X-Telegram-Bot-Api-Secret-Token. O token prova que o remetente conhece o valor usado quando o webhook foi registrado, mas não fornece um resumo da carga útil. TLS protege a solicitação em trânsito.
Exponha o endpoint com HTTPS
- Inicie o aplicativo e confirme que
curl -i http://localhost:3000/webhooks/telegramchega ao servidor, mesmo que GET retorne 404. - Abra um segundo terminal e execute
npx portpreview 3000. - Copie a origem HTTPS pública e anexe
/webhooks/telegram. - Mantenha o processo de túnel em execução enquanto o Telegram entrega atualizações.
A API do Bot aceita URLs de webhook HTTPS. Telegram documenta suporte a webhook nas portas 443, 80, 88 e 8443; o terminal público de um túnel gerenciado normalmente usa 443 mesmo quando o processo local encaminhado escuta em 3000.
Registre o webhook do Telegram com segurança
Crie um segredo aleatório contendo apenas letras, dígitos, sublinhados ou hifens. O telegrama permite de 1 a 256 caracteres. Não reutilize o token do bot com este valor.
export TELEGRAM_WEBHOOK_SECRET="$(openssl rand -hex 32)"
curl -sS -X POST \
"https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/setWebhook" \
-d "url=https://YOUR-TUNNEL.portpreview.dev/webhooks/telegram" \
-d "secret_token=${TELEGRAM_WEBHOOK_SECRET}" \
-d 'allowed_updates=["message","callback_query"]' \
-d "drop_pending_updates=true"
allowed_updates reduz o ruído e deve listar apenas os tipos de atualização que o bot manipula. drop_pending_updates=true é útil ao iniciar uma nova sessão local, mas descarta permanentemente as atualizações na fila, portanto, omita-o quando esses eventos forem importantes. A Documentação de atualização do Telegram descreve campos como message, callback_query e my_chat_member.
Confirme o registro antes de depurar o código
Use getWebhookInfo para separar falhas de configuração de falhas de manipulador:
curl -sS "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getWebhookInfo"
Verifique url, pending_update_count, last_error_message e last_error_date. Um URL vazio significa que o registro não funcionou. Uma contagem pendente crescente geralmente significa que o Telegram não consegue se conectar ou seu endpoint retorna um status diferente de 2xx. Envie uma mensagem direta para o bot após o cadastro; apenas abrir o chat não cria necessariamente uma atualização.
Tratar atualizações sem causar novas tentativas
Reconhecer antes de trabalhar lentamente
Retorne uma resposta 2xx assim que a solicitação for autenticada e aceita de forma duradoura. Exportações de banco de dados, chamadas de IA e APIs de terceiros devem ser executadas de forma assíncrona. O Telegram tenta novamente solicitações malsucedidas após respostas diferentes de 2xx, portanto, o trabalho síncrono lento pode criar duplicatas.
Desduplicar com update_id
Cada atualização possui um update_id. Armazene IDs processados com uma janela de expiração ou aplique uma chave de banco de dados exclusiva. Uma nova tentativa não deve enviar um segundo comprovante de pagamento, criar um ticket duplicado ou executar o mesmo retorno de chamada duas vezes.
Modelar cada tipo de atualização explicitamente
Nem todas as atualizações contêm message.text. Os botões de retorno de chamada chegam em callback_query; postagens de canal e alterações de associação têm outros campos. Ramifique no campo de nível superior atual e trate os tipos desconhecidos como autônomos válidos, em vez de lançados.
Regras de segurança para testes locais de bot do Telegram
- Valide o cabeçalho secreto primeiro. Rejeite valores ausentes ou incorretos antes de registrar ou analisar campos confidenciais.
- Mantenha tokens fora de URLs e logs. O token Bot API no comando de registro é uma credencial. Evite o histórico de shell em sistemas compartilhados e gire um token exposto por meio do BotFather.
- Use uma rota e um segredo indecifráveis. A rota é uma defesa em profundidade; o cabeçalho secreto é a verificação real do aplicativo.
- Limitar dados capturados. As mensagens podem conter nomes, nomes de usuário, números de telefone, arquivos e texto de conversa privada. Edite os logs e exclua as capturas locais quando terminar.
- Nunca desative a autenticação no desenvolvimento. Um túnel público é público. O código local deve exercer as mesmas verificações que a produção.
Consulte o guia de segurança do túnel localhost mais amplo para práticas de controle de acesso e retenção de dados.
Solucionar falhas comuns de webhook do Telegram
Telegram relata um certificado ou erro de conexão
Use a URL HTTPS do túnel, não seu destino HTTP local. Confirme se o túnel está ativo e se o URL não foi alterado. Se você fornecer seu próprio certificado autoassinado, o Telegram exigirá o upload do certificado público como um arquivo; um endpoint TLS gerenciado evita essa configuração.
O terminal retorna 401
Compare o segredo passado para setWebhook com a variável de ambiente usada pelo processo. Os nomes de cabeçalho não diferenciam maiúsculas de minúsculas, mas proxies ou middleware podem remover cabeçalhos personalizados. Inspecione os cabeçalhos recebidos sem imprimir o valor secreto.
Nenhum pedido chega
Execute getWebhookInfo, verifique se o caminho registrado corresponde exatamente à sua rota e certifique-se de que nenhum firewall bloqueie a conexão local do túnel. Se você usou a pesquisa recentemente, confirme se o URL do webhook agora está preenchido. Acione uma atualização real enviando uma mensagem para o bot.
As atualizações chegam repetidamente
Status do registro e tempo de resposta. Exceções após o recebimento da solicitação podem transformar um valor pretendido de 200 em 500. Retorne 200 imediatamente, torne o processamento idempotente e use reprodução de webhook controlada em vez de esperar pelas novas tentativas do provedor durante a depuração.
Teste consultas e arquivos de retorno de chamada, não apenas texto
Uma matriz de teste de bot útil cobre mais de message.text. Envie uma foto com legenda, compartilhe um contato, edite uma mensagem e pressione um botão do teclado embutido. Para consultas de retorno de chamada, chame answerCallbackQuery imediatamente para que o cliente pare de mostrar seu indicador de progresso e, em seguida, execute um trabalho mais lento separadamente. As atualizações de arquivos contêm identificadores; baixar os bytes é uma segunda operação da Bot API e não deve atrasar a resposta do webhook.
Mantenha os fixtures feitos a partir de atualizações higienizadas para testes unitários, mas preserve o caminho de transporte completo para pelo menos um teste de cada tipo suportado. Um acessório prova que seu despachante entende uma carga útil; uma entrega em túnel real também comprova registro, TLS, cabeçalhos, análise de corpo e comportamento de confirmação. Ao adicionar uma nova entrada allowed_updates, chame setWebhook novamente e verifique se getWebhookInfo reflete a configuração pretendida.
Remova o webhook após a sessão local
curl -sS -X POST \
"https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/deleteWebhook" \
-d "drop_pending_updates=false"
Excluir o webhook permite retornar para getUpdates. Se a URL do túnel mudar na próxima sessão, chame setWebhook novamente. Para diagnósticos adicionais, siga o fluxo de trabalho geral de depuração de webhook local .
