---
name: notify_telegram
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func NotifyTelegram(botToken string, chatID string, text string, parseMode string) error"
description: "Envía un mensaje a un chat de Telegram via Bot API. Útil para alertas de deploy, fallos de assertions y eventos del bucle reactivo."
tags: [notify, telegram, alert, http, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: ["bytes", "encoding/json", "fmt", "io", "net/http", "time"]
params:
  - name: botToken
    desc: "Token del bot Telegram (formato 123456:ABC-DEF...). Sin prefijo 'bot'."
  - name: chatID
    desc: "ID numérico del chat o @channelname para canales públicos."
  - name: text
    desc: "Cuerpo del mensaje. Máximo 4096 chars según límite de Telegram. Si excede, se trunca a 4093 + '...'."
  - name: parseMode
    desc: "Modo de formato del texto. Valores válidos: '' (plain), 'Markdown', 'MarkdownV2', 'HTML'. Cualquier otro valor devuelve error."
output: "error nil si el mensaje se envió correctamente. Error con status code y body si la API responde con status != 200. Error con description si ok=false en la respuesta JSON."
tested: true
tests:
  - "texto largo se trunca a 4096 chars con sufijo ..."
  - "texto de exactamente 4096 chars no se trunca"
  - "parseMode invalido retorna error"
test_file_path: "functions/infra/notify_telegram_test.go"
file_path: "functions/infra/notify_telegram.go"
---

## Ejemplo

```go
err := NotifyTelegram("123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11", "-1001234567890", "Deploy completado ✓", "")
if err != nil {
    log.Printf("telegram notify failed: %v", err)
}

// Con Markdown
err = NotifyTelegram(token, chatID, "*ERROR*: assertion failed en `metabase_entities`", "Markdown")
```

## Notas

Sin retries. Caller hace backoff si necesario. Timeout fijo de 10 segundos. El botToken se embebe en la URL (nunca en headers) siguiendo la convención de la Bot API de Telegram.
