Sending Bacula notifications using Telegram

To send notifications using Telegram is it possible with an API written in C, called “Telegram Messenger CLI”, that is a command line interface that interacts with Telegram servers.
One advantage of the telegram-cli instead yowsup, is possible receive notifications in many device in the same time.
https://github.com/vysheng/tg

Required dependencies to install using apt-get

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

Download source and compile

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

Configure directories for 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

Copy public keys and telegram-cli binary

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/

Create default config /etc/telegram.conf

default_profile = "bacula";

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

Execute telegram-cli and request authorization.
If you have problems to register the Telegram, access https://web.telegram.org, because the codes are send to web interface also.

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
>

If all goes well you are already able to send messages using the telegram-cli. Realize that you are in a terminal, if you type “help”, will show all available commands.
You can send messages using the user name, but it is better to use user ID. To find the user ID, at telegram-cli terminal type “get_self” and get the code inside the parentheses after the # on the first line. The user ID is the number 123456789, for example.

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

To check if the telegram-cli is ready to send messages, use the following command:

> msg user#123456789 "telegram message example"

If occurs an error like “FAIL: 71: RPC_CALL_FAIL 400: PEER_ID_INVALID”, is necessary add the contact to contact list.

# add the contact to contact list
> add_contact XXXXXXXXXX Name LastName
# Listar contatos
> contact_list
Name LastName
# Spaces must be replaced by underscore (_) in contact name
# Is it possible use TAB for command completion.
> > user_info Name_LastName
User Name LastName @namelastname (#987654321):
 phone: 1XXXXXXXXXX
 offline (was online [2016/02/15 22:50:01])

To send messages for a group, is necessary creates a new group or use an existing one and add to the group the number will be used to send the messages. I suggest create a group name or change name to monosyllabic word. Example: Bacula.

To find the group ID, at telegram-cli terminal type “chat_info Bacula” and write the code inside the parentheses. The group ID number is 123456789, for example.

> 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
>

To check if the telegram-cli is ready to send messages for a group, use the following command:

msg chat#123456789 "telegram message example for a group"

Send using command line

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

Create an script file /etc/bacula/scripts/_send_telegram.sh and give permission a+x.
(For the Emoji works properly it is necessary that the file is in UTF8 encoding)
(The script is pretty similar with _send_whatsapp.sh only with some modifications)

#!/bin/bash
# /etc/bacula/scripts/_send_telegram.sh
# function bytes to humanreadable
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, )
}


# Variables
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"

#MySQL config
DBUSER="bacula"
DBPASSWORD="bacula"
DBNAME="bacula"
# Query to get Jobs from 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"

# Variables get the fields
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 # Message 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  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

Change Bacula Config
You can set in a few some Jobs, but how I wanted in all, I set up in JobDefs. It should include the RunScript, as indicated below, save and do reload in 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 # execute in all jobs
  }
}

Example of message:
telegram_message
Source: http://www.huttel.com.br/

Disponível em: pt-brPortuguês (Portuguese (Brazil)) enEnglish

Leave a Reply

Close Menu