Cómo hacer un backup de tus mensajes de Telegram

Supongamos que quieres hacer un backup de los mensajes de un grupo (canal, supergrupo, conversaciones privadas, usuarios, whatever…) de Telegram.  Puede haber distintas razones para ello: simple copia de seguridad para estar tranquilo, porque vas a irte de un grupo, porque van a cerrar el mismo… o, como en mi caso, con fines estadísticos.

Hasta donde yo sé, Telegram no ofrece herramientas directas para esta labor, pero al usar un protocolo abierto y bien documentado, hay gente que se ha pegado el curro de implementar aplicaciones cliente desde cero. Una de esas aplicaciones es tg, escrita en C, software libre y ejecutable desde la línea de comandos. tg es «simplemente» un cliente de Telegram, pero ofrece -entre muchas otras funcionalidades interesantes- la opción de ser ejecutado en modo servidor. De esta forma, mediante scripting, nos será posible obtener toda la información que tengamos almacenada en esta plataforma de mensajería instantánea. Pero no adelantemos acontecimientos 🙂 Lo primero será compilar esta bestia, cosa nada fácil (al menos en OSX, donde estoy ahora mismo).

Descargamos tg y seguimos los pasos de compilación e instalación. En resumen:

git clone --recursive https://github.com/vysheng/tg.git
cd tg

En OSX necesitarás instalar dependencias usando brew como sistema de gestor de paquetes:
brew install libconfig readline lua python libevent jansson
Verás multitud de warnings relacionados con posibles conflictos de versiones (sqlite, readline, SSL…). Brew nos avisa de que OSX ya viene con algunas de esas librerías instaladas y que si queremos usar o compilar las de brew tendremos que cambiar las variables de entorno (PATH, LDFLAGS , CFLAGS, PKG_CONFIG_PATH). Bueno, por ahora haremos caso omiso a esos warnings. Y pasamos al siguiente paso:

./configure

Idealmente te debería mostrar un mensaje de que todo va bien.

Y llegamos al make, donde seguramente obtengas un error indicando algo similar a:

lua-tg.c:664:27: error: unused function 'get_peer' [-Werror,-Wunused-function]

Un error en la línea get_peer. Si es el caso, tendrás que aplicar este parche, así:

patch < lua.patch
Patching file lua-tg.c

y volver a ejecutar el make. Si todo va bien, obtendrás un mensaje como el siguiente y de premio, el ejecutable telegram-cli en la carpeta bin.

La primera vez que ejecutes tg tendrás que asociarlo con tu número de teléfono. No olvides indicar el prefijo +34 si estás en España. Te llegará un PIN de verificación al teléfono (a través de un mensaje Telegram). Es el PIN que deberás indicar en la línea CALL correspondiente.
u026627:bin juanan$ ./telegram-cli
Telegram-cli version 1.4.1, Copyright (C) 2013-2015 Vitaly Valtman
Telegram-cli comes with ABSOLUTELY NO WARRANTY; for details type `show_license'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show_license' for details.
Telegram-cli uses libtgl version 2.1.0
Telegram-cli includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit. (http://www.openssl.org/)
I: config dir=[/Users/juanan/.telegram-cli]
[/Users/juanan/.telegram-cli] created
[/Users/juanan/.telegram-cli/downloads] created
phone number: +34XXXXXXXXX
code ('CALL' for phone code): XXXXX
User Juanan Pereira updated flags
User Juanan Pereira online (was online [2017/03/20 14:15:45])

Ahora dispondrás de multitud de comandos (teclea help para ver la lista completa). Puedes probar que todo ha ido bien tecleando comandos como get_self, para obtener información sobre tu cuenta en Telegram, contact_list para ver un listado con el nombre de tus contactos o channel_list para ver el nombre de los canales y grupos a los que estás suscrito.

Es interesante remarcar que tg dispone de autocompletamiento en la línea de comandos (soporte readline), por lo que basta con teclear las primeras letras del comando y pulsar TAB para que rellene el resto. Para salir, teclear quit.

Para poder cumplir con el objetivo marcado al comienzo de este post (backup de los mensajes de un grupo) necesitaremos instalar un script que maneje tg de forma automática. Se trata de telegram-history-dump, escrito en Ruby:

git clone https://github.com/tvdstaaij/telegram-history-dump

Debemos asegurar que disponemos de una versión reciente de Ruby (>= 2.0).

ruby --version
ruby 2.0.0p648 (2015-12-16 revision 53162) [universal.x86_64-darwin16]

Ahora podemos decidir hacer backup de todo o sólo de algunos grupos en concreto. Yo sólo necesito backup de un super-grupo, así que edito el fichero de configuración del script config.yaml e indico en la sección [backup_supergroups] que quiero sólo el grupo "MI_GRUPO". En el resto de secciones, indico null.

Para finalizar, lanzamos tg en modo servidor:

./telegram-cli --json -P 9009

(escuchando en el puerto 9009 e intercambiando mensajes en formato JSON)

y ¡por fin! lanzamos el script de backup:

u026627:telegram-history-dump juanan$ ruby telegram-history-dump.rb
I, [2017-03-20T14:27:23.381792 #24590]  INFO -- : Attaching to telegram-cli control socket at localhost:9009
I, [2017-03-20T14:27:23.849295 #24590]  INFO -- : Skipping XXX dialogs: .....
I, [2017-03-20T14:27:23.849485 #24590]  INFO -- : Backing up 1 dialogs: "MI_GRUPO"
I, [2017-03-20T14:27:23.849783 #24590]  INFO -- : Dumping "MI_GRUPO" (range 1-100)
I, [2017-03-20T14:27:24.854833 #24590]  INFO -- : Dumping "MI_GRUPO" (range 101-200)
I, [2017-03-20T14:27:25.860089 #24590]  INFO -- : Dumping "MI_GRUPO" (range 201-300)
I, [2017-03-20T14:27:26.864448 #24590]  INFO -- : Dumping "MI_GRUPO" (range 301-400)
I, [2017-03-20T14:27:27.869046 #24590]  INFO -- : Dumping "MI_GRUPO" (range 401-500)
I, [2017-03-20T14:27:28.872592 #24590]  INFO -- : Dumping "MI_GRUPO" (range 501-600)
I, [2017-03-20T14:27:28.977374 #24590]  INFO -- : Finished

Tras unos segundos (veremos el progreso en la terminal donde tengamos lanzado telegram-cli) obtendremos el resultado en la carpeta output/ . Si disponemos del comando jq (si no, lo instalamos con brew install jq) podremos visualizar el JSON resultante cómodamente así:


cat output/json/MI_GRUPO.jsonl | jq

Espero que os haya sido de interés 🙂

 

What’s the default password of root user in mariadb?

If you have just installed mariadb, you should run this command in order to set a password for the root user and secure your installation:

$ sudo mysql_secure_installation

Besides asking you to provide the new root password, this utility will help you to remove anonymous user (created by default, intended for testing), disallow root login remotely (root should only be allowed to connect from ‘localhost’), remove test database and privileges ad reloading the privilege table. All of it just pressing the Enter key a couple of times 🙂 Not bad!

If that process doesn’t work, try this other one:

(using sudo, don’t specify any password)

$ sudo mysql -u root

Create a new database:

CREATE DATABASE yourdb;

Grant privileges to a new user:

GRANT ALL ON yourdb.* TO yournewuser@localhost IDENTIFIED BY 'yourpassword';
FLUSH privileges;

 

[Vim] e365 failed to print postscript file

Nota rápida por si a alguien más le viene bien. La cuestión es que desde Vim no podía imprimir (desde LibreOffice lo hacía sin problemas). El error que arrojaba Vim era:

e365 failed to print postscript file

La cuestión es que el comando lpr (comando Linux para imprimir que Vim usa internamente) intentaba lanzar el trabajo a la impresora por defecto y ésta no estaba definida. En Ubuntu uso el sistema de impresión CUPS. Según el manual de CUPS, para conocer los nombres de impresoras disponibles podemos usar el comando lpstat:

$ lpstat -p -d

Y una vez conocido el nombre de las impresoras, puedes fijar una por defecto con lpoptions:

$ lpoptions -d hp_LaserJet_1300

¡Listo! Vim (GVim en mi caso) imprime ahora perfectamente 🙂

Buscar cadenas de texto dentro de ficheros ODT

Como sabéis, los ficheros ODT de LibreOffice son simples ficheros .zip . Dentro de ellos, encontramos distintos archivos xml, gráficos incrustados, etc. Un ejemplo:

$ unzip -l herramientas.odt 
Archive:  herramientas.odt
  Length      Date    Time    Name
---------  ---------- -----   ----
       39  2012-07-20 12:00   mimetype
      997  2012-07-20 12:00   meta.xml
     8798  2012-07-20 12:00   settings.xml
    12512  2012-07-20 12:00   content.xml
     7003  2012-07-20 12:00   Thumbnails/thumbnail.png
       22  2012-07-20 12:00   layout-cache
      899  2012-07-20 12:00   manifest.rdf
        0  2012-07-20 12:00   Configurations2/popupmenu/
        0  2012-07-20 12:00   Configurations2/images/Bitmaps/
        0  2012-07-20 12:00   Configurations2/toolpanel/
        0  2012-07-20 12:00   Configurations2/statusbar/
        0  2012-07-20 12:00   Configurations2/toolbar/
        0  2012-07-20 12:00   Configurations2/progressbar/
        0  2012-07-20 12:00   Configurations2/menubar/
        0  2012-07-20 12:00   Configurations2/floater/
        0  2012-07-20 12:00   Configurations2/accelerator/current.xml
    12033  2012-07-20 12:00   styles.xml
     1185  2012-07-20 12:00   META-INF/manifest.xml
---------                     -------
    43488                     18 files

El problema viene cuando tienes una carpeta llena de ficheros .ODT y quieres buscar un texto en concreto en todos ellos. Al tratarse de ficheros comprimidos, no vale con usar ni el comando strings ni el comando grep, porque no encontrará lo que buscas.

¿Solución? Convertir los .odt a texto con el comando odt2txt (funciona también para .odg y otros formatos):

for i in *.odt; 
do 
   echo $i; 
   echo "*************"; 
   odt2txt $i | grep -i cadena_de_texto_a_buscar; 
done

Ese bucle for recorre todos los ficheros con extensión .odt, los convierte a texto (no genera ficheros nuevos, la conversión se realiza hacia la salida estándar) y los pasa por un pipe a grep, que realiza la búsqueda. El echo $i con los *** sirve para remarcar el nombre del fichero en el que se encontró la cadena.

Una china en el autocompletamiento Bash

No una china en el zapato… sino en el autocompletamiento Bash. Los usuarios de la línea de comandos solemos «volar» literalmente mientras escribimos comandos en terminal. Pero usamos un truco: el autocompletamiento Bash. Si quieres ver el contenido del directorio /tmp/algo/muy/largo basta con teclear (donde TAB es el tabulador):

ls /t<TAB>a<TAB>m<TAB>l<TAB>

y Bash lo autocompletará así:

ls /tmp/algo/muy/largo

Sin embargo, desde la versión de Bash que nos trajo Natty (Ubuntu 11.04), al teclear

ls /t<TAB>_

el autocompletamiento añadía un espacio en blanco a la derecha del TAB y por tanto se rompía la magia (no es posible seguir tecleando y pulsando TAB a partir de ese espacio)

En este hilo de discusión al respecto de este bug, el usuario Silas da con la clave para arreglar este comportamiento tan errático: basta con editar el fichero /etc/bash_completion, línea 1587 y donde pone -o default poner- o filenames. Guardamos los cambios y a partir de la siguiente terminal que abramos, el problema estará solucionado.