Plugin — Telegram Bot

Plugin — Telegram Bot

El plugin de Telegram convierte mensajes de texto y notas de voz recibidos en un bot en tareas cascarón. Opera vía webhook: Telegram envía un POST al endpoint de Joe por cada actualización.

Mecanismo: Webhook  ·  Autenticación: Secret Token en header  ·  Tipos soportados: Texto, Voz

Endpoint del webhook

PropiedadValor
MétodoPOST
Ruta/plugins/telegram/webhook/{plugin_id}/
ParámetroUbicaciónDescripción
plugin_id Path ID del PluginConfig registrado para este bot.
X-Telegram-Bot-Api-Secret-Token Header Token secreto configurado al registrar el webhook en Telegram.

Configuración paso a paso

  1. Crear el bot en Telegram con BotFather
    /newbot
    # Sigue las instrucciones, BotFather te entrega:
    # Token: 1234567890:ABCDefghIJKlmnOPQrsTUVwxyz
  2. Registrar el PluginConfig en Joe
    from apps.common.models import PluginConfig
    
    config = PluginConfig(
        usuario=user,
        servicio="telegram",
        identificador="@joe_bot",
        metadatos={"webhook_secret": "mi_secret_seguro_aleatorio"},
    )
    config.set_token("1234567890:ABCDefghIJKlmnOPQrsTUVwxyz")
    config.save()
    # Anota el ID generado: config.pk → ej. 3
    # Anota el código de verificación: config.codigo_verificacion → ej. JOE-A1B2
  3. Registrar el webhook en Telegram
    POST https://api.telegram.org/bot<TOKEN>/setWebhook
    Content-Type: application/json
    
    {
      "url": "https://joe.pedroospino.net/plugins/telegram/webhook/3/",
      "secret_token": "mi_secret_seguro_aleatorio"
    }
    import requests
    
    TOKEN = "1234567890:ABCDefghIJKlmnOPQrsTUVwxyz"
    resp = requests.post(
        f"https://api.telegram.org/bot{TOKEN}/setWebhook",
        json={
            "url": "https://joe.pedroospino.net/plugins/telegram/webhook/3/",
            "secret_token": "mi_secret_seguro_aleatorio"
        }
    )
    print(resp.json())  # {"ok": true, "result": true, ...}
    const TOKEN = '1234567890:ABCDefghIJKlmnOPQrsTUVwxyz';
    const { data } = await axios.post(
      `https://api.telegram.org/bot${TOKEN}/setWebhook`,
      {
        url: 'https://joe.pedroospino.net/plugins/telegram/webhook/3/',
        secret_token: 'mi_secret_seguro_aleatorio'
      }
    );
    var token = "1234567890:ABCDefghIJKlmnOPQrsTUVwxyz";
    var body = new StringContent(
        JsonSerializer.Serialize(new {
            url = "https://joe.pedroospino.net/plugins/telegram/webhook/3/",
            secret_token = "mi_secret_seguro_aleatorio"
        }),
        Encoding.UTF8, "application/json"
    );
    var response = await client.PostAsync(
        $"https://api.telegram.org/bot{token}/setWebhook", body);
    String token = "1234567890:ABCDefghIJKlmnOPQrsTUVwxyz";
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://api.telegram.org/bot" + token + "/setWebhook"))
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(
            "{\"url\":\"https://joe.pedroospino.net/plugins/telegram/webhook/3/\"," +
            "\"secret_token\":\"mi_secret_seguro_aleatorio\"}"
        ))
        .build();

    Respuesta esperada: {"ok": true, "result": true, "description": "Webhook was set"}

  4. Verificar el webhook
    GET https://api.telegram.org/bot<TOKEN>/getWebhookInfo
    import requests
    
    TOKEN = "1234567890:ABCDefghIJKlmnOPQrsTUVwxyz"
    resp = requests.get(f"https://api.telegram.org/bot{TOKEN}/getWebhookInfo")
    print(resp.json())
    const TOKEN = '1234567890:ABCDefghIJKlmnOPQrsTUVwxyz';
    const { data } = await axios.get(
      `https://api.telegram.org/bot${TOKEN}/getWebhookInfo`
    );
    var token = "1234567890:ABCDefghIJKlmnOPQrsTUVwxyz";
    var response = await client.GetAsync(
        $"https://api.telegram.org/bot{token}/getWebhookInfo");
    String token = "1234567890:ABCDefghIJKlmnOPQrsTUVwxyz";
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://api.telegram.org/bot" + token + "/getWebhookInfo"))
        .GET()
        .build();
  5. Vincular el chat (Soberanía del Usuario)

    Abre el bot en Telegram y envía el comando de verificación con el codigo_verificacion del paso anterior:

    /start JOE-A1B2

    El bot responderá: "✅ ¡Bot vinculado con éxito! Ya puedes enviarme notas de voz o texto."
    Hasta completar este paso, cualquier mensaje recibido será rechazado con un aviso.

Soberanía del Usuario: El flujo de verificación garantiza que solo el dueño del PluginConfig puede vincular un chat. El código JOE-XXXX es único por registro y se genera automáticamente al crear el plugin.

Flujo de un mensaje entrante

  1. Telegram envía POST al webhook con el update JSON.
  2. Joe valida el header X-Telegram-Bot-Api-Secret-Token contra el webhook_secret almacenado.
  3. Se deserializa el payload (TelegramUpdate).
  4. Si el mensaje es /start JOE-XXXX: se valida el código, se establece verificado=True y se guarda el chat_id_verificado.
  5. Si el plugin no está verificado: el bot avisa al usuario y descarta el mensaje (sin crear tarea).
  6. Si es texto: se crea una tarea con tipo=telegram y el texto como título.
  7. Si es voz: se crea una tarea con tipo=telegram_voice y pendiente_stt=True en metadatos.
  8. Joe responde {"ok": true} con HTTP 200 (evita reintentos de Telegram).
  9. El bot envía un mensaje de confirmación al chat: "✅ Recibido. Encolando... [CODIGO]"

Campos en metadatos_extra de la tarea

CampoDescripción
chat_idID del chat de Telegram. Necesario para responder.
message_idID del mensaje en Telegram.
plugin_idID del PluginConfig que procesó el mensaje.
owner_idID del usuario dueño del plugin.
texto_originalTexto completo del mensaje (solo en tareas de texto).
pendiente_stttrue si es una nota de voz pendiente de transcripción.
Nota V1.5 (NOVA): El soporte para transcripción de audio (Whisper STT) está planificado para V1.5. Actualmente las notas de voz generan una tarea pero no se transcriben automáticamente.

Campos del PluginConfig para Telegram

CampoValor esperado
servicio"telegram"
identificadorUsername del bot: @joe_bot
token_cifradoBot token de BotFather (cifrado con Fernet)
metadatos.webhook_secretString aleatorio seguro. Se envía a Telegram al registrar el webhook.
codigo_verificacionGenerado automáticamente (ej. JOE-A1B2). El usuario lo usa en /start.
verificadoFalse hasta que el usuario complete el flujo /start.
chat_id_verificadonull hasta la verificación. Luego contiene el ID del chat vinculado.