Bots de Telegram
Comandos, botões, conversa com estado e webhook — e testes que rodam sem token e sem rede.
`Arcane.Telegram` é o módulo de bots. A Bot API do Telegram é HTTP com JSON: falar com ela do zero é possível e chato — noventa métodos, um formato de erro próprio, um limite de taxa que responde no corpo e não no status, upload multipart, e uma sintaxe de formatação que quebra a mensagem inteira se um caractere escapar.
adopt Arcane.Telegram as Tg
app := Tg.app(Tg.segredo_do_ambiente())
mark @app.comando("start")
action comecar(ctx):
ctx.responder($"Ola, {ctx.nome()}!")
app.rodar()Isso é o bot inteiro. ctx traz quem falou, o que disse e como responder; o rodar faz long polling até alguém parar.
Do zero ao bot no ar#
dataforge telegram new meubot # cria o projeto
cd meubot
export TELEGRAM_TOKEN="123456:AAH..." # o token vem do @BotFather
dataforge telegram doctor # confere o que falta
dataforge telegram run # sobe em long pollingO módulo também nunca deixa o token aparecer numa mensagem de erro. Ele está na URL de toda chamada, e a URL entra em todo traceback — um token num log de CI é um bot sequestrado.
O que chega em `ctx`#
| O que é | |
|---|---|
ctx.texto | o texto da mensagem, ou a legenda da mídia |
ctx.args | o que veio depois do comando, já separado |
ctx.dados | o dados do botão que foi clicado |
ctx.chat | o id do chat |
ctx.nome() · ctx.apelido() | quem falou |
ctx.e_privado() · ctx.e_grupo() · ctx.e_admin() | onde, e com que poder |
ctx.estado | o vault deste chat, que sobrevive entre mensagens |
ctx.update | o update cru, para o campo que nenhuma conveniência cobre |
E para responder: ctx.responder, ctx.citar (que responde citando, o que dá contexto em grupo), ctx.responder_foto, ctx.responder_documento, ctx.editar, ctx.apagar, ctx.digitando e ctx.avisar.
O despacho para no primeiro que casa#
O update é casado uma vez, na ordem do registro. A alternativa — entregar a todos — parece mais flexível e produz o bug mais confuso que um bot tem: duas respostas para uma mensagem, e ninguém sabe de onde veio a segunda.
mark @app.comando("start")
action comecar(ctx):
ctx.responder("Ola!")
mark @app.texto("\\b(oi|ola)\\b")
action cumprimento(ctx):
ctx.responder("Oi!")
mark @app.qualquer()
action resto(ctx):
ctx.responder("Nao entendi.")Onde continuar#
Comandos e roteamento
Comando, texto, botão, mídia, consulta inline e middleware.
Teclados e formatação
Botões, o teclado do celular, e o escape que salva a mensagem.
Conversas e estado
A máquina de estados por chat, e onde ela mora.
Testar sem rede
A sonda injeta updates e lê o que o bot mandou.
Publicar
Webhook, HTTPS, e por que deploy não existe.