Programar un bot de Telegram usando PHP

Mediante un bot de Telegram podemos crear chats dónde el interlocutor sea un programa informático en vez de una persona.

Instalación

Telegram es una aplicación de mensajería instantánea donde prima la seguridad en las comunicaciones. Una gran parte de la aplicación está licenciada como código libre

Podemos instalarnos Telegram en nuestro dispositivo móvil o podemos acceder vía web.telegram.org.

1) Crear un bot usando @BotFather

El usuario @BotFather es un bot que nos permite crear nuestros propios bots (20 cómo máximo). Para ello hay que establecer con él una conversación de esta guisa:

Tú:
/newbot
BotFather:
¿Cómo se va a llamar el bot?
Tú:
Bender
BotFather:
Elige un nombre de usuario para el bot que acabe en bot
Tú:
bender_bot
BotFather:
¡Hecho! Tu token secreto es: 123456789:A1bC2dEf3GhIj4KlMnO5pQrStU6vWxYz789

Para acceder a la documentación del bot podemos acudir a la página core.telegram.org/bots/api

Si queremos gestionar nuestros bots tenemos disponible el comando /mybots

2) Iniciar un chat con el bot que hemos creado

Podemos establecer un chat con el usuario @bender_bot como si se tratase de una persona

Como nosotros somos quienes programamos el bot hemos de poder hacer lo siguiente:

  • Hablar: Enviar mensajes al chat. Para ello necesitamos conocer el chat_id
  • Escuchar: Recibir mensajes del chat. Necesitamos que Telegram nos dé los mensajes pendientes.

3) Escuchar los mensajes enviados a nuestro bot

Para obtener los mensajes que alguna persona escriba en los chats de nuestro bot usaremos el método setWebHook. Con este método hemos de proporcionar la dirección de una página PHP con protocolo HTTPS que será llamada por Telegram cada vez que alguien se comunique con nuestro bot.

  • El comando setWebHook de Telegram es el siguiente:

    https://api.telegram.org:443/bot<TOKEN>/setwebhook?url=<WEBHOOK>
  • Supongamos que el token secreto que nos dio Telegram al dar de alta el bot fue:

    123456789:A1bC2dEf3GhIj4KlMnO5pQrStU6vWxYz789
  • Supongamos que nuestra página web, que va a atender a Telegram, tiene la dirección:

    https://midominio.es/webhook.php
  • El comando final sería:

    https://api.telegram.org:443/bot123456789:A1bC2dEf3GhIj4KlMnO5pQrStU6vWxYz789/setwebhook?url=https://midominio.es/webhook.php

La respuesta JSON de Telegram al ejecutar el comando será:

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

La página webhook.php

Para ver que tipo de mensajes nos envía Telegram lo que haremos será guardar todos los mensajes en el archivo webhook.log. Dicho archivo deberá tener permiso de escritura

<?php
$request = file_get_contents("php://input");
$date = date('Y-m-d H:i:s');
$content = "$date\n$request\n\n";
file_put_contents("webhook.log", $content, FILE_APPEND);

El archivo webhook.log

Una vez ejecutado el comando setWebHook y tras haber escrito algún mensaje en un chat con nuestro bot podremos inspeccionar el fichero webhook.log a ver que nos está enviando Telegram.

Nos enviará mensajes JSON como el siguiente:

{
  "update_id": 1223334444,
  "message": {
    "message_id": 10,
    "from": {
      "id": 5551234,
      "is_bot": false,
      "first_name": "Pepe",
      "last_name": "Pérez",
      "language_code": "es"
    },
    "chat": {
      "id": 5551234,
      "first_name": "Pepe",
      "last_name": "Pérez",
      "type": "private"
    },
    "date": 1511111110,
    "text": "Probando"
  }
}

En el mensaje se nos indica cual es identificador del chat, que necesitaremos para enviar mensajes a ese chat

4) Hablar en los chats dónde está unido nuestro bot

Una vez que ya sabemos el chat_id, que hemos averiguado gracias a nuestro webhook, podemos enviar mensajes a ese chat con el comando setMessage

  • El comando setMessage de Telegram es el siguiente:

    https://api.telegram.org:443/bot<TOKEN>/setmessage?chat_id=<CHAT_ID>&text=<TEXT>
  • El comando final sería:

    https://api.telegram.org:443/bot123456789:A1bC2dEf3GhIj4KlMnO5pQrStU6vWxYz789/setmessage?chat_id=5551234&text=Hola

La respuesta JSON de Telegram al ejecutar el comando será algo como lo siguiente:

{
  "ok": true,
  "result": {
    "message_id": 13,
    "from": {
      "id": 999000111,
      "is_bot": true,
      "first_name": "Caliban",
      "username": "caliban_bot"
    },
    "chat": {
      "id": 5551234,
      "first_name": "Pepe",
      "last_name": "Pérez",
      "type": "private"
    },
    "date": 1511007159,
    "text": "Hola"
  }
}

Hablar en el chat usando PHP

<?php
function sendMessage($chatId, $text) { $TOKEN = "123456789:A1bC2dEf3GhIj4KlMnO5pQrStU6vWxYz789"; $TELEGRAM = "https://api.telegram.org:443/bot$TOKEN"; $query = http_build_query(array( 'chat_id'=> $chatId, 'text'=> $text, 'parse_mode'=> "Markdown", // Optional: Markdown | HTML )); $response = file_get_contents("$TELEGRAM/sendMessage?$query"); return $response; }

Hablar usando un comando Linux

$ curl -s -X POST https://api.telegram.org/bot<TOKEN>/sendMessage
  -d chat_id=<CHAT_ID>
  -d text="<TEXT>"

Hablar usando un script Bash

#!/bin/bash
TOKEN="<TOKEN>"
CHAT_ID=<CHAT_ID>
TEXT="<TEXT>"
TELEGRAM="https://api.telegram.org/bot$TOKEN/sendMessage"
curl -s -X POST $TELEGRAM -d chat_id=$CHAT_ID -d text="$TEXT"

5) Nuestro bot responde cuando se le habla

Vamos a conseguir que el bot responda a lo que se le diga mediante un eco. Es decir, repetir como un loro todo lo que se le diga. Para ello vamos a cambiar el código de la página webhook.php

Página webhook.php con eco

<?php
$json = file_get_contents("php://input");
$request = json_decode($json, $assoc=false);
$chatId = $request->message->chat->id;
$text = $request->message->text;
sendMessage($chatId, $text);

6) Hacer que el webhook sea más seguro

En el momento de ejecutar el comando setWebHook podríamos pasar el token secreto a nuestra página:

https://api.telegram.org:443/bot123456789:A1bC2dEf3GhIj4KlMnO5pQrStU6vWxYz789/setwebhook?url=https://midominio.es/webhook.php/123456789:A1bC2dEf3GhIj4KlMnO5pQrStU6vWxYz789

Y luego, dentro de nuestro código, comprobamos que se nos esté pasando el token correcto

Página webhook.php final

<?php

$TOKEN = "123456789:A1bC2dEf3GhIj4KlMnO5pQrStU6vWxYz789";
$TELEGRAM = "https://api.telegram.org:443/bot$TOKEN"; 

if (checkToken()) 
{
  $request = receiveRequest();
  $chatId = $request->message->chat->id;
  $text = $request->message->text;
  sendMessage($chatId, $text);
}

function checkToken() 
{
  global $TOKEN;
  $pathInfo = ltrim($_SERVER['PATH_INFO'] ?? '', '/');
  return $pathInfo == $TOKEN;
}

function receiveRequest() 
{
  $json = file_get_contents("php://input");
  $request = json_decode($json, $assoc=false);
  return $request;
}

function sendMessage($chatId, $text) 
{
  global $TELEGRAM;	

  $query = http_build_query([
    'chat_id'=> $chatId,
    'text'=> $text,
    'parse_mode'=> "Markdown", 
  ]);

  $response = file_get_contents("$TELEGRAM/sendMessage?$query");
  return $response;
}

Otra versión del código usando POO: TelegramBot.php

Enlaces

Mis bots

  • @cifrasletras_bot — Convertir cifras en letras.
    Configuración: euro, femenino o masculino
  • @matematicas_bot — Cálculos matemáticos.
    Opciones: es primo, factorial, factorización, fibonacci, potencia de 2
  • @codigo_bot — Cálculo de códigos.
    Opciones: iban, nif

Comentarios

Proinf.net, ©2003-2017 ci 3.1.6 (CC) Esta obra está bajo una licencia de Creative Commons Este software está sujeto a la CC-GNU GPL