Search

Debian - Server Notifications thru Telegram

Contents[Hide]

dropcap debian

As a system administrator, you must be receiving your important server notifications by emails. Email has been used since decades, but it is slowly replaced in everydays life by social networks. With social network clients, messages are usually displayed as thread and get instant notification on your smartphone.

So, why not receiving your main server notifications on one of your favorite social network client ?

Telegram is becoming a very popular social network as it is free and multi-platforms. It has also a unique feature : it's allowing the use of bots. Bots are very interesting as they can be seen as an application account associated to a real person's account. They are able to send or receive messages to/from either an individual account or a group.

So, instead of sending a mail, it could be very interesting for your Debian/Ubuntu server to be able to send you Telegram notification. You can for example create an administrator group and send all your server notifications to this group. Any administrator belonging to this Telegram group will get instant notification from the server.

This article explains how to setup a server environment to very easily send Telegram notifications from any of your server script or service. It also provides a script that allows you to send Telegram messages including text, photos, documents, logs, …

It has been tested on a Debian 8.5 server but it should work on any modern Linux distribution.

1. Pre-Requisite

1.1. Create your Telegram Bot

Telegram allows you to easily create your own Bot with the help of @BotFather.

This page explain very clearly what you can expect from your Telegram Bot and how to create it.

To make it short, a Bot is a type of Telegram account that doesn't need to be associated to a phone number. It's an application account associated to your personnal account.

Once you have created your Bot, you get your API key. This key looks like 123456789:AABBCCDD_abcdefghijklmnopqrstuvwxyz.

As Telegram APIs are using plain httpsURL with POST data, this API key is needed to identify the Bot when you send messages, photos and documents straight from any web client.

All parameters are explained in Telegram API page.

Your Bot will be able to send messages either to :

  • your personnal account
  • any channel it belongs to

But to send any message, your Bot will need to use either your user ID or a Channel ID. It can not address an account simply using its name.

Here is the way to get these IDs.

1.2. Get your User ID

To get your user ID, you just need to :

  • send a message to your Bot from your Telegram client
  • call the following URL from any web browser
 URL  https://api.telegram.org/bot123456789:AABBCCDD_abcdefghijklmnopqrstuvwxyz/getUpdates
 Answer  {"ok":true,"result":[{"update_id":563273027,"message":{"message_id":505, "from":"id":11223344, "first_name":"YourFirstName", "last_name":"YourLastName", "username":"YourUserName"},
"chat":{"id":11223344, "first_name":"YourFirstName", "last_name":"YourLastName", "username":"YourUserName", "type":"private"}, "date":1483150094, "text":"Hello bot !"}}]}

 

You can see here that your user ID is 11223344.

This is the client ID that Telegram Bot should use to send me a message.

1.3. Get Channel ID

If your server must notify multiple users, it should notify a channel.

First, from your Telegram client, create a channel and keep it public as you need to obtain the channel ID. Give a name @YourNewChannelName to your channel.

Next, from your Bot thread, go to the Bot parameters page. You should see that your Bot is in both Members and Administrators list.

The Bot is now ready to publish messages.

To get your channel ID, you just need to send a message to @YourNewChannelName from any web browser using your Bot API key :

 URL https://api.telegram.org/bot123456789:AABBCCDD_abcdefghijklmnopqrstuvwxyz/sendMessage?chat_id=@YourNewChannelName&text=FirstMessage
 Answer

{"ok":true, "result":{"message_id":2, "chat":{"id":-1234567890123, "title":"Your Channel", "username":"YourNewChannelName", "type":"channel"}, "date":1483383169, "text":"FirstMessage"}}

 

You can see in the resulting JSON string that your new channel ID is -1234567890123.

You can now edit your Channel and convert its type to Private.

Your Bot can still send a message to the channel using the Channel ID :

 URL https://api.telegram.org/bot123456789:AABBCCDD_abcdefghijklmnopqrstuvwxyz/sendMessage?chat_id=-1234567890123&text=SecondMessage
 Answer

{"ok":true, "result":{"message_id":2, "chat":{"id":-1234567890123, "title":"Your Channel", "username":"YourNewChannelName", "type":"channel"}, "date":1483383169, "text":"SecondMessage"}}

 

2. Telegram Notification Script

It's now time to install and configure Telegram notification script on the server.

The script will be in charge of sending Telegram notification and can be used by any script, service, daemon, … on the server.

2.1. Functionalities

Main functionality of Telegram notification script is to … send a Telegram notification.

It allows to :

  • display plain text message or a file content (log, …)
  • display a title
  • display an emoji as leading icon  (codes may be found in this emoji table)
  • add a photo or a document
  • select formatting style as Markdown (default) or HTML
  • disable message notification on the client side
  • select Bot to use to send the message (thru API key)
  • set message recipient ID

Terminal
# telegram-notify
Tool to send a message to a Telegram User or Channel.
Message is sent from a Telegram Bot and can contain icon, text, image and/or document.
Main parameters are :
  --text <text>       Text of the message or file holding the text
  --photo <file>      Image to display
  --document <file>   Document to transfer
Options are :
  --title <title>     Title of the message (if text message)
  --html              Use HTML mode for text content (markdown by default)
  --silent            Send message in silent mode (no user notification on the client)
  --user <user-id>    Recipient User or Channel ID (replaces user-id= in /etc/telegram-notify.conf)
  --key <api-key>     API Key of your Telegram bot (replaces api-key= in /etc/telegram-notify.conf)
Optionnal icons are :
  --success           Add a success icon
  --error             Add an error icon
  --question          Add a question mark icon
  --icon <code>       Add an icon by UTF code (ex 1F355)

Here are some examples of notifications and the expected result :

Terminal
# telegram-notify --success --text "Action *sucessful* with markdown *bold* example"
# telegram-notify --error --title "Error" --text "Error message with a title"
# telegram-notify --question --title "File content display" --text "/tmp/log.txt"
# telegram-notify --icon 1F355 --text "Message with custom icon 1F355 and embedded image" --photo "/tmp/icon.png"
# telegram-notify --text "Result is available in the embedded document" --document "/tmp/result.log"

telegram test message

2.2. Script

Main notification script is placed under /usr/local/sbin/telegram-notify.

#!/bin/bash
# ---------------------------------------------------
#  Send notification to a telegram account thru a bot account
#  Configuration is stored in /etc/telegram-notify.conf
#  Depends on curl 
#
#  Revision history :
#    10/01/2016, V1.0 - Creation by N. Bernaerts
#    22/01/2016, V1.1 - Handle emoticons
#    06/08/2016, V1.2 - Add API key and User ID parameters
#                       Remove dependency to PERL
#    08/08/2016, V1.3 - Add --document, --html and --silent options
#    10/11/2016, V1.4 - Add --icon option
# ---------------------------------------------------

# initialise variables
NOTIFY_TEXT=""
DISPLAY_TEXT=""
DISPLAY_PICT=""
DISPLAY_ICON=""
DISPLAY_MODE="markdown"
DISPLAY_SILENT="false"

# Configuration file
FILE_CONF="/etc/telegram-notify.conf"

# -------------------------------------------------------
#   Check tools availability
# -------------------------------------------------------

command -v curl >/dev/null 2>&1 || { echo "[Error] Please install curl"; exit 1; }

# -------------------------------------------------------
#   Loop to load arguments
# -------------------------------------------------------

# if no argument, display help
if [ $# -eq 0 ] 
then
  echo "Tool to send a message to a Telegram User or Channel."
  echo "Message is sent from a Telegram Bot and can contain icon, text, image and/or document."
  echo "Main parameters are :"
  echo "  --text <text>       Text of the message or file holding the text"
  echo "  --photo <file>      Image to display"
  echo "  --document <file>   Document to transfer"
  echo "Options are :"
  echo "  --title <title>     Title of the message (if text message)"
  echo "  --html              Use HTML mode for text content (markdown by default)"
  echo "  --silent            Send message in silent mode (no user notification on the client)"
  echo "  --user <user-id>    Recipient User or Channel ID (replaces user-id= in ${FILE_CONF})"
  echo "  --key <api-key>     API Key of your Telegram bot (replaces api-key= in ${FILE_CONF})"
  echo "Optionnal icons are :"
  echo "  --success           Add a success icon"
  echo "  --error             Add an error icon"
  echo "  --question          Add a question mark icon"
  echo "  --icon <code>       Add an icon by UTF code (ex 1F355)" 
  exit
fi

# loop to retrieve arguments
while test $# -gt 0
do
  case "$1" in
    "--text") shift; DISPLAY_TEXT="$1"; shift; ;;
    "--photo") shift; PICTURE="$1"; shift; ;;
    "--document") shift; DOCUMENT="$1"; shift; ;;
    "--title") shift; DISPLAY_TITLE="$1"; shift; ;;
    "--html") DISPLAY_MODE="html"; shift; ;;
    "--silent") DISPLAY_SILENT="true"; shift; ;;
    "--user") shift; USER_ID="$1"; shift; ;;
    "--key") shift; API_KEY="$1"; shift; ;;
    "--success") DISPLAY_ICON=$(echo -e "\U2705"); shift; ;;
    "--error") DISPLAY_ICON=$(echo -e "\U1F6A8"); shift; ;;
    "--question") DISPLAY_ICON=$(echo -e "\U2753"); shift; ;;
    "--icon") shift; DISPLAY_ICON=$(echo -e "\U$1"); shift; ;;
    *) shift; ;;
  esac
done

# -------------------------------------------------------
#   Read configuration
# -------------------------------------------------------

# if needed, load from configuration file
[ -f "${FILE_CONF}" -a "${API_KEY}" = "" ] && API_KEY=$(cat "${FILE_CONF}" | grep "api-key=" | cut -d'=' -f2)
[ -f "${FILE_CONF}" -a "${USER_ID}" = "" ] && USER_ID=$(cat "${FILE_CONF}" | grep "user-id=" | cut -d'=' -f2)

# check API key and User ID
[ "${API_KEY}" = "" ] && { echo "[Error] Please provide API key or set it in ${FILE_CONF}"; exit 1; }
[ "${USER_ID}" = "" ] && { echo "[Error] Please provide User ID or set it in ${FILE_CONF}"; exit 1; }

# -------------------------------------------------------
#   Check for file existence
# -------------------------------------------------------

# if picture, check for image file
[ "${PICTURE}" != "" -a ! -f "${PICTURE}" ] && { echo "[error] Image file ${PICTURE} doesn't exist"; exit; }

# if document, check for document file
[ "${DOCUMENT}" != "" -a ! -f "${DOCUMENT}" ] && { echo "[error] Document file ${DOCUMENT} doesn't exist"; exit; }

# -------------------------------------------------------
#   String preparation : space and line break
# -------------------------------------------------------

# if text is a file, get its content
[ -f "${DISPLAY_TEXT}" ] && DISPLAY_TEXT="$(cat "${DISPLAY_TEXT}")"

# convert \n to LF
DISPLAY_TEXT="$(echo "${DISPLAY_TEXT}" | sed 's:\\n:\n:g')"

# if icon defined, include ahead of notification
[ "${DISPLAY_ICON}" != "" ] && NOTIFY_TEXT="${DISPLAY_ICON} "

# if title defined, add it with line break
if [ "${DISPLAY_TITLE}" != "" ]
then
# convert title according to Markdown or HTML
[ "${DISPLAY_MODE}" = "html" ] && NOTIFY_TEXT="${NOTIFY_TEXT}<b>${DISPLAY_TITLE}</b>%0A%0A" \
       || NOTIFY_TEXT="${NOTIFY_TEXT}*${DISPLAY_TITLE}*%0A%0A"
fi

# if text defined, replace \n by HTML line break
[ "${DISPLAY_TEXT}" != "" ] && NOTIFY_TEXT="${NOTIFY_TEXT}${DISPLAY_TEXT}"

# -------------------------------------------------------
#   Notification
# -------------------------------------------------------

# if photo defined, display it with icon and caption
if [ "${PICTURE}" != "" ]
then
  # display image
  curl --silent --insecure --form chat_id=${USER_ID} --form disable_notification=${DISPLAY_SILENT} --form photo="@${PICTURE}" --form caption="${NOTIFY_TEXT}" "https://api.telegram.org/bot${API_KEY}/sendPhoto" 

# if document defined, send it with icon and caption
elif [ "${DOCUMENT}" != "" ]
then
  # transfer document
  curl --silent --insecure --form chat_id=${USER_ID} --form disable_notification=${DISPLAY_SILENT} --form document="@${DOCUMENT}" --form caption="${NOTIFY_TEXT}" "https://api.telegram.org/bot${API_KEY}/sendDocument" 

# else, if text is defined, display it with icon and title
elif [ "${NOTIFY_TEXT}" != "" ]
then
  # display text message
  curl --silent --insecure --data chat_id="${USER_ID}" --data "disable_notification=${DISPLAY_SILENT}" --data "parse_mode=${DISPLAY_MODE}" --data "text=${NOTIFY_TEXT}" "https://api.telegram.org/bot${API_KEY}/sendMessage"

#  else, nothing, error
else
  # error message
  echo "[Error] Nothing to notify"
fi

# end
exit 0

2.3. Configuration

Telegram notification script is using 2 default parameters that should be configured in /etc/telegram-notify.conf :

  • api-key : Your Bot API key
  • user-id : Default User ID or Channel ID to send messages to

# -------------------------------#
#   /etc/telegram-notify.conf    #
# -------------------------------#

[general]
api-key=YourAPIKey
user-id=YourUserOrChannelID

When calling the notification script these default parameters may be surcharged with --user and --key parameters.

2.4. Installation

Installation of Telegram notification script is quite simple as all files are available from my Debian GitHub repository :

Terminal
# wget https://raw.githubusercontent.com/NicolasBernaerts/debian-scripts/master/telegram/telegram-notify-install.sh
# ./telegram-notify-install.sh

Once you've configured /etc/telegram-notify.conf, you are ready to send your first Telegram notification from command line.

 

Hope it helps.

Signature Technoblog

This article is published "as is", without any warranty that it will work for your specific need.
If you think this article needs some complement, or simply if you think it saved you lots of time & trouble,
just let me know at This email address is being protected from spambots. You need JavaScript enabled to view it.. Cheers !

icon linux icon debian icon apache icon mysql icon php icon piwik icon googleplus