El proceso lleva tiempo por la compilación que requiere, pero no es complicado en absoluto, dado que cada parte está documentada, enlazo las fuentes al final del artículo. Me he decidido a escribirlo porque aunque sí es posible encontrar cada parte por separado, no he encontrado un artículo que lo especifique todo junto y si puede servirle a alguien bienvenido sea. Sí que hay mucho al respecto de bots Telegram para Raspberry pero en Python, está la librería en C++ que da acceso a la api de Telegram y hay documentación de cómo compilar Boost, pero cada cosa por un lado, no todo junto y en una Raspberry. Vamos con el índice:

  • Infraestructura requerida
  • Compilar Boost
  • Compilar API Telegram
  • Ejemplo funcional
  • Referencias

 

 

 Infraestructura requerida

Indicar que el proceso lo he llevado a cabo sobre una Raspberry Pi 3, aunque no obstante es exportable cualquier otro modelo de Raspberry. Es previsible que en una Raspberry con 512 MB de RAM sea necesario configurar un espacio de swap extra y resulta muy interesante hacerlo para una Pi Zero, dado el precio que tiene y las posibilidades de automatización y comunicaciones que ofrece un bot Telegram integrado en una Raspberry.

Hay al menos 2 librerías en C++ que implementan la API de Telegram, he cogido tgbot-cpp, la probé previamente en un PC con Debian y vi que era ciertamente funcional, por eso me he ido a por ella, no sé si cualquier otra es mejor o peor. Esta librería requiere de una versión de Boost (otra librería) superior a la que por defecto trae Raspbian, no la he encontrado precompilada para el procesador ARM que lleva mi Raspberry y esto me ha obligado a bajar la última versión y compilarla a mano. Durante la compilación de Boost, que duró varias horas (no me molesté en medirlo), tenía cargado el interfaz gráfico de Pixel pero ninguna otra aplicación y no configuré memoria swap extra. 

 

Compilar Boost

Esta librería es requerida por tgbot-cpp y resulta que la versión que trae Raspbian es demasiado antigua, cosa que pasa igual ahora según escribo esto en cualquier Debian 8 Jessie estable (no SID). Así que a compilar. 

Descargar Boost

Cuando escribo esto la última version sigue siendo la que usé la semana pasada, la 1.63. Es un tar.bz2 que hay que descomprimir en una carpeta, reproduzco el proceso funcional sobre esta versión 1.63, es fácil que en el futuro haya pasos que cambien:

http://downloads.sourceforge.net/project/boost/boost/1.63.0/boost_1_63_0.tar.bz2

Corregir primero un error en la ruta a los ficheros de cabecera

Descomprimido el fichero, nos introducimos en la carpeta en la que ya está todo y ejecutamos esta sustitución:

sed -e '/using python/ s@;@: /usr/include/python${PYTHON_VERSION/3*/${PYTHON_VERSION}m} ;@' \
    -i bootstrap.sh
Compilar e instalar Boost (tarda así que paciencia)
./bootstrap.sh --prefix=/usr
./b2 stage threading=multi link=shared
./b2 install threading=multi link=shared
 

Compilar tgbot-cpp

Lo más adecuado creo que es ver directamente la página en github, por si el autor hace cambios en el proceso, he clonado y he seguido los pasos que recomienda sin ninguna incidencia.

https://github.com/reo7sp/tgbot-cpp

 

Ejemplo funcional

Es un bot que básicamente repite lo que le digas y tiene un comando /Start que responde saludando. Hasta ahí es el ejemplo que está en el git del autor con un añadido: he implementado otro comando que es /capullo que si se ejecuta repetidas veces acaba respondiendo una sarta de improperios. Puede no ser muy educativo, pero es que no imaginaba que acabara siendo funcional y mucho menos que tuviera que explicarlo, mientras tanto me resultaba una compensación necesaria al tiempo de oscuridad en medio de la lectura de diferentes funtes y la compilación, darle un toque irreverente. Ahora mismo el mínimo esfuerzo es publicar lo que ya está hecho, que no me sobra el tiempo.

#include <stdio.h>
#include <tgbot/tgbot.h>

int contador=0;

int main() 
{
    TgBot::Bot bot("353223542:AAHrJSaCNuv49WK_-DaAqra-1i6inNzBtqU");

    bot.getEvents().onCommand("start", [&bot](TgBot::Message::Ptr message) {
        bot.getApi().sendMessage(message->chat->id, "Hi!");
    });

    bot.getEvents().onCommand("capullo", [&bot](TgBot::Message::Ptr message) {
        switch (contador)
        {
            case 0: bot.getApi().sendMessage(message->chat->id, "No me calientes!");
            contador++;
            break;
            case 1: bot.getApi().sendMessage(message->chat->id, "GRRRRR, NO SIGAS EH!");
            contador++;
            break;
            case 2: bot.getApi().sendMessage(message->chat->id, "PAYASO, ATONTAO, PELELE, EMPANAO, BOBOTONTO, TORRIJO!");
            contador=0;
            break;
        }

    });

    bot.getEvents().onAnyMessage([&bot](TgBot::Message::Ptr message) {
        printf("User wrote %s\n", message->text.c_str());
        if (StringTools::startsWith(message->text, "/start")) 
        {
            return;
        }
        else if (StringTools::startsWith(message->text, "/capullo"))
        {
            return;
        }
        else bot.getApi().sendMessage(message->chat->id, "Your message is: " + message->text);
    });
    
    try {
        printf("Bot username: %s\n", bot.getApi().getMe()->username.c_str());
        TgBot::TgLongPoll longPoll(bot);
        while (true) {
            printf("Long poll started\n");
            longPoll.start();
        }
    } catch (TgBot::TgException& e) {
        printf("error: %s\n", e.what());
    }
    return 0;
}

 

Screenshot 20170426 132826

 

Referencias

http://www.linuxfromscratch.org/blfs/view/8.0/general/boost.html

https://github.com/reo7sp/tgbot-cpp