One of the rules of working with CI (Continuous Integration) is that everyone should be able to see the build status, i.e., synchronization. And what could be better than receiving notifications about failed or successful builds directly in the chat?
- 3cky/jenkins-telegram-uploader-plugin: Jenkins CI post-build action that uploads artifacts generated during build process to Telegram chats.
- jenkinsci/telegram-notifications-plugin: This plugin allows you to send messages from Jenkins jobs to Telegram chat.
- Use the post-functions section in the pipeline.
The third option is more versatile, and although I spent a lot of time trying to get the first plugin to work, I couldn’t get it to run.
Setting Up the Bot
Create a New Bot and Notification Channel.
Find @botfather
and follow the instructions to create a new bot. It is important to get the bot token. The token will allow anyone to control your bot.

Create a new channel and add the newly created bot with admin rights, necessary for posting new messages.
Obtaining the Chat ID for Sending Notifications
Make a request through the browser’s address bar.
https://api.telegram.org/bot<TOKEN>/getUpdates
Where we replace
Response to the request:
{
"ok": true,
"result": [
{
"update_id": 151985646,
"channel_post": {
"message_id": 3,
"chat": {
"id": -1001459789606,
"title": "Leroy",
"type": "channel"
},
"date": 1603123407,
"text": "/sub",
"entities": [
{
"offset": 0,
"length": 4,
"type": "bot_command"
}
]
}
}
]
}
You need to save the chat.id and keep the - sign before the number; this is the full identifier.
Preparing Jenkins
Setting Up API Authorization Variables
First, add the chat ID, to which we will send messages, and the token of the created bot to the Jenkins credentials section.
- Manage Jenkins -> Manage Credentials

- To send notifications on Telegram, create a new domain.

- We add a variable for the chat ID and a separate variable for the token of the created bot. We specify understandable IDs for further substitution of variables.

Setting up the pipeline.
Assuming the pipeline is already configured through Jenkinsfile, all that’s left is to add to it. post-section
pipeline {
agent any
stages {
stage('Checkout') {
steps {
echo 'Checkout..'
checkout scm
}
}
stage('Build') {
steps {
// script here
}
echo 'Done'
}
}
stage('Publish') {
steps {
// script here
echo "Deployed Successfully!"
}
}
}
post {
success {
// script here
}
aborted {
// script here
}
failure {
// script here
}
}
}
The post-section is executed regardless of the result of the main pipeline stages. It is in this section where the actions to send notifications will be carried out.
All specified conditions should contain the scripts to be executed:
post {
success {
withCredentials([string(credentialsId: 'botSecret', variable: 'TOKEN'), string(credentialsId: 'chatId', variable: 'CHAT_ID')]) {
sh ("""
curl -s -X POST https://api.telegram.org/bot${TOKEN}/sendMessage -d chat_id=${CHAT_ID} -d parse_mode=markdown -d text='*${env.JOB_NAME}* : POC *Branch*: ${env.GIT_BRANCH} *Build* : OK *Published* = YES'
""")
}
}
aborted {
withCredentials([string(credentialsId: 'botSecret', variable: 'TOKEN'), string(credentialsId: 'chatId', variable: 'CHAT_ID')]) {
sh ("""
curl -s -X POST https://api.telegram.org/bot${TOKEN}/sendMessage -d chat_id=${CHAT_ID} -d parse_mode=markdown -d text='*${env.JOB_NAME}* : POC *Branch*: ${env.GIT_BRANCH} *Build* : `Aborted` *Published* = `Aborted`'
""")
}
}
failure {
withCredentials([string(credentialsId: 'botSecret', variable: 'TOKEN'), string(credentialsId: 'chatId', variable: 'CHAT_ID')]) {
sh ("""
curl -s -X POST https://api.telegram.org/bot${TOKEN}/sendMessage -d chat_id=${CHAT_ID} -d parse_mode=markdown -d text='*${env.JOB_NAME}* : POC *Branch*: ${env.GIT_BRANCH} *Build* : `not OK` *Published* = `no`'
""")
}
}
}
Where:
- The line starting with withCredentials declares variables for substitution in the request.
- The text is sent in markdown format.
We initiate the build and, upon success, receive a notification:
