Enviar notificações do bacula via Telegram

Para o envio de mensagens via Telegram, é possível utilizar uma API escrita em C, chamada “Telegram Messenger CLI”, que é uma interface via linha de comando que interage com os servidores do Telegram.
Uma das vantagens em relação ao yowsup, é que é possível receber as mensagens em diversos dispositivos conectados ao mesmo tempo.
https://github.com/vysheng/tg

Dependências necessárias para baixar com o apt-get:

apt-get install libreadline-dev libconfig-dev libssl-dev lua5.2 liblua5.2-dev libevent-dev libjansson-dev libpython-dev make git

Baixar código fonte e compilar

cd /usr/src
git clone --recursive https://github.com/vysheng/tg.git && cd tg
./configure
make -j 8

Configurar os diretórios para o telegram-cli

mkdir /usr/local/telegram-cli
mkdir /usr/local/telegram-cli/keys
mkdir /usr/local/telegram-cli/profiles
mkdir /usr/local/telegram-cli/log

Copiar as chaves públicas  e o binário do telegram-cli

cp /usr/src/tg/bin/telegram-cli  /usr/local/bin/
cp /usr/src/tg/server.pub  /usr/local/telegram-cli/keys/
cp /usr/src/tg/tg-server.pub  /usr/local/telegram-cli/keys/

Criar o arquivo de configuração /etc/telegram.conf

default_profile = "bacula";

bacula = {
    config_directory = "/usr/local/telegram-cli/profiles/bacula";
    msg_num = true;
    binlog_enabled = true;
    log_level = 2;
};

Executar o telegram-cli e solicitar a autorização.
Caso encontre problemas para se registrar, acesse o https://web.telegram.org pois os códigos serão mandados para a interface web também.

telegram-cli --config /etc/telegram.conf --rsa-key /usr/local/telegram-cli/keys/tg-server.pub

change_user_group: can't find the user telegramd to switch to
Telegram-cli version 1.3.3, 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.0.3
Telegram-cli includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit. (http://www.openssl.org/)
Telegram-cli uses libpython version 2.7.9
No binlog found. Creating new one
phone number: # digite o número do seu celular 55DDDFONE
code ('CALL' for phone code): # digite o código recebido por SMS
>

Se tudo ocorrer bem você já está habilitado para enviar mensagens usando o telegram-cli. Perceba que você esta em um terminal, se digitar help irá mostrar todos os comandos disponíveis.
É possível mandar mensagens usando o nome do usuário, porém é melhor utilizar o ID do mesmo. Para descobrir o ID do usuário, no terminal do telegram-cli digite get_self e anote o código dentro do parênteses após o # na primeira linha. O ID do usuário é o número 123456789, por exemplo.

> get_self
User Nome Usuário (#123456789):
        phone: 55XXXXXXXXXX
        offline (was online [2016/02/15 21:03:59])

Para testar o envio das mensagens dentro do terminal do telegram-cli vamos utilizar o comando abaixo:

> msg user#123456789 "teste mensagem telegram"

Se ocorrer algum erro como este “FAIL: 71: RPC_CALL_FAIL 400: PEER_ID_INVALID”, é preciso adicionar à lista de contatos o telefone do destinatário.

# Adicionar contato
> add_contact 55DDDFONE Nome Sobrenome
# Listar contatos
> contact_list
Nome Sobrenome
# Pegar informações do contato, espaços devem ser substituídos por _ (underscore)
# Ou é possível usar o TAB para autocompletar.
> > user_info Nome_Sobrenome
User Nome Sobrenome @nomesobrenome (#987654321):
 phone: 55XXXXXXXXXX
 offline (was online [2016/02/15 22:50:01])

Para enviar mensagens para um grupo, é preciso criar um novo grupo ou utilizar um já existente e adicionar no grupo o número que será utilizado para enviar as mensagens. Sugestiono criar o nome do grupo ou alterar o nome dele para ficar monossílabo e sem acentuação. Exemplo: Bacula.

Para descobrir o ID do grupo, no terminal do telegram-cli digite chat_info Bacula e anote o código dentro do parênteses. O ID do grupo é o número 123456789, por exemplo.

> chat_info Bacula
Chat Bacula updated photo
Chat Bacula (id 123456789) members:
                XXXXXXXXX invited by Wanderlei at [2016/02/20 09:28:00]
                Wanderlei invited by Wanderlei at [2016/02/20 09:28:00] admin
>

Para testar o envio das mensagens dentro do terminal do telegram-cli para um grupo vamos utilizar o comando abaixo:

msg chat#123456789 "teste mensagem telegram para um grupo"

Testar o envio via linha de comando

/usr/local/bin/telegram-cli --config /etc/telegram.conf --rsa-key /usr/local/telegram-cli/keys/tg-server.pub --exec "msg user#987654321"teste mensagem telegram""

Criar o script em /etc/bacula/scripts/_send_telegram.sh e dar permissão a+x.
(Para que os emojis funcionem corretamente é necessário que o arquivo esteja com a codificação UTF8).
(O script é praticamente o mesmo do _send_whatsapp.sh, apenas com as modificações necessárias

#!/bin/bash
# /etc/bacula/scripts/_send_telegram.sh
# Função para converter bytes para humanos
b2h(){
    # Spotted Script @: http://www.linuxjournal.com/article/9293?page=0,1
    SLIST=" bytes, KB, MB, GB, TB, PB, EB, ZB, YB"
    POWER=1
    VAL=$( echo "scale=2; $1 / 1" | bc)
    VINT=$( echo $VAL / 1024 | bc )
    while [ ! $VINT = "0" ]
    do
        let POWER=POWER+1
        VAL=$( echo "scale=2; $VAL / 1024" | bc)
        VINT=$( echo $VAL / 1024 | bc )
    done
    echo $VAL$( echo $SLIST  | cut -f$POWER -d, )
}
# fim da funcao

# Declaração de variáveis
HOUR=$(date +%d/%m/%Y %H:%M:%S)
NUM_DEST="user#123456789"  # ou "chat#123456789" para um grupo
COMMAND="msg $NUM_DEST"
TGEXEC="/usr/local/bin/telegram-cli"
CONF="/usr/local/telegram-cli/telegram.conf"
RSAKEY="/usr/local/telegram-cli/keys/tg-server.pub"
LOGTG="/usr/local/telegram-cli/log/telegram.log"
LOG="/etc/bacula/log/telegram.log"
DBUSER="bacula"
DBPASSWORD="bacula"
DBNAME="bacula"
#convert_humanreadable(Job.JobBytes) as JobBytes, Job.JobFiles,
# Query para buscar as informações do JobId
sql_query="select Job.Name, Job.JobId,(select Client.Name from Client where Client.ClientId = Job.ClientId) as Client, Job.JobBytes, Job.JobFiles,
case when Job.Level = 'F' then 'Full' when Job.Level = 'I' then 'Incremental' when Job.Level = 'D' then 'Differential' end as Level,
(select Pool.Name from Pool where Pool.PoolId = Job.PoolId) as Pool,
(select Storage.Name  from JobMedia left join Media on (Media.MediaId = JobMedia.MediaId) left join Storage on (Media.StorageId = Storage.StorageId)
where JobMedia.JobId = Job.JobId limit 1 ) as Storage, date_format( Job.StartTime , '%d/%m/%Y %H:%i:%s' ) as StartTime, date_format( Job.EndTime , '%d/%m/%Y %H:%i:%s' ) as EndTime,
sec_to_time(TIMESTAMPDIFF(SECOND,Job.StartTime,Job.EndTime)) as Duration, Job.JobStatus,
(select Status.JobStatusLong from Status where Job.JobStatus = Status.JobStatus) as JobStatusLong
from Job where Job.JobId=$1"

# Atribuição de Variáveis
str=`echo -e "$sql_query" | mysql -u $DBUSER-p$DBPASSWORD -D $DBNAME -B |  while read; do sed 's/t/|/g'; done`
JobName=`echo $str | cut -d"|" -f1`
JobId=`echo $str | cut -d"|" -f2`
Client=`echo $str | cut -d"|" -f3`
JobBytes=`b2h $(echo $str | cut -d"|" -f4)`
JobFiles=`echo $str | cut -d"|" -f5`
Level=`echo $str | cut -d"|" -f6`
Pool=`echo $str | cut -d"|" -f7`
Storage=`echo $str | cut -d"|" -f8`
StartTime=`echo $str | cut -d"|" -f9`
EndTime=`echo $str | cut -d"|" -f10`
Duration=`echo $str | cut -d"|" -f11`
JobStatus=`echo $str | cut -d"|" -f12`
Status=`echo $str | cut -d"|" -f13`

# Emojis
# OK
# http://emojipedia.org/white-heavy-check-mark/
# Not OK
# http://emojipedia.org/cross-mark/
# Floppy Disk
# http://emojipedia.org/floppy-disk/
# Header diferente caso tenha erro
if [ "$JobStatus" == "T" ] ; then
   HEADER=">>>>> ? BACULA BAKUP ✅ <<<<<n"  # OK
else
   HEADER=">>>>> ? BACULA BAKUP ❌ <<<<<n"  # Error
fi
# Formata a mensagem
MESSAGE="$HEADERnJobName=$JobNamenJobid=$JobIdnClient=$ClientnJobBytes=$JobBytesnJobFiles=$JobFilesnLevel=$LevelnPool=$PoolnStorage=$StoragenStartTime=$StartTimenEndTime=$EndTimenDuration=$DurationnJobStatus=$JobStatusnStatus=$StatusnAttempt="
MESSAGELOG="Message: JobName=$JobName | Jobid=$JobId | Client=$Client | JobBytes=$JobBytes | Level=$Level | Status=$Status"
# PROCESS_NUM=$(ps -ef | grep "$1" | grep -v "grep" | wc -l)

# Loop múltiplas tentativas
COUNT=1
while [ $COUNT -le 20 ]; do

   echo "$(date +%d/%m/%Y %H:%M:%S) - Start message send (attempt $COUNT) ..." >> $LOG
   echo "$(date +%d/%m/%Y %H:%M:%S) - $MESSAGELOG" >> $LOG

   while [ $(ps -ef | grep telegram-cli | grep -v grep | wc -l) -eq 1 ]; do
      echo "$(date +%d/%m/%Y %H:%M:%S) - Telegram still running, waiting 2 seconds before a new try ..." >> $LOG
      sleep 2;
   done;

   $TGEXEC --config $CONF --rsa-key $RSAKEY --exec "$COMMAND "$MESSAGE${COUNT}"" &>> $LOG

   RET=$?

   if [ $RET -eq 0 ]; then
     echo "$(date +%d/%m/%Y %H:%M:%S) - Attempt $COUNT executed successfully!" >> $LOG
     exit 0
   else
     echo "$(date +%d/%m/%Y %H:%M:%S) - Attempt $COUNT failed!" >> $LOG
     echo "$(date +%d/%m/%Y %H:%M:%S) - Waiting 30 seconds before retry ..." >> $LOG
     sleep 30
     (( COUNT++ ))
   fi

done

Configurando o Bacula
Deve-se incluir o RunScript, conforme abaixo, salvar e dar um reload no bconsole:

JobDefs {
  Name = "Backup_Padrao"
  Type = Backup
  Level = Incremental
  Client = bacula-fd
  FileSet = "FileSet_Bacula"
  Schedule = "WeeklyCycle"
  Messages = Standard
  Pool = "File"
  SpoolAttributes = yes
  Priority = 10
  Write Bootstrap = "/etc/bacula/working/%c.bsr"
  RunScript {
     Command = "/etc/bacula/scripts/_send_telegram.sh %i"
     RunsWhen = After
     RunsOnFailure = yes
     RunsOnClient = no
     RunsOnSuccess = yes # se quiser apenas nos Jobs com erro, altere para No.
  }
}

Exemplo de mensagem com sucesso e com erro:
telegram_message

Disponível em: pt-brPortuguêsenEnglish (Inglês)

Deixe uma resposta