Tutoriales, noticias y soluciones informáticas

Crea un bot de Telegram para tu Raspberry. Ordénale cosas y habla con ella a distancia.

Seguro que si tienes una Raspberry o un servidor linux encendido todo el día realizando alguna tarea has pensado alguna vez que estaría bien que ese mismo equipo te enviara reportes de lo que está haciendo. O posiblemente en algún momento ha pasado que necesitabas hacerle algún cambio o realizar alguna comprobación pero te has encontrado alejado de dónde está instalada.

Hola. Pues a mi me ha pasado una vez. Tuve que acabar mandándole un mensaje a mi hermana que estaba en casa para que me la reiniciase y...

Bienvenido, usuario anónimo. Tal vez tu hermana pudiera ayudarte en ese momento, pero no siempre vas a tener la suerte de tener a alguien que pueda reiniciar tu equipo o hacer la modificación que necesitas en el momento preciso. En muchos entornos empresariales hay Raspberrys «solas ante el peligro» sin nadie que pueda atenderlas. Una solución que estaría muy muy bien sería poder «hablar» con tu raspberry por medio de algún programa de mensajería, como WhatsApp o Telegram. Podríamos enviarle un mensaje con lo que queremos y la Raspberry nos obedecería. Y también podría avisarnos por mensajería de reinicios inesperados o de cuándo va a realizar alguna tarea concreta. Una comunicación en las dos direcciones en toda regla. En este tutorial vamos a aprender a hacerlo.

¡Eh! ¡Eh! ¡Para el carro! ¿Te crees que vivimos en Matrix o en Minority Report? Hacer esas cosas no está a disposición del común de los mortales hoy en día. Nadie puede hablar con un aparato por una aplicación de mensajería. 

Estás muy equivocado. Hoy en día podemos hacerlo sin problemas gracias a los bots. Telegram en el 2015 puso a disposición de sus usuarios una «API» (Interfaz de programación de aplicaciones) que nos permite crear aplicaciones informáticas para que manden mensajes por Telegram a quien queramos. Esta API se puede usar con un bot de Telegram. Un bot es una cuenta especial que podemos crear en telegram, que no necesita asociarse a ningún teléfono en concreto y que permite enviar y recibir mensajes desde y hacia otras cuentas. Como todo esto es gratuito, podemos plantearnos algo así de forma muy sencilla y asequible a cualquiera.

¡Oye! ¡Pues esto pinta bien! Pero mira... Mejor ¿Por qué no nos explicas cómo hacer todo esto con WhatsApp en lugar de con Telegram? Es que WhatsApp es la aplicación de mensajería que usa todo el mundo. Yo no uso Telegram y...

Como ya te dije en el tutorial que hice acerca de cómo gestionar contraseñas, por un lado WhatsApp es una aplicación insegura, en la que sabes a ciencia cierta (o al menos deberías ser consciente de ello) que todo lo que escribes puede puede ser visto por los trabajadores de WhatsApp (recordad que pertenece a Facebook), sus subcontratas o cualquier gobierno que se lo pida. Telegram por el momento ha mostrado más decencia con los datos de sus usuarios. Debería empezar a entrarnos en la cabeza que usar WhatsApp es un verdadero despropósito y un riesgo para nuestros datos, privacidad y seguridad. No… no me sirve la excusa de «todo el mundo lo usa». Por norma general, si alguien me escribe por WhatsApp, le respondo por Telegram.

Además aunque quisiéramos, por el momento, salvo que seas una empresa y pongas pasta de por medio este tipo de cosas no se pueden hacer de forma sencilla por WhatsApp. Por no decir que los bots de WhatsApp necesitan identificarse con un número de teléfono distinto al tuyo (vamos… que necesitas una línea de teléfono a mayores sólo para esto). WhatsApp no es una opción para hacer lo que estamos planteando.

Veeeenga... aceptamos barco. ¿Vamos al lío?

Venga, pues vamos a ver cómo hacer todo esto paso a paso, de forma que sea imposible perderse. Por cierto… aunque me voy a centrar en una Raspberry, porque es el equipo que tengo más a mano ahora mismo, esto se puede aplicar sin ningún problema a cualquier equipo que ejecute cualquier distribución de Linux basada en Debian.

1- Cómo crear un bot en Telegram.

En primer lugar debéis tener Telegram instalado con una cuenta habilitada. Para ilustrar el tutorial voy a usar la mayor parte del tiempo la versión «desktop» de Telegram (La que nos permite instalarlo en nuestro ordenador personal), y de hecho es la versión que os aconsejo usar para seguir con el tutorial de forma cómoda.

En primer lugar vamos a irnos a los contactos de Telegram y vamos a buscar uno que se llama de la siguiente forma:

@BotFather

Haciendo esa búsqueda, a mi me sale esto:

Os pongo todos los resultados que me salen en la búsqueda para que no haya duda ninguna acerca de qué bot se trata, ya que hay algunos con nombres e imágenes similares. En mi lista aparece el primero de todos, en «contactos y chats» porque ya lo usé con mi usuario. En todo caso fijaos en el nick que hay debajo de los nombres y que empiezan por «@» para no equivocaros. Para más indicaciones, la imagen de su usuario es esta.

Si hacemos doble click para hablar con este «usuario» tan especial, nos aparecerá en Telegram algo similar a esto.

Pulsamos en el botón «iniciar» que hay debajo del mensaje y lo que nos aparecerá a continuación serán unas breves instrucciones de cómo manejar el bot. Podemos ver una lista de comandos que podemos usar para crear nuestro bot particular.

¿Y dónde vamos a tener que poner esos comandos? Pues en el campo inferior dónde normalmente escribiríamos a cualquier «humano», dónde pone «escriba un mensaje». Así que en ese recuadro empezaremos escribiendo «/newbot» para comenzar la creación de nuestro bot. Lo primero que nos preguntará es el nombre que le vamos a poner al bot. Yo le voy a poner al mío «flopybot», pero podéis poner el que queráis. Simplemente escribidlo como si estuvierais hablando con otra persona.

Ahora os pedirá ponerle al bot un nombre de usuario, y os obligará a que ese nombre de usuario termine en «bot». En un alarde de originalidad, voy a ponerle el mismo nombre de usuario que el nombre del bot, así que pongo de nuevo «flopybot». De nuevo poned vosotros el nombre que os apetezca, pero terminado en «bot».

Si os fijáis, en el mensaje que os pone una vez creado el bot, se os da un «Token» para la API que os comentaba al principio del artículo. Ese token va a ser importante, así que copiadlo porque lo usaremos varias veces.

Antes de empezar a trabajar con el bot vamos a hacerle una cosa interesante, que es ponerle una imagen de perfil. Así va a ser más sencillo localizarlo entre todos tus contactos. Algo útil es sacarle una foto a tu Raspberry y ponerla como foto de perfil, pero tened en cuenta que la imagen ha de estar en formato «.jpg» y ha de ser pequeña (si es demasiado grande, BotFather se va a quejar). Una vez que tenemos la foto, debemos escribir a «BotFather» el comando «/setuserpic», y obtendremos una pantalla como ésta.

Escogemos el bot al que queremos cambiarle la foto de perfil en la zona inferior y nos saldrá lo siguiente en pantalla.

Ahora debemos coger la foto de nuestra Raspberry y arrastrarla al bot, y nos pondrá este mensaje.

¡¡Perfecto!! Ya tenemos el bot listo para empezar a trabajar con él.

2- Un bot sencillito para empezar con buen pie. Enviar mensajes al iniciarse acciones en Cron.

Vamos a empezar creando un sistema muy básico para que nuestra raspberry nos vaya diciendo lo que está haciendo (digamos… que es el primer nivel de dificultad), y luego ya nos atreveremos a hacer algo más complicado.

Vamos a conectarnos a nuestra Raspberry por SSH (Mediante Putty si accedemos a ella desde Windows o con el comando ssh si accedemos a ella mediante Linux o Mac OS). Os remito al punto 5 del tutorial que realizamos sobre cómo instalar Raspbian Server si no sabéis cómo realizar esta conexión.

Vamos a necesitar tener una carpeta dentro del «home» de nuestro usuario (la llamaremos aplicaciones) en la que guardar lo que vayamos creando. En caso de que hayáis realizado el tutorial en el que explico cómo medir las temperaturas de la raspberry ya la tendréis creada. De hecho os recomiendo encarecidamente que realicéis todo lo que se pone en él porque luego lo usaremos precisamente para preguntarle a la raspberry por su temperatura por Telegram. En caso contrario, simplemente desde nuestro terminal, situándonos en la carpeta home del usuario»pi» tecleamos lo siguiente:

mkdir aplicaciones

Nos situamos dentro de la carpeta tecleando lo siguiente:

cd aplicaciones

Ahora vamos a crear un script muy muy sencillo que sólo nos avisará por Telegram cuando la Raspberry haya sufrido un reinicio.

Para ello crearemos un archivo de texto al que vamos a llamar reinicio.sh, tecleando lo siguiente.

sudo nano reinicio.sh

Ahora copiad el siguiente código y ponedlo dentro del editor.

#!/bin/bash

TOKEN="aquí-va-el-token-de-tu-bot-de-telegram"
ID="aquí-va-el-id-del-usuario-de-destino-del-mensaje"
MENSAJE="La raspberry PI-Hole, PiVPN y Amule server se acaba de encender."
URL="https://api.telegram.org/bot$TOKEN/sendMessage"

curl -s -X POST $URL -d chat_id=$ID -d text="$MENSAJE"

Como os podéis imaginar, necesitáis cambiar tres líneas de ese archivo.

En la línea número 3, entre las comillas debéis poner el token del bot de Telegram que habéis creado. ¿Os acordáis que os dije más arriba que lo tuviérais a mano? Pues aquí lo tendréis que poner (y más adelante también).

En la línea número 4 hay que poner el id del usuario al que va destinado ese mensaje (que normalmente es tu usuario de telegram). Pero OJO: este id tenéis que averiguarlo. Hay que preguntarle a Telegram cuál es vuestro ID. Para ello nos vamos de nuevo a Telegram y buscamos al usuario «@userinfobot».

De nuevo cuidado con el usuario que escogéis. Fijaos que en la captura que os puse hay usuarios con un nombre parecido (@userinf y cosas así). Por tanto aseguraos de buscar el usuario con su nombre completo. Pulsamos sobre ese usuario y le enviamos el mensaje «/start». Nos devolverá directamente el id de nuestro usuario en la línea que empieza por «Id».

Una vez que tengamos el id de usuario, lo ponemos en la línea número 4 del archivo que estábamos creando en «nano», de forma que el archivo nos debería quedar similar a esto.

Y que no se me olvide: En la línea 5 podemos poner el mensaje que nos venga en gana.

Muy bien. Ahora que tenemos el script hecho, lo guardamos pulsando «Control»+»o» y salimos de nano con «Control»+»x». A estas alturas el archivo ya está creado, pero necesitamos hacer ese archivo ejecutable, cosa para nada complicada. Simplemente tecleamos lo siguiente en nuestro terminal.

chmod +x reinicio.sh

Y por supuesto, ahora vamos a probar lo que hemos hecho tecleando la siguiente línea:

./reinicio.sh

De inmediato, en nuestro Telegram debería saltar un mensaje que nos ha mandado nuestro bot. Algo similar a esto:

Oye tío. Eres un hacha... ya sé cómo mandarme un mensaje a mi mismo anunciando algo que ni siquiera ha sucedido. ¿Para qué %&$@# me sirve esto?

Tranquilo, mi anónimo amigo. Una de las cosas que podemos hacer con este método es añadirlo a las tareas del Cron de Linux. Cron es en Linux algo similar al programador de tareas de Windows. Es un sitio en el que podemos añadir tareas para que se ejecuten cuando nos venga en gana. Por ejemplo, podríamos poner una tarea en el Cron para que cada vez que la raspberry se encienda, nos mande un mensaje a nuestro telegram. De esta forma si hay un reinicio inesperado nos enteraremos al momento. Particularmente, además de esta tarea tengo añadida otra al cron para que la raspberry busque actualizaciones cada tres días y después de aplicarlas se reinicie. Por la noche, cada tres días se ejecuta esta tarea, pero antes del reinicio el cron me envía un mensaje con este método, y en cuanto la raspberry se ha iniciado me envía otro idéntico al del ejemplo que os estoy poniendo para saber que el reinicio se completó con normalidad. Si un día amanezco sólo con uno de los dos mensajes, entonces ya sé que algo ha ido mal.

Ah, pues suena útil. ¿Y eso cómo se hace?

Muy sencillo. Debemos escribir el siguiente comando en el terminal.

sudo crontab -e

y nos debería aparecer algo similar a esto:

Nos iremos a la parte inferior de ese archivo y añadiremos la siguiente línea:

@reboot ( sleep 30 ; sh /home/pi/aplicaciones/reinicio.sh ) >/dev/null 2>&1

Os explico lo que le estamos diciendo a Cron.

  • @reboot: Le decimos que ejecute que viene a continuación cada vez que se reinicie el equipo.
  • Los paréntesis: Entre ellos va lo que se va a ejecutar
  • Sleep 30: Decimos que espere 30 segundos para ejecutar el comando. Así le damos tiempo al sistema operativo a cargar todo lo necesario para que el comando se ejecute bien.
  • sh /home/pi/aplicaciones/reinicio.sh: Es el comando que ejecuta el script.
  • >/dev/null 2>&1: Esta parte significa que aunque esta línea genere algún mensaje en pantalla, no se nos muestre.

Al igual que antes, guardamos los cambios con «Control»+»o» y salimos con «Control»+»x». Si queremos, podemos reiniciar el equipo escribiendo en el terminal lo siguiente:

sudo shutdown -r now

En cuanto el sistema se reinicie, a los 30 segundos aproximadamente deberíais recibir el mensaje de Telegram.

Y por supuesto… esto podéis usarlo con cualquier tarea automatizada mediante Cron (y sin necesidad de retrasar la tarea).

3- Hagamos que la Raspberry nos envíe un mensaje de telegram cada vez que alguien se conecte por SSH.

Tener SSH activado en un equipo Linux se podría considerar un pequeño riesgo de seguridad. Si alguien averigua nuestra contraseña de SSH y tenemos el puerto mapeado hacia nuestra Raspberry, podrían hacer lo que quisieran con el equipo. Así que vamos a usar el bot para aumentar la seguridad de nuestro equipo. Cada vez que nos conectemos por SSH (nosotros u otra persona cualquiera), nuestra Raspberry nos enviará un mensaje por telegram indicando que alguien se ha conectado, indicándonos incluso la dirección IP de la conexión.

Esta tarea no se iniciará mediante Cron (ya que no es una tarea programada). Cada vez que se inicia una sesión en el terminal, el sistema lee y ejecuta el archivo llamado «.bashrc» (El punto del principio indica que es un archivo oculto). Así que vamos a editar este archivo. Nos vamos a la carpeta «home» del usuario «pi» y editamos ese archivo.

cd /home/pi
sudo nano .bashrc

El archivo está lleno de cosas. No vamos a tocar nada y nos desplazamos directamente al final y añadimos una línea nueva, que será tal que así.

curl -s -X POST https://api.telegram.org/bot"token_del_bot_del_telegram"/sendMessage -d chat_id="ID_de_vuestro_usuario_de_telegram" -d text="Alguien se acaba de conectar a la Raspberry que tiene el PiVPN, Pi-Hole y Amule server por ssh con la IP $(echo $SSH_CLIENT | awk '{ print $1}'). ¿Serás tú?">/dev/null 2>&1

Evidentemente sustituimos «token_del_bot_de_telegram» por el token de nuestro bot (Conservando las comillas), «ID_de_vuestro_usuario_de_telegram» por nuestro ID de Telegram (también conservando las comillas) y el texto del mensaje por el texto que queramos.

Ahora, cada vez que nos conectemos por SSH, Telegram nos mandará un mensaje similar a éste.

4) El bot definitivo: Mantener una «conversación» con nuestra Raspberry.

Vamos ahora a hacer el «más difícil todavía» y crear un bot que nos permitirá enviarle órdenes a nuestra raspberry directamente desde Telegram. Antes de comenzar os diré que el bot que vamos a instalar, entre otros incluye un comando para poder monitorizar la temperatura y otros parámetros de nuestro equipo. Para que funcione este comando en particular debéis haber realizado previamente lo que se dice en nuestro anterior tutorial acerca de la monitorización de las temperaturas en una Raspberry. Si no os interesa el monitoreo de las temperaturas, podéis seguir sin realizar el tutorial que os acabo de indicar (a sabiendas de que esa característica en particular no funcionará).

Otra cosa que quiero advertiros es que no he tenido buenas experiencias con cuentas de télegram en cuyo nombre hay acentos o caracteres no anglosajones. Si tenéis acentos en el nombre de vuestra cuenta de Telegram, poned vuestro nombre en mayúsculas y quitad los acentos. Si no lo hacéis, hay muchas posibilidades de que esto no funcione. Ya que estamos… si alguien sabe cómo solucionar este problema (me juego el tipo a que es algo sencillo que se me escapa) que me deje un comentario en el artículo, por favor.

Para empezar vamos a necesitar una librería específica escrita en «Python», que se trata de un conocido lenguaje de programación. Primero vamos a instalar todo lo necesario para que funcione.

Antes de nada instalaremos GIT con este comando.

sudo apt-get install git

Ahora nos vamos a la carpeta de aplicaciones que teníamos creada

cd /pi/aplicaciones

… y dentro de ella realizamos la descarga de la librería que vamos a usar con este comando:

git clone https://github.com/eternnoir/pyTelegramBotAPI

NOTA IMPORTANTE: Según indicaciones del usuario «Juan» en los comentarios de este artículo, en este punto deberíamos teclear este comando a mayores para evitar errores:

git checkout 3.6.6

En estos momentos se debería haber creado dentro de esa carpeta otra más llamada «pyTelegramBotAPI». Entramos en ella tecleando

cd pyTelegramBotAPI

Ahora tenemos un problema. Necesitamos instalar un añadido a Python para poder realizar la instalación de esta librería, así que tecleamos esto en el terminal.

sudo apt-get install python-setuptools

Ok. Ya estamos preparados para instalar la librería. Tecleamos lo siguiente dentro de la carpeta «pyTelegramBotAPI».

sudo python setup.py install

Perfecto. Ya tenemos instalado todo lo necesario. Dentro de la carpeta tenemos varios ejemplos que podemos usar, pero voy a daros todo ya hecho. Crearemos un archivo al que llamaremos «bot_pihole.py» mediante el siguiente comando:

sudo nano bot_pihole.py

dentro de ese archivo pegaremos el siguiente código (Agarraos los machos, que es largo).

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#import time
#time.sleep(60)

"""
This is a detailed example using almost every command of the API
"""
 
import telebot
from telebot import types
import time
import os

TOKEN = 'el_token_de_vuestro_bot'
 
knownUsers = [número_de_usuario_telegram] # todo: save these in a file,
userStep = {} # so they won't reset every time the bot restarts
 
commands = { # command description used in the "help" command
             'start': 'Get used to the bot',
             'ayuda': 'Da informacion sobre los comandos disponibles',
             'exec': 'Ejecuta un comando',
             'temp': 'Comprueba la temperatura de la raspberry',
             'reboot': 'Reinicia el servidor'
}
 
hideBoard = types.ReplyKeyboardRemove() # if sent as reply_markup, will hide the keyboard
 
# error handling if user isn't known yet
# (obsolete once known users are saved to file, because all users
# had to use the /start command and are therefore known to the bot)
def get_user_step(uid):
    if uid in userStep:
        return userStep[uid]
    else:
        knownUsers.append(uid)
        userStep[uid] = 0
        print "New user detected, who hasn't used \"/start\" yet"
        return 0
 
# only used for console output now
def listener(messages):
    """
    When new messages arrive TeleBot will call this function.
    """
    for m in messages:
        if m.content_type == 'text':
            # print the sent message to the console
            print str(m.chat.first_name) + " [" + str(m.chat.id) + "]: " + m.text
 
 
bot = telebot.TeleBot(TOKEN)
bot.set_update_listener(listener) # register listener
 
# handle the "/start" command
@bot.message_handler(commands=['start'])
def command_start(m):
    cid = m.chat.id
    if cid not in knownUsers:
        knownUsers.append(cid) 
        userStep[cid] = 0
#        command_help(m) # show the new user the help page
 
# help page
@bot.message_handler(commands=['ayuda'])
def command_help(m):
    cid = m.chat.id
    help_text = "Estos son los comandos disponibles: \n"
    for key in commands:
        help_text += "/" + key + ": "
        help_text += commands[key] + "\n"
    bot.send_message(cid, help_text)
 
# Reinicia servidor
@bot.message_handler(commands=['reboot'])
def command_long_text(m):
    cid = m.chat.id
    bot.send_message(cid, "Voy a reiniciar el servidor...")
    bot.send_chat_action(cid, 'typing')
    time.sleep(3)
    bot.send_message(cid, ".")
    os.system("sudo shutdown -r now")
 
# Mira temperaturas
@bot.message_handler(commands=['temp'])
def command_long_text(m):
    cid = m.chat.id
    bot.send_message(cid, "Vamos a comprobar si has puesto caliente a tu equipo...")
    bot.send_chat_action(cid, 'typing') # show the bot "typing" (max. 5 secs)
    time.sleep(2)
    f = os.popen("temperaturas")
    result = f.read()
    bot.send_message(cid, ""+result)
 
# Ejecuta un comando
@bot.message_handler(commands=['exec'])
def command_long_text(m):
    cid = m.chat.id
    bot.send_message(cid, "Ejecutando: "+m.text[len("/exec"):])
    bot.send_chat_action(cid, 'typing') # show the bot "typing" (max. 5 secs)
    time.sleep(2)
    f = os.popen(m.text[len("/exec"):])
    result = f.read()
    bot.send_message(cid, "Resultado: "+result)
 
 
# filter on a specific message
@bot.message_handler(func=lambda message: message.text == "Hola")
def command_text_hi(m):
    bot.send_message(m.chat.id, "Muy buenas")
@bot.message_handler(func=lambda message: message.text == "Hijoputa")
def command_text_hi(m):
    bot.send_message(m.chat.id, "Bocachancla")
@bot.message_handler(func=lambda message: message.text == "Hijo de puta")
def command_text_hi(m):
    bot.send_message(m.chat.id, "Chupacables")
@bot.message_handler(func=lambda message: message.text == "Capullo")
def command_text_hi(m):
    bot.send_message(m.chat.id, "Pagafantas")
    # default handler for every other text
 
 
@bot.message_handler(func=lambda message: True, content_types=['text'])
def command_default(m):
    # this is the standard reply to a normal message
    bot.send_message(m.chat.id, "No te entiendo, prueba con /ayuda")
 
bot.polling()

Como en los puntos anteriores, tendremos que cambiar el token (línea 15) por el del bot que hemos creado y el botuser (línea 17) por el id de vuestro usuario de telegram (el bot sólo va a responderle a los usuarios que estén en esa línea, que si no podría ser un despiporre si alguien averigua el nombre de nuestro bot). Voy a explicaros muy brevemente lo que hacen algunas líneas del código por si vosotros queréis hacer modificaciones en él.

De la línea 21 a la 25 tenemos los comandos con los que vamos a comunicarnos con nuestro bot. Tal como os dije al principio de esta sección, en el caso de que no os interese monitorizar las temperaturas, podemos eliminar la línea 24 (El comando «Temp»). En ese caso os interesaría también eliminar las líneas de la 85 a la 94 en las que se habilita el comando «/temp» para ver las temperaturas de nuestra máquina. Este intervalo de líneas es muy interesante, porque si tenemos la suficente soltura en programación, podemos hacer un copiar – pegar de ese bloque y crear comandos abreviados para sentencias de terminal extensas.

No quiero aburrir con este tema, así que vamos a guardar el código con «Control»+»o» y saldremos de «nano» con «Control»+»x». en esta ocasión no tendremos por qué convertir este código en ejecutable, puesto que es un archivo que necesita pyton para funcionar. Para probar si funciona el código tendremos que teclear lo siguiente en el terminal.

python bot_pihole.py

Y ahora sucederá algo extraño. El sistema operativo se pone como a la espera y la línea en la que se nos invita a poner más comandos ha desaparecido. Parece como si el sistema estuviera haciendo algo por detrás. Y efectivamente: está esperando a que le digamos algo por Telegram. Así que vamos a coger nuestro telegram (el del ordenador o el móvil) y vamos a escribirle algo a nuestro bot. Seamos educados y digámosle «Hola».

Como podéis observar, nuestro bot reconoce ese comando y nos saluda afectuosamente (Eso sí… la «H» debe estar en mayúsculas y el resto en minúsculas).

Vamos a probar a decirle algo más etéreo, como «reinicia la raspberry».

Vale… parece que no nos ha entendido, pero nos está dando un comando que a lo mejor nos aclara algo. Vamos a escribirle «/ayuda» a nuestro bot a través de Telegram.

Ahora sí que se empiezan a poner las cosas interesantes. Tenemos la lista de cosas que podemos hacer con este bot. Una de las más interesantes es el comando «/exec», con el que podremos teclear comandos de terminal.

Así que vamos a ponerle las cosas complicadas. Hay un comando para saber el espacio ocupado en disco, que es «df -h». Vamos a pedirle a nuestro bot que lo ejecute tecleándole «/exec df -h».

Si queremos reiniciar la raspberry desde el Telegram, podemos hacerlo con el comando «/reboot» o con el método anterior tecleando «/exec sudo shutdown -r now».

Para conocer las temperaturas de nuestra Raspberry, si hemos seguido el tutorial anterior, podemos hacerlo mediante el comando «/temp», que nos ofrecerá un resultado similar a este.

Vamos… que podemos sacarle mucho partido al Bot. Pero recordad que tenemos el terminal medio «colgado». Eso es porque el bot está ejecutándose. Tendremos que teclear «Control»+»C» para que nos vuelva a responder, pero eso terminará el programa y el bot dejará de funcionar. Si intentamos invocar este programa desde el Cron no nos funcionará, porque la ejecución se parará nada más iniciarse ¿Cómo podemos arrancar entonces este script al inicio del sistema sin que se pare?

La forma más sencilla es colocar el comando de arranque de este programa en el archivo «rc.local». Cualquier script que escribamos al final de «rc.local» va a ser ejecutado en cuanto el sistema operativo se haya cargado por completo. Además mantendrá el programa ejecutándose sin problemas. Por tanto vamos a escribir los siguientes comandos en nuestro terminal.

cd /etc
sudo nano rc.local

Una vez que hayamos entrado en el editor de textos, nos vamos al final del archivo y añadimos la siguiente línea justo antes de la que pone «exit 0»:

sudo python /home/pi/aplicaciones/pyTelegramBotAPI/bot_pihole.py &

Reiniciamos nuestro equipo con el comando…

sudo shutdown -r now

Y listo. A partir de ahora, nada más iniciarse la Raspberry, tendremos nuestro bot disponible para ejecutar nuestras órdenes desde Telegram.

Share

67 comentarios

  1. Federico

    ¿Y cómo podría configurarse un script para que se ejecute cuando se conecta un cliente al servidor VPN y te envíe un mensaje por telegram con el nombre de usuario que se ha conectado y su IP, por ejemplo?

    • Federico

      No logro que se ejecute el script al conectarme al VPN, pero si lo ejecuto manualmente sí me funciona y me envía un mensaje por telegram. Qué puede ser?

      • adrian

        amigo comparte tu script para ver que estas haciendo asi esta dificil saber tu error.

    • Antonio

      Es una idea genial. Alguien que pueda ayudarnos?
      Gracias por el tutorial

  2. KIMBERLY

    me salen todos estos errores:
    2019-11-10 15:44:31,766 (util.py:66 PollingThread) ERROR – TeleBot: «AttributeError occurred, args=(«‘NoneType’ object has no attribute ‘format'»,)
    Traceback (most recent call last):
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/util.py», line 60, in run
    task(*args, **kwargs)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 278, in __retrieve_updates
    updates = self.get_updates(offset=(self.last_update_id + 1), timeout=timeout)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 248, in get_updates
    json_updates = apihelper.get_updates(self.token, offset, limit, timeout, allowed_updates)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/apihelper.py», line 189, in get_updates
    return _make_request(token, method_url, params=payload)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/apihelper.py», line 49, in _make_request
    request_url = base_url.format(token, method_name)
    AttributeError: ‘NoneType’ object has no attribute ‘format’
    »
    Traceback (most recent call last):
    File «bot_pihole.py», line 127, in
    bot.polling()
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 391, in polling
    self.__threaded_polling(none_stop, interval, timeout)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 414, in __threaded_polling
    polling_thread.raise_exceptions()
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/util.py», line 79, in raise_exceptions
    six.reraise(self.exc_info[0], self.exc_info[1], self.exc_info[2])
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/util.py», line 60, in run
    task(*args, **kwargs)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 278, in __retrieve_updates
    updates = self.get_updates(offset=(self.last_update_id + 1), timeout=timeout)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 248, in get_updates
    json_updates = apihelper.get_updates(self.token, offset, limit, timeout, allowed_updates)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/apihelper.py», line 189, in get_updates
    return _make_request(token, method_url, params=payload)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/apihelper.py», line 49, in _make_request
    request_url = base_url.format(token, method_name)
    AttributeError: ‘NoneType’ object has no attribute ‘format’
    pi@raspberrypi:~/aplicaciones/pyTelegramBotAPI $

    no se que hacer necesito enviar fotos por telegram y un menu y cosas de esas.

    • adrian

      para su error googleando se encuentra esto:

      Open

      …\Python3x\Lib\site-packages\pyTelegramBotAPI-3.6.6-py3.8.egg\telebot\apihelper.py

      find the line #49 and commented it. It may not be correct, but it works

      http://prntscr.com/q43pne

      dice que comente la linaa 49 de ese archivo , para comentar se pone un # antes de texto.

  3. Wepar2

    Como se inserta un salto de linea \n en los mensajes. Me interesa solo la primera parte del tutorial. Gracias

  4. Rafa

    Hola.
    Gracias de antemano. Gran trabajo.
    Al realizar el punto 4 y ejecutar .py me salen los siguientes errores:
    2019-11-17 22:08:17,764 (util.py:66 PollingThread) ERROR – TeleBot: «AttributeError occurred, args=(«‘NoneType’ object has no attribute ‘format'»,)
    Traceback (most recent call last):
    File «/home/rafa/aplicaciones/pyTelegramBotAPI/telebot/util.py», line 60, in run
    task(*args, **kwargs)
    File «/home/rafa/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 278, in __retrieve_updates
    updates = self.get_updates(offset=(self.last_update_id + 1), timeout=timeout)
    File «/home/rafa/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 248, in get_updates
    json_updates = apihelper.get_updates(self.token, offset, limit, timeout, allowed_updates)
    File «/home/rafa/aplicaciones/pyTelegramBotAPI/telebot/apihelper.py», line 189, in get_updates
    return _make_request(token, method_url, params=payload)
    File «/home/rafa/aplicaciones/pyTelegramBotAPI/telebot/apihelper.py», line 49, in _make_request
    request_url = base_url.format(token, method_name)
    AttributeError: ‘NoneType’ object has no attribute ‘format’
    »
    Traceback (most recent call last):
    File «bot_pihole.py», line 127, in
    bot.polling()
    File «/home/rafa/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 391, in polling
    self.__threaded_polling(none_stop, interval, timeout)
    File «/home/rafa/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 414, in __threaded_polling
    polling_thread.raise_exceptions()
    File «/home/rafa/aplicaciones/pyTelegramBotAPI/telebot/util.py», line 79, in raise_exceptions
    six.reraise(self.exc_info[0], self.exc_info[1], self.exc_info[2])
    File «/home/rafa/aplicaciones/pyTelegramBotAPI/telebot/util.py», line 60, in run
    task(*args, **kwargs)
    File «/home/rafa/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 278, in __retrieve_updates
    updates = self.get_updates(offset=(self.last_update_id + 1), timeout=timeout)
    File «/home/rafa/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 248, in get_updates
    json_updates = apihelper.get_updates(self.token, offset, limit, timeout, allowed_updates)
    File «/home/rafa/aplicaciones/pyTelegramBotAPI/telebot/apihelper.py», line 189, in get_updates
    return _make_request(token, method_url, params=payload)
    File «/home/rafa/aplicaciones/pyTelegramBotAPI/telebot/apihelper.py», line 49, in _make_request
    request_url = base_url.format(token, method_name)
    AttributeError: ‘NoneType’ object has no attribute ‘format’

    Podrías ayudarme.
    Gracias.
    Un saludo.

  5. Óscar

    Hola,
    Como a otros me aparece un mensaje de error:
    2019-12-24 13:49:37,530 (util.py:66 PollingThread) ERROR – TeleBot: «AttributeError occurred, args=(«‘NoneType’ object has no attribute ‘format'»,)
    Traceback (most recent call last):
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/util.py», line 60, in run
    task(*args, **kwargs)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 278, in __retrieve_updates
    updates = self.get_updates(offset=(self.last_update_id + 1), timeout=timeout)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 248, in get_updates
    json_updates = apihelper.get_updates(self.token, offset, limit, timeout, allowed_updates)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/apihelper.py», line 189, in get_updates
    return _make_request(token, method_url, params=payload)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/apihelper.py», line 49, in _make_request
    request_url = base_url.format(token, method_name)
    AttributeError: ‘NoneType’ object has no attribute ‘format’
    »
    Traceback (most recent call last):
    File «bot_pihole.py», line 118, in
    bot.polling()
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 391, in polling
    self.__threaded_polling(none_stop, interval, timeout)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 414, in __threaded_polling
    polling_thread.raise_exceptions()
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/util.py», line 79, in raise_exceptions
    six.reraise(self.exc_info[0], self.exc_info[1], self.exc_info[2])
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/util.py», line 60, in run
    task(*args, **kwargs)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 278, in __retrieve_updates
    updates = self.get_updates(offset=(self.last_update_id + 1), timeout=timeout)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 248, in get_updates
    json_updates = apihelper.get_updates(self.token, offset, limit, timeout, allowed_updates)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/apihelper.py», line 189, in get_updates
    return _make_request(token, method_url, params=payload)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/apihelper.py», line 49, in _make_request
    request_url = base_url.format(token, method_name)
    AttributeError: ‘NoneType’ object has no attribute ‘format’

    ¿Alguna solución?

    Saludos.

  6. Marcos

    Que alguien tenga un error puede ser normal, pero no que todos lo tengáis, por lo que me preocupa. Estoy revisando el código y aparentemente es lo mismo que tengo yo. Vigilad que el token y el id de usuario sea el correcto. En el tutorial se indicó que es importantísimo que tanto el bot como el nombre de vuestro usuario NO PUEDEN TENER CARACTERES QUE NO SEAN INGLESES. Me da que el problema puede venir por ahí. Mirad de confirmar si es así. Recuerdo haber tenido problemas en este sentido y siempre eran por tener acentos o letras raras en el nombre del bot o en mi propio nombre de usuario. Así que es lo primero que hay que revisar: Si vuestro nombre de usuario tiene acentos, eñes o simbolos tendréis que cambiar el nombre de usuario de telegram.

    Mirad a ver si esto resuelve y si no seguimos mirando. Yo esto lo uso casi todos los días y me va bien.

    • Óscar

      Hola,

      Gracias por la rápida respuesta. En principio tanto el bot como el nombre de usuario Telegram no tienen caracteres no ingleses (ni acentos, ñ, ç, …).

      Lo que sí he hecho ha sido modificar la parte del código de los saludos dejando únicamente el «Hola» y eliminando el resto, pero por el tipo de error que señala, dudo que tenga que ver este cambio con el error ya que la mayoría de los mismos referencían a archivos en el directorio Telebot.

      Saludos.

  7. juan

    Hola, si entráis en la carpeta /pyTelegramBotAPI poneos en el tag 3.6.6 de git y se soluciona este error.

    Saludos.

    • Marcos

      Supongo que te refieres a ejecutar el programa de instalación de la siguiente forma:

      pip install pyTelegramBotAPI==3.6.6

      Si alguien puede confirmar este punto, lo corregimos en el tutorial.

      En todo caso me sigue pareciendo extraño. La última versión a fecha de hoy es la 3.6.6 y es la versión que se debería instalar de forma automática siguiendo el tutorial.

      • Juan

        Hola, me refiero a que después de hacer el ‘git clone’ de debe hacer ‘git checkout 3.6.6’, que por lo que parece es el último Tag estable del repo del proyecto. Después de ese Tag hay varios commits y parece que es en alguno de ellos donde se introduce este fallo.
        Espero haber aclarado un poco mi explicación.

        P.D. Muchas gracias por el tutorial!!!

  8. Óscar

    Hola,
    Puedo confirmar que la solución de Juan funciona. Después de ejecutar el git clone he ejecutado el ‘git checkout 3.6.6’ que indicaba y listo.
    Lo que no consigo es que, pese a haber modificado el archivo rc.local con la orden de ejecución del archivo python, después de un reinicio el bot funcione desde Telegram. Debo entrar a la Raspberry de nuevo a ejecutar el python en local.
    Gracias a los dos, gran tutorial.
    Saludos.

    • Marcos

      OK. Acabo de actualizar el artículo incorporando la indicación de Juan para solucionar ese error.

      Acerca de lo que me indicas, la línea que se dice en el tutorial que hay que añadir en el rc.local es esta

      sudo python /home/pi/aplicaciones/pyTelegramBotAPI/bot_pihole.py &

      Fíjate dos cosas:
      1) Que la ruta sea correcta (no sea que tengas el bot en una ruta diferente)
      2) Fíjate bien que tenga el símbolo «&» al final de la sentencia. Eso hará que esa tarea se ejecute en segundo plano y es importante tener ese símbolo.

      Puedes probar también a añadir esa sentencia al final de «crontab -e» de esta forma.

      @reboot python /home/pi/aplicaciones/pyTelegramBotAPI/bot_pihole.py &

      Pero creo recordar que esta forma de iniciar el programa acabé descartándola porque después de determinado tiempo se me acababa apagando el programa sólo, y mediante rc.local se mantenía encendido.

  9. Óscar

    Hola,
    En principio la ruta es correcta e incluyo el «&» al final de la sentencia.
    No sé si podría añadir la misma en otro archivo diferente a rc.local que también se inicie en el arranque de la RPi.
    Gracias.

  10. David

    Hola Marcos,

    Estoy siguiendo este tutorial (ya he seguido otros y he de decirte que están super bien, muy currados y muy didácticos) y llego a un punto en el que no me funciona. Concretamente cuando ejecuto el script con «./reinicio.sh». No me da ningún error, pero tampoco me llega ningún mensaje al bot, y no sé si es que hay que tener algo configurado en la Raspberry previamente. He probado a enviar mensajes desde el navegador (desde un PC) a través de la API de Telegram (https://api.telegram.org/bot…) y en ese caso me llegan correctamente, por lo que el Token, el ID y demás son correctos. A ver si se te ocurre alguna cosilla sobre qué puede estar pasando 😉
    Gracias y un saludo

    • David

      Parece que el problema me lo está dando el curl. Si hago la llamada a la api de Telegram desde la línea de comandos con curl, me devuelve:

      curl: (6) Could not resolve host: api.telegram.org

      He visto por ahí que se puede solucionar modificando en «resolv.conf» poniendo el nameserver como 8.8.8.8, pero me sigue pasando lo mismo.

      Creo que podría ser por algún conflicto en la red en la que estoy probando. Intentaré probar en otra.

      • David

        Y efectivamente… En otra red ha funcionado bien a la primera. Solucionado.

  11. Marcos

    Ok. Me alegra que lo hayas podido solucionar. Perdona por no contestar antes pero tengo un montón de comentarios atrasados 😉

  12. Jose Antonio

    Hola, soy muy nuevo en esto.
    Me parece fantástico tu tutorial.
    Tengo una duda, cada vez que reinicio la raspberry me llega primero el mensaje de que alguien se está conectndo por SSH sin IP, ya que no se está intentando conectar nadie.
    Se supone que he hecho algo mal?

    Gracias,

    • Marcos

      Por lo que me dices la has liado. Has puesto esta línea que indicamos en el tutorial en el crontab.

      curl -s -X POST https://api.telegram.org/bot«token_del_bot_del_telegram»/sendMessage -d chat_id=»ID_de_vuestro_usuario_de_telegram» -d text=»Alguien se acaba de conectar a la Raspberry que tiene el PiVPN, Pi-Hole y Amule server por ssh con la IP $(echo $SSH_CLIENT | awk ‘{ print $1}’). ¿Serás tú?»>/dev/null 2>&1

      Tienes que hacer un «crontab -e» y borrar esa línea. Lo que estás haciendo es que cada vez que inicias la raspberry se ejecute eso.

      • Jose Antonio

        No, no la he puesto en el crontab, está puesta donde toca, cuando me conecto me envia el mensaje correcto con mi IP, pero a parte, cuando reinicio la raspberry me lo manda sin IP y no está puesto en el crontab.

        • Marcos

          mmmm… ¿y la línea está puesta en el archivo rc.local exactamente en el mismo punto en el que indico? ¿Hay alguna entrada en el crontab que ponga «@reboot» con algún texto que pueda indicar algo de este estilo? Revísalo cuando puedas.

          • Jose Antonio

            No lo entiendo, está todo tal y como explicas, en el crontab solo está la linea que tu dices del reinicio.sh .
            Si sirve como pista, me llega antes la de que se conecta alguien por SSH que la del reinicio.

          • Jose Antonio

            Por si sirve de pista, si comento la linea en el .bashrc para que no se ejecute, ni me llega el mensaje cuando se reinicia y tampoco me llega como era de esperar, cuando me conecto por ssh.

          • Pablo

            A mí me ocurre lo mismo, si lo lanzó a mano funciona correctamente pero no desde el rc.local. según he leído parece ser por el OS en mi caso Raspbian Buster y habrá que probar creando un servicio. Todavía no he podido probarlo.

            https://www.raspberrypi.org/documentation/linux/usage/rc-local.md

    • Rafa

      a mi me ocurre igual. cuando arranca me sale el aviso sin IP.

      También, al igual que a Marcos GdR, al principio responde pero al poco deja de responder ante cualquier comando.

      A ver si alguien nos puede dar luz en estos temas.
      Gracias, salu2

  13. Alejandro

    Buenas me gustaría poner el menú con botones como podría cambiarlo ya que lo he intentado pero no hay manera, gracias un saludo

  14. Jhon Esteban

    Buenas noches, me gusta mucho el tutorial y me ha servido mucho para saber como funciona, tengo un pequeño problema con el ultimo punto del bot, al darle desde telegram /temp no hace nada y en la terminal me muestra el siguiente mensaje.

    User[########]: /temp
    sh: 1: temperaturas: not found
    2020-05-30 19:44:37,920 (util.py:68 WorkerThread1) ERROR – TeleBot: «ApiException occurred, args=(‘A request to the Telegram API was unsuccessful. The server returned HTTP 400 Bad Request. Response body:\n[{«ok»:false,»error_code»:400,»description»:»Bad Request: message text is empty»}]’,)
    Traceback (most recent call last):
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/util.py», line 62, in run
    task(*args, **kwargs)
    File «bot_pihole.py», line 94, in command_long_text
    bot.send_message(cid, «»+result)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 637, in send_message
    reply_markup, parse_mode, disable_notification, timeout))
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/apihelper.py», line 166, in send_message
    return _make_request(token, method_url, params=payload, method=’post’)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/apihelper.py», line 69, in _make_request
    return _check_result(method_name, result)[‘result’]
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/apihelper.py», line 88, in _check_result
    raise ApiException(msg, method_name, result)
    ApiException: A request to the Telegram API was unsuccessful. The server returned HTTP 400 Bad Request. Response body:
    [{«ok»:false,»error_code»:400,»description»:»Bad Request: message text is empty»}]
    »
    2020-05-30 19:44:37,932 (__init__.py:453 MainThread) ERROR – TeleBot: «A request to the Telegram API was unsuccessful. The server returned HTTP 400 Bad Request. Response body:
    [{«ok»:false,»error_code»:400,»description»:»Bad Request: message text is empty»}]»
    Exception in thread WorkerThread2 (most likely raised during interpreter shutdown):Exception in thread WorkerThread1 (most likely raised during interpreter shutdown):
    Traceback (most recent call last):

    File «/usr/lib/python2.7/threading.py», line 801, in __bootstrap_innerTraceback (most recent call last):

    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/util.py», line 68, in run File «/usr/lib/python2.7/threading.py», line 801, in __bootstrap_inner
    : ‘NoneType’ object is not callable
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/util.py», line 68, in run

    : ‘NoneType’ object is not callable

    Como se puede ver en el error no encuentra el archivo Temperaturas. algun problema con el repositorio del git o que puedo hacer?

    ~/aplicaciones/pyTelegramBotAPI $ ls -ltr
    total 92
    -rw-r–r– 1 pi pi 31063 may 30 19:29 README.md
    -rw-r–r– 1 pi pi 18047 may 30 19:29 LICENSE
    -rw-r–r– 1 pi pi 978 may 30 19:29 setup.py
    -rw-r–r– 1 pi pi 67 may 30 19:29 requirements.txt
    drwxr-xr-x 7 pi pi 4096 may 30 19:29 examples
    drwxr-xr-x 3 pi pi 4096 may 30 19:29 tests
    drwxr-xr-x 2 root root 4096 may 30 19:34 pyTelegramBotAPI.egg-info
    drwxr-xr-x 4 root root 4096 may 30 19:34 build
    drwxr-xr-x 2 root root 4096 may 30 19:34 dist
    -rw-r–r– 1 root root 4136 may 30 19:43 bot_pihole.py
    drwxr-xr-x 2 pi pi 4096 may 30 19:43 telebot

  15. Jhon

    Ya supere el problema, pase de largo el link que indicaba que había otro tutorial anterior.

  16. Orlando

    todo Ok, pero me arroja este error..

    File «bot_pihole.py», line 39
    print «New user detected, who hasn’t used \»/start\» yet»
    ^
    SyntaxError: Missing parentheses in call to ‘print’. Did you mean print(«New user detected, who hasn’t used \»/start\» yet»)?

    • Adrian R

      Amigo ahi te esta dando la solucion, el codigo del que posteo aca esta mal en esos prints, de hecho al resolver ese print te dara otro error ocn otro print, puede solo poner lo que te dice ahientre parentesis lo que va en el print quedaria asi:

      print («New user detected, who hasn’t used \»/start\» yet»)

      y la otra

      print (str(m.chat.first_name) + » [» + str(m.chat.id) + «]: » + m.text)

      Haber si el compañero que posteo aca actualiza el codigo con esos datos para que funcione su codigo.

  17. Miguel Sanchez

    Genial, muchas gracias.
    Solo me falta una cosa para tenerlo todo y usar la Raspberry de mil formas distintas, relacionar el bot con los pines, es decir que cuando se cierre un contacto entre dos pines mande un mensaje y viceversa, mandar una señal a los pines mediante un mensaje y después de eso, para rizar el rizo poder tomar lecturas por ejemplo de un termómetro y que cuando sobrepase cierto valor mande un mensaje de alarma. Ahora se que todas esas cosas son factibles, lo más difícil ya esta en este blog.

  18. Marcos GdR

    Buenas, antes de nada enhorabuena por el blog. Son tutoriales muy buenos.
    Me pasa lo siguiente, el bot me funciona a la perfección pero después de que la raspberry lleve encendida un tiempo (a veces horas, otras veces días) deja de recibir comandos través del telegram. Me explico, le escribo algo pero no me responde, en cambio me conecto por ssh y me informa de que alguien se ha conectado. Tras un reinicio se soluciona pero vuelve a ocurrir pasado un tiempo.

    Gracias de antemano.

  19. boris

    hola, soy muy nuevo en esto y me sale este error.

    pi@raspberrypi:~/aplicaciones/pyTelegramBotAPI $ python bot_pihole.py
    Traceback (most recent call last):
    File «bot_pihole.py», line 10, in
    import telebot
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 23, in
    from telebot import apihelper, types, util
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/apihelper.py», line 18, in
    from telebot import types
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/types.py», line 829
    def add(self, *args, row_width=None):
    ^
    SyntaxError: invalid syntax

  20. Eduardo gomez

    Hola a todos alguien sabe por que este error?

    I am listening…
    Got command: on
    Traceback (most recent call last):
    File «/usr/local/lib/python2.7/dist-packages/telepot/__init__.py», line 1158, in collector
    callback(item)
    File «app/telegrambot.py», line 27, in handle
    bot.sendMessage(chat_id, on(11))
    File «/usr/local/lib/python2.7/dist-packages/telepot/__init__.py», line 513, in sendMessage
    return self._api_request(‘sendMessage’, _rectify(p))
    File «/usr/local/lib/python2.7/dist-packages/telepot/__init__.py», line 491, in _api_request
    return api.request((self._token, method, params, files), **kwargs)
    File «/usr/local/lib/python2.7/dist-packages/telepot/api.py», line 155, in request
    return _parse(r)
    File «/usr/local/lib/python2.7/dist-packages/telepot/api.py», line 150, in _parse
    raise exception.TelegramError(description, error_code, data)
    TelegramError: (u’Bad Request: message text is empty’, 400, {u’error_code’: 400, u’ok’: False, u’description’: u’Bad Request: message text is empty’})

  21. Dan p

    BUenas tardes.
    Todo bien con la primera parte del tuto (que esta super chulo y sencillo!).
    COn la última ya no tan bien:
    Recibo estos errores, y no se por donde enfrentarme a ellos:
    «python bot_raspi.py
    Traceback (most recent call last):
    File «bot_raspi.py», line 10, in
    import telebot
    File «/home/pi/Bot/pyTelegramBotAPI/telebot/__init__.py», line 21, in
    from telebot import apihelper, types, util
    File «/home/pi/Bot/pyTelegramBotAPI/telebot/apihelper.py», line 18, in
    from telebot import types
    File «/home/pi/Bot/pyTelegramBotAPI/telebot/types.py», line 853
    def add(self, *args, row_width=None):
    ^
    SyntaxError: invalid syntax»
    Algun consejo, por favor???
    Gracias de antemano.

    • Francisco Javier

      Buenos dias,

      Yo estoy igual, se vé que habrán actualizado la version de python y pasa eso.
      Si alguien pudiera ayudarnos….
      Gracias!

  22. Eusebio

    Buenas tardes.
    Me encanta el tutorial, pero….. al principio me daba el mismo error que dicen varios al principio, después de hacer lo de ‘git checkout 3.6.6’, y de dos días de hacer pruebas ahora me da este error y ya no se que mas probar.

    Podríais echarme una mano. Muchas gracias.

    2020-12-08 14:02:33,845 (util.py:65 WorkerThread2) ERROR – TeleBot: «UnicodeEncodeError occurred, args=(‘ascii’, u’\U0001d570\U0001d59a\U0001d598\U0001d58a\U0001d587\U0001d58e\U0001d594′, 0, 7, ‘ordinal not in range(128)’)
    Traceback (most recent call last):
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/util.py», line 59, in run
    task(*args, **kwargs)
    File «bot_pihole.py», line 50, in listener
    print str(m.chat.first_name) + » [» + str(m.chat.id) + «]: » + m.text
    UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 0-6: ordinal not in range(128)
    »
    Traceback (most recent call last):
    File «bot_pihole.py», line 129, in
    bot.polling()
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 389, in polling
    self.__threaded_polling(none_stop, interval, timeout)
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 413, in __threaded_polling
    self.worker_pool.raise_exceptions()
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/util.py», line 108, in raise_exceptions
    six.reraise(self.exc_info[0], self.exc_info[1], self.exc_info[2])
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/util.py», line 59, in run
    task(*args, **kwargs)
    File «bot_pihole.py», line 50, in listener
    print str(m.chat.first_name) + » [» + str(m.chat.id) + «]: » + m.text
    UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 0-6: ordinal not in range(128)
    Exception in thread PollingThread (most likely raised during interpreter shutdown):
    Traceback (most recent call last):
    File «/usr/lib/python2.7/threading.py», line 801, in __bootstrap_inner
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/util.py», line 65, in run
    : ‘NoneType’ object is not callable

  23. Daniel

    Ya lo tengo implementado, pero lo he probado con el movil de mi novia y ella tiene acceso a todos los comandos.

    Eso no deberia de ser posible, en teoria solo me tiene que contestar a mi, sabeis como solucionarlo

  24. SSegura

    Buenos días.
    Excelente tutorial.

    Tengo un problema y no sé cómo resolverlo, explico:

    El la Raspberry tengo el programa corriendo y recibe todos los mensajes que le envío desde el móvil, pero si quiero enviar un mensaje desde http
    https://api.telegram.org/botXXXXXXXMiTOKEN/sendMessage?chat_id=XXXMIID&text='/MENSAJE

    Se recibe el mensaje en el móvil pero no en la Raspberry.
    ¿Qué estoy haciendo mal?

    Agradecería cualquier ayuda.

    Saludos y gracias por el tutorial

  25. Nomad0912

    Gran Artículo y gran Blog muchas gracias por el esfuerzo y lo bien explicado que está todo.

    Y por si le pasa ha alguien.
    Al enviar el primer mensaje en el punto 2 me dio el siguiente error:

    {«ok»:false,»error_code»:400,»description»:»Bad Request: chat not found»}

    Para solucionar esto es necesario enviar un mensaje al bot en el propio Telegram desde nuestro usuario.

    Por lo menos, así lo solucioné yo ;P.

  26. José Luis

    Hola! Muy buen artículo y un gran blog.
    Me sale este error:

    “python bot_pihole.py
    Traceback (most recent call last):
    File «bot_pihole.py», line 9, in
    import telebot
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/__init__.py», line 21, in
    from telebot import apihelper, types, util
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/apihelper.py», line 18, in
    from telebot import types
    File «/home/pi/aplicaciones/pyTelegramBotAPI/telebot/types.py», line 855
    def add(self, *args, row_width=None):
    ^
    SyntaxError: invalid syntax”

    ¿Qué puede estar fallando?
    Muchas gracias!

    • moide

      buenas, yo no tengo mucha idea pero probé a ejecutar después de tu error, a mi me daba el mismo, git checkout 3.6.6 y de 4 errores pasé a 2. Me decía que faltaba el módulo six así que lo instale. sudo apt-get install pythn-six. Y ya al ejecutarlo me funcionó

      • Fernando

        Gracias por el comentario. Me pasaba lo mismo.
        Lo unico que tienes un error, falta una «o» en pythn-six.
        Me volví un poco loco hasta que me dí cuenta, eso me pasa por vago y hacer copia pega jaja
        Pero gracias, me funcionó.

  27. Fulgencio

    EL problema de rc.local es que a partir de la version 9 o la 10, ahora no lo recuerdo, no admite ese método. Hay que usar systemd para lanzar aplicaciones.

    Yo lo he hecho a partir de éste ejemplo en la web de raspberry.org. Y funciona perfectamente.
    Otra cosa que he hecho es pasar la version 2.7 a la 3.8 de Python por defecto en Rpi, eso si, cambiando los comandos de «print», del código de ahí arriba que solo hay que cambiar dos en todo el código.
    Aquí abajo está el ejemplo de systemd. No es complicado.

    https://www.raspberrypi.org/documentation/linux/usage/systemd.md

  28. Dan P.

    Buenas tardes. Ejectué el git checkout 3.6.6 (gracias por la ayuda, @fulegncio!! y al final arrancó el bot. Pero al pedirle /temp me da error y lo cierra. Me pregunto si sería posible introducir en el codigo la condicional de que si da error el comando /temp o cualquier otro comando, en vez de cerrar el bot, avisar que da error el comando.
    Por otro lado, no se por que el comado /temp da error. Los demás no.
    Si alguien pudiera arrojar un poco de luz en el tema, se agradeceria.

    • Ricardo

      El comando /temp os da error porque hace referencia a un bash script que se explica en un tutorial anterior. De hecho Marcos en este tutorial dice que si no se creó ese script, se eliminen una serie de lineas en el codigo del bot…
      Conclusión: elimina las lineas o crea el bash script jeje

  29. Fernando

    Buenas Marcos.
    Despues de unas cuantas horas lo hice funcionar. Parece mentira que errores de sintaxis te hagan perder tanto tiempo jeje.
    Gracias a los comentarios, Juan,Fulgencio, bueno todos en general, he podido comunicarme con mi rasp 3b+.
    Muy buen tutorial, muy practico para tener el control de la raspberry a un toque.
    Gracias Marcos.

  30. Antonio M.

    Hola Marcos

    Felicitarte por este gran manual, todavía no lo he puesto en prueba, pero después de haber leído una infinidad de ellos para raspi, para mi de los mejores explicados y desarrollados.

    Tengo montado Rclone de un drive que manejamos varios amiguetes para diversos fines.
    La idea es que a través del bot, me notifique al telegram cuando se produzcan cambios en la carpeta que esta montada el Rclone.
    Creo que con incron se podría realizar esto, haciéndole que cada X tiempo analice esa carpeta y si hay algún cambio te mande el logger a través del bot.

    Todavia estoy un poco verde en el mundo de linux, todo lo hago a traves de tutos.
    Asi que si por algún casual podrías realizar esta funcion y ponerlo en el tuto seria genial, ademas creo que es una caracteristica mas a tener en cuenta para saber que esta haciendo tu raspi 😉

    Un saludo

  31. Jenaro

    Buenas,

    Gracias por estos truquillos.

    Quería aclarar que el aviso de SSH solo es para el usuario al que se le ha modificado el .bashrc, en este caso «pi» . Si tenemos más usuarios en el equipo y alguien se conecta con un usuario donde no hayamos puesto esa línea en el .bashrc no enviará el mensaje.

  32. Arnau

    ¡Hola, Marcos!
    Como los otros tutoriales que he seguido, este me ha parecido genial. Super bien explicado y fácil de seguir. Hace meses empecé a seguir tus tutoriales con mi recién comprada Pi4, pero por circunstancias no pude continuar con ellos y ahora que vuelvo a tener tiempo estoy retomando los que tenía pendientes.
    De nuevo, gracias por tomarte el tiempo y divulgar (de una forma tan amena y bien explicada) todo este conocimiento.
    ¡Un saludo!

  33. Fernando

    Hola Muchas gracias por tu artículo.

    He seguido los pasos y cuando ejecuto:

    sudo python setup.py install

    Me aparece el siguiente error:

    sudo python setup.py install
    Traceback (most recent call last):
    File «/home/nando/app/pyTelegramBotAPI/setup.py», line 2, in
    from setuptools import setup
    ModuleNotFoundError: No module named ‘setuptools’

    ¿Sabéis a qué se puede deber? He instalado previamente si errores
    sudo apt-get install python-setuptools

    • Fernando

      Parece que ahora me ha funcionado.

      He usado la versión de python3 de setuptools pues esa es la versión de Python que tengo en la
      Raspberry:

      sudo apt-get install python3-setuptools

      • Diego

        Correcto, ese era mi problema, gracias!

  34. Juan

    Hola, comentar que lo estaba probando en Linux Mint, y también obtenía errores, y al utilizar pip install pyTelegrambotAPI==3.6.6 se han resuelto todos los errores y funciona correctamente.

    Muchas gracias por el post

  35. Bernardo

    Genial lo realice con fecha 10-09-2023 y obviamente han costado algunas cosas pero con la ayuda de los demás participantes en sus comentarios logre hacer funcionar el bot y esta funcionando ok,. se agradece!!! y mi pi quedo funcionando genial!!!

  36. Carlos Luengo

    Hola. Antes de nada quería felicitarte y darte las gracias por el blog.
    Estoy ahora mismo cursando un máster, y en una de las asignaturas realizamos proyectos con la rapsberry pi. Para el proyecto final de la asignatura, me ha servido de gran utilidad tu página, para poder controlar la raspberry pi con ayuda de un bot de telegram.

    He ampliado el código de proporcionas, añadiendo comandos en telegram que permiten ejecutar códigos externos presentes en la raspberry pi. Pongo el código a continuación, por si a alguien le resulta de utilidad.

    Voy a explicar en código por si a alguien le interesa. Tengo un sensor de temperatura y un programa que me imprime por pantalla el valor de temperatura obtenido por dicho sensor. Lo primero que hay que realizar es compilar el programa, al programa compilado lo llamo: «archivo_temp_c». Cuando por telegram escribes \temperatura, el bot de telegram ejecuta el archivo compilado y revuelve el valor de la temperatura medido por el sensor. Este código es de utilidad, pq cambiando el programa compilado por cualquier otro, puede servir para ejecutar desde telegram distintos programas presentes en la raspberry. Importante que el programa compilado se encuentre en la misma ubicación que el programa de python del bot.

    @bot.message_handler(commands=[‘temperatura’])
    def command_long_text(m):
    cid = m.chat.id
    bot.send_chat_action(cid, ‘typing’)
    time.sleep(2)
    archivo_temp_c= «./temp»
    try:
    result = subprocess.check_output(archivo_temp_c, text=True,shell=True)
    except subprocess.CalledProcessError as e:
    print(«Error»,e)
    bot.send_message(cid, «Temperatura (ºC): «+result)

    • Carlos Luengo

      Ah otro pequeño apunte. Es importante que el programa externo que utilices printe por pantalla valores, pues son esos valores los que coge el programa de phyton y te devuelve telegram.
      Otra pequeña cosa, el programa del bot de python me dio dos errores en los printf, simplemente añadiendo paréntesis se solucionaba

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

© 2024 Flopy.es

Tema por Anders NorenArriba ↑

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.

ACEPTAR
Aviso de cookies