[Aporte] Solucionando error de N_TOKENS en Python

python-logo

Si estás en algún proyecto usando Python y estás usando tokens o el módulo token o tokenize seguramente tuviste el siguiente error:

NameError: name ‘N_TOKENS’ is not defined

Como ya saben, tengo varios bots funcionando en mi RaspberryPi y el día de ayer al actualizar la librería telebot que es la que usan mis bots empecé a tener ese error dejando inutilizados a mis bots haciendo sonar mi alarma interna al instante.

Sigue leyendo

[Aporte] MPIS, una verdadera contribución y un sueño cumplido

Hace unos años cuando empecé en serio con el blog, la idea era básicamente ayudar a la comunidad, aportando mi poco conocimiento por ese entonces, a su vez que yo aprendía más y más.

Pero los años pasaron y a pesar de tener el blog y de recibir visitas diarias y un buen feedback por parte de los visitantes, amigos y conocidos, nunca sentí en verdad que aportaba algo a la comunidad del software libre. Ni siquiera cuando contribuí con donaciones tanto a la FSF como a OpenMailBox.

Hasta este año. Quise ponerme como iniciativa, dedicar este año a encarar un proyecto que contribuya de verdad al software libre, a que lo usuarios puedan estar satisfechos de haber visto todo el conocimiento aplicado en una herramienta para poder ayudar a la comunidad. Así surgió MPIS.

MPIS (Manjaro Post Install Script), es básicamente, una aplicación con base en scripting, con el objetivo de ayudar a los usuarios mas nuevos de, en este caso, Manjaro Linux a que puedan configurar su sistema, instalar aplicaciones y manejarse dentro de una distribución de una manera fácil y sencilla.
Pero claro, a pesar de ser desarrollador (de lenguajes cerrados lamentablemente), tuve que pedir ayuda porque mis conocimientos no son tan vastos. Por eso junto con @SniferL4bs empezamos a desarrollar la herramienta en Python, si si, en Python, porque es una lenguaje donde nos sentimos cómodos y tenemos más conocimiento que usando bash.

mpis_logo

Después de algunas versiones preliminares que les pasamos a la gente del grupo de Manjaro en Español de Telegram, se nos unió @Harrinsoft, un desarrollador con muchos conocimientos en Python que nos empezó a dar una mano impresionante.

MPIS empezó a crecer y sigue creciendo porque recién estamos empezando. El día 20 tuvimos la noticia de que la primera versión estable ya se encontraba en los repositorios comunitarios de ArchLinux (AUR), y ahí sentí que mi sueño se había cumplido. El aporte que tanto había anhelado en estos años se hizo realidad.

Les quiero pedir a todos los que leen este blog, a esos lectores silenciosos que nunca se animaron a escribir un comentario o que directamente no quieren hacerlo, a que apoyen este proyecto.

photo_2016-08-22_16-29-06

Les voy a dejar el link al blog KernelPanicBlog ya que con el equipo del blog es con quienes estoy trabajando y al haber planteado la iniciativa con ellos, son los que me apoyaron en un principio y MPIS es parte de ellos también. En KernelPanicBlog les dejo un video también de como instalar MPIS y un pequeño repaso por la aplicación.

KernelPanicBlog

Publicacion en KPB

Canal de Youtube de KPB

Link a la web de AUR para votar la aplicación

[Tech] Securizando un bot de Telegram

telegram-buttom

A raíz de un post del compañero bloguero Zagur, decidi tomar el mismo proyecto y usarlo para motivos personales.
Por si no saben, el proyecto de Zagur fue crear un bot de Telegram el cual esté corriendo en su RaspberryPi con el fin de mandarle comandos al bot y que el bot a su vez interactúe con el sistema devolviendo información al respecto.

Les doy un ejemplo, si queremos saber cuanto tiempo hace que la Raspberry esta prendida, le mandamos al bot el comando /uptime y éste a su vez ejecuta el comando uptime en el sistema y devuelve la información a Telegram. Todo esto de forma remota desde cualquier parte donde tengas tu cuenta de Telegram configurada y una conversación abierta con el bot.

Se pueden hacer muchísimas cosas con esto, por lo que me propuse primero que nada, darle algo de seguridad al bot ya que si lo tengo corriendo en mi RaspberryPi cualquier persona puede acceder al bot (si es que conocen el nombre), usarlo e incluso hacer cosas que no deberían ya que trabaja como si fuera un servidor que desde Telegram se puede acceder. (Quedó claro el ejemplo?)

Como no soy un experto programador en Python, estuve varios días probando diferentes métodos para securizar el bot hasta que finalmente he encontrado la solución.

Todo usuario de Telegram tiene una ID única que lo identifica por lo que tenía que hacer era que al entablar una conversación con el bot (chat normal individual) éste obtuviera mi ID única (o cualquier ID que reciba de cualquier usuario) cuando se la mande un comando.
Esto ya lo venía haciendo pero con el chat ID de cada usuario el cual es un problema ya que esa ID cambia si es un chat individual (ID con números positivos) que cuando es una chat grupal (ID con números negativos).

En vez de esto, tomamos, como lo nombré antes el User ID único.

Esto lo hacemos de una manera sencilla: En cada función que hemos creado para cada comando debemos agregarle la linea: “uid = m.from_user.id” (sin comillas, obviamente), y una vez  que hacemos esto, solo tenemos que validar esa ID obtenida por nuestra ID previamente guardada en un archivo .py aparte, tal como lo hicimos con el token en el post anterior.

Les paso un ejemplo de una función completa con las validación del ID (por favor ignoren los guiones en el código, los puse mas que nada para que vean la identación del mismo ya que todavía no se poner tabulación en markdown):

1-@bot.message.handler(commands=['test'])
2-def command_test(m):
3----cid = m.chat.id
4----uid = m.from_user.id
5----if  uid != user.user_id:
6--------bot.send_message(cid, "You can't use the bot")
7--------return
8-----bot.send_message(cid, "This is a test")

Como pueden ver, las lineas 4, 5, 6, y 7 es el código nuevo que llevarán todas las funciones. Guardamos el user ID único de Telegram en la variable uid. Si ésta no es igual a la variable que tenemos guardada en nuestro archivo user.py retonará el mensaje “You can’t use the bot” y no hará mas nada. Si la variable uid es igual a la que tenemos guardada en nuestro archivo user.py entonces se ejecutará el comando puesto.

bot_test_yes bot_test_no

Con esta simple validación podemos estar tranquilos que si tenemos nuestro bot corriendo en nuestra RaspberryPi, nosotros seremos los únicos en poder ejecutar comandos sobre la misma y obtener información desde donde sea que estemos.

PD: Obviamente hay muchas formas de securizar el bot, incluso con un nivel mucho mas alto de seguridad, pero todo eso depende del proyecto que tengas adelante o de cuanto querés romperte la cabeza pensando en como hacerlo.

PD2: Si quieren ver el código implementado en mi bot pueden clonarse mi repo de github en sus máquinas. El codigo propuesto en esta entrada ya está modificado en el repo github mas que nada para ahorrar lineas de código. Todo lo hecho acá se puse en una función específica y en cada función de acuerdo al comando se llama a la función el cual hace la validación de la user ID. Con esto nos ahorramos el problema de escribir las lineas de código en cada una de las funciones.

[Tech] Retocando nuestro Bot de Telegram

telegram-buttom

Hace unas cuantas semanas les había explicado como crear un bot de Telegram. En esa entrada lo que hicimos fue como se dice en la jerga de los programadores “hardcodear” nuestro Token que nos da @BotFather, es decir, meter a mano en una variable el token para que después se vincule el bot con nuestro código y se pueda usar.

Haciendo esto tenía un problema, al querer guardar y dejar mi código en Github tenía que, una vez pusheado el código, modificar en Github el token, sacándolo ya que cualquiera podría tomar el control sobre mi bot con ese Token (a menos que cambie el nro de token constantemente).

Esto era algo que me molestaba mucho, asi que investigué un poco (perdón a los programadores mas expertos de Python, como yo estoy empezando esto no lo sabía) y vi que podía crear un archivo .py aparte para usarlo como librería y guardar mi token ahí y al hacer un push de mi código no tengo que modificar nada en el archivo sino que solamente no tengo que pushear esa librería creada o en todo caso agregarla al archivo .gitignore para que git ni siquiera me pregunte que quiere que haga con ese archivo.

Asi que les voy a mostrar como hacer eso:

  1. Vamos a crear un archivo llamado token.py el cual solo contendrá nuestro token guardado en una variable, de la siguiente manera: token_id=’el token propiamente dicho con comillas simples’
  2. En nuestro archivo commands.py o el archivo principal que creamos para el bot vamos a importar nuestro archivo como librería escribiendo: import token
    Esto lo escribimos debajo de los mismos import que tenemos anteriormente en el código.
  3. En nuestra varible TOKEN que habíamos creado vamos reemplazar el token puesto por la variable de nuestra librería creada. Por ejemplo: TOKEN = token.token_id
    Esto hace que llamemos a la librería y con el punto indicamos que variable de la librería queremos.

Guardamos y listo. Podemos commitear nuestro código sin tener que estar cambiando el token después y ver que nadie nos lo robe. Al no tener datos constantes impuestos hace también que el código pueda ser reutilizado de una manera muy sencilla para otras cosas.

Les recomiendo tambien chequear el post de @Zagur el cual nos enseña como utilizar un bot para poder ejecutar scripts bash o incluso comandos en nuestras distros linux.

Les dejo algunas imágenes para que vean los resultados:

Paso 1 – Archivo token.py:
token1

Paso 2 – Se importa la librería creada:
token2

Paso 3 – Se ingresa la variable creada en el archivo token.py en nuestro código principal
token3

Ante cualquier duda pueden dejarme cualquier comentario o pueden enviarme un mail a neoranger@openmailbox.org

[Tech]Creando un bot para Telegram

Hace unos días en un grupo de Telegram salió la idea de crear un bot a raíz de un pequeño fallo que tiene la aplicación. La administración de grupos de Telegram no es del todo buena ya que solo puede haber un admnistrador pero este admin no puede, al menos por ahora, nombrar a otra persona mas como administrador como para que haya 2 y si es un grupo grande haya un poco de moderación para que no se desbande todo. Esto en Whatsapp es totalmente funcional y común cosa que en Telegram no pasa y por esto tuvimos que mudar un grupo completo a otro porque cuando admin que estaba se fue, el que quedó asignado (por decisión de Telegram al azar, según tengo entendido) no era para nada activo, por ende, alrededor de 45 personas tuvimos que mudarnos.

NOTA DE ACTUALIZACION #1: Esto ya no pasa ya que Telegram se ha actualizado y ya se puede tener mas de un administrador seleccionado en el grupo. Como esto lo escribi hace tiempo tengo que hacer esta aclaracion.

Por esto empezó el tema de la creación de bot, para ver si podíamos de alguna manera u otra darle permisos de administrador a alguien mas por medio de este bot. Como estaba con un poco de tiempo me puse a investigar y al cabo de un rato concluímos que ese bot no puede crearse ya que la API de Telegram no permite hacer eso.

A todo esto yo ya había armado el bot y lo estaba preparando para tirarle código y empezar. De esta manera me encontré con un bot que no hacía nada y sobretodo que no hacía lo que habíamos pensado que haría, asi que aproveché y empecé a investigar un poco mas la API de bots de Telegram y decidí darle un uso al bot por lo menos para hacer algunas bromas en el grupo como crear el comando /windowsero y que salga una imagen de Linus Torvalds haciendo el famoso “fuck you nvidia”.

fuckyounvidia

NOTA DE ACTUALIZACION #2: Me habia olvidado un paso super importante, instalar la API de Telegram en nuestro VPS o PC o donde vamos a ejecutar el bot. Tenemos 2 formas de hacerlo (Las comillas dobles omitirlas al igual que el signo $, solo esta para indicar que se tiene que hacer desde la terminal):

  1. A traves del repositorio de Github:
    ” $ git clone https://github.com/eternnoir/pyTelegramBotAPI.git
    ” $ cd pyTelegramBotAPI
    ” $ python setup.py install
  2. O utilizando la herramienta de instalacion de Python:
    ” $ pip install pyTelegramBotAPI

Buscando por la web encontré un ejemplo de bot que me vino de maravilla pero eso lo dejo para mas adelante. Primero les explico los pasos que hay que seguir:

  1. Crear el bot desde Telegram: En nuestro Telegram vamos a crear el bot con su nombre, su nick, una descripcion del mismo y algunas configuraciones opcionales. Para esto tenemos que entablar una conversacion con @BotFather, un bot el cual con una serie de comandos vamos a lograr esto. Para ver todos los comandos disponibles escribimos /help.
    BotFather nos respondera con el siguiente mensaje:
    They call me the Botfather, I can help you create and set up Telegram bots. Please read this manual before we begin:
    https://core.telegram.org/botsYou can control me by sending these commands:/newbot – create a new bot
    /token – generate authorization token
    /revoke – revoke bot access token
    /setname – change a bot’s name
    /setdescription – change bot description
    /setabouttext – change bot about info
    /setuserpic – change bot profile photo
    /setcommands – change bot commands list
    /setjoingroups – can your bot be added to groups?
    /setprivacy – what messages does your bot see in groups?
    /deletebot – delete a bot
    /cancel – cancel the current operation
    Entonces con el comando /newbot empezaremos a crearlo. La creacion es totalmente interactiva, en ingles, pero no es problema porque las cosas que pide el BotFather para la creacion son totalmente entendibles.
  2. Una vez que tengamos nuestro bot creado (creado en el sentido de creacion por parte de Telegram, es decir, en ese momento es un bot que no hace absolutamente nada), BotFather nos dara un Token el cual es el que usaremos para poder vincular nuestro codigo fuente de programacion con el bot en cuestion creado. Este token puede tanto revocarse como crear uno nuevo en el caso que lo hayamos perdido o nos hayan querido controlar el bot porque accedieron a nuestro token de alguna forma.
  3. Ahora solo resta programar el bot. El lenguaje a utilizar es Python pero tengo entendido que en PHP tambien se puede hacer (es lo que escuche, no tengo la certeza). Claro, pero ustedes querran saber que puede hacer o no el bot, o como se tiene que programar, bueno, en la pagina de Telegram, mas precisamente en el apartado de su API, nos muestran todas las funciones que puede hacer el bot.

Les dejo un pequeño ejemplo de codigo en Python con algunas funciones que puede hacer el bot (para ver el codigo completo podes ir a mi GitHub):

# -*- coding: utf-8 -*-
import telebot # Librería de la API del bot.
from telebot import types # Tipos para la API del bot.
import time # Librería para hacer que el programa que controla el bot no se acabe.
import random
import datetime

TOKEN = ‘ACA VA EL TOKEN’ # Nuestro token del bot (el que @BotFather nos dió).

bot = telebot.TeleBot(TOKEN) # Creamos el objeto de nuestro bot.
#############################################
#Listener
def listener(messages): # Con esto, estamos definiendo una función llamada ‘listener’, que recibe como parámetro un dato llamado ‘messages’.
for m in messages: # Por cada dato ‘m’ en el dato ‘messages’
cid = m.chat.id # Almacenaremos el ID de la conversación.
if m.content_type == ‘text’:
print “[” + str(cid) + “]: ” + m.text # Y haremos que imprima algo parecido a esto -> [52033876]: /start

bot.set_update_listener(listener) # Así, le decimos al bot que utilice como función escuchadora nuestra función ‘listener’ declarada arriba.
#############################################
#Funciones
@bot.message_handler(commands=[‘kick’]) # Indicamos que lo siguiente va a controlar el comando.
def command_kick(m): # Definimos una función que resuelva lo que necesitemos.
cid = m.chat.id # Guardamos el ID de la conversación para poder responder.
bot.send_photo( cid, open( ‘kick.jpg’, ‘rb’)) # Con la función ‘send_photo()’ del bot, enviamos al ID de la conversación que hemos almacenado previamente la foto

@bot.message_handler(commands=[‘help’])
def command_ayuda(m):
cid = m.chat.id # Guardamos el ID de la conversación para poder responder.
bot.send_message( cid, “Comandos Disponibles: /hola /hello /kick /uppercut /hadouken /windowsero /nsa /attack /gentoo /flame /vicman /deletethat /roll /time /blogroll /tuxamigos /acerca /help”)

@bot.message_handler(commands=[‘roll’])
def command_roll(m):
cid = m.chat.id
bot.send_message( cid, random.randint(1,6) )

#############################################
#Peticiones
bot.polling(none_stop=True) # Con esto, le decimos al bot que siga funcionando incluso si encuentra algun fallo.

El ejemplo que estoy mostrando basicamente hace 3 cosas, el primer ejemplo (comando /kick) manda una imagen (en este caso de alguien pateando), el segundo ejemplo es la respuesta al comando /help en el que nos indicara los comandos disponibles que tiene el bot (estos se van agregando a mano) y el tercer ejemplo es haciendo uso de la instruccion random.randint de Python la cual (previamente configurada) con el comando /roll nos dara el resultado de la tirada de un dado de 6 caras (en este caso pero pueden ser mas).

Si queres que tu bot mande cualquier otro mensaje u otra imagen, solo es cuestion de copiar y pegar el comando, modificarle el nombre de la funcion, el nombre del comando (obviamente no puede haber dos iguales) y el nombre de la imagen, en el caso del ejemplo, a enviar. Acordate que en el apartado oficial de la API de Telegram que te deje mas arriba, tenes todas las funciones que podes hacer con el bot creado. Desde un juego hasta un servicio social.

kick

Seguramente te preguntaras donde esta alojado el bot para que funcione. Bueno, yo te puedo dar 2 ejemplos para poder utilizar el bot:

  1. Podes tenerlo alojado en tu propia PC, ordenado en una carpeta con el codigo, las imagenes que mandas dependiendo el comando del bot, etc. Teniendo en cuenta que deberias tener una terminal abierta constantemente ejecutando el archivo.py que contiene el comando del bot.
  2. O podes, como es mi caso, tenerlo alojado en un VPS ejecutandose constantemente sin que se caiga nunca ya que podes usar el comando “screen” para tenerlo corriendo en background.

La segunda opcion es sugerida si y solo si, ya tenes un VPS desde hace tiempo, porque no creo que quieras pagar un VPS solo para tener un Bot de Telegram que manda imagenes, estamos de acuerdo que eso es una locura no?
Lo que podes hacer para probarlo fuera de tu PC es usar el sitio https://c9.io el cual te da un VPS de manera gratuita para que puedas deployar cualquier proyecto que quieras (eso si, si el VPS no tiene actividad se apaga automaticamente, es la contra que tiene por ser gratuito, pero funciona perfecto).

Ejemplos de comandos:
comandos

Si queres probar mi Bot para ver como es el tema de la interaccion podes agregarlo a un chat de Telegram por su nombre de usuario @RootAdminBot (el nombre fue pensado por lo que comentaba al principio del post, asi que quedo ese nombre, me da fiaca cambiarlo).

Espero que te haya gustado y si te animas a crear tu propio bot esperamos tus comentarios. Si hay algo que no entendiste o necesitas que te lo explique mas detalladamente podes escribirme a neoranger@openmailbox.org