Skip to content

Getting started

A Telegram bot token and a chat id. If you have neither:

  1. Message @BotFather, send /newbot, and keep the token it gives you. It looks like 123456789:AAHdqTcv....
  2. Add the bot to the target chat or channel. For a channel it must be an administrator.
  3. Find the chat id. The simplest way is to send one message in the chat and read it back:
Terminal window
curl -s "https://api.telegram.org/bot<TOKEN>/getUpdates" | grep -o '"chat":{"id":[-0-9]*'

Group and supergroup ids are negative and usually start with -100. A public channel can also be addressed as @channelusername.

Check that the token works before wiring anything up:

Terminal window
NOTIFLOW_BOT_TOKEN=<TOKEN> notiflow whoami
# Notiflow (@notiflow_bot, id=123456789)

Store the token and the chat id as repository secrets, then add one step at the end of the job you care about:

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- run: make test
- uses: jtprogru/notiflow@v2
if: always()
with:
bot_token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
chat_id: ${{ secrets.TELEGRAM_CHAT_ID }}
status: ${{ job.status }}

if: always() matters: without it the step is skipped when the job fails, which is precisely when you wanted to hear about it.

status has to be passed explicitly. A composite action’s input defaults cannot read the job context, so notiflow cannot fill it in for you.

By default you get a message on success, failure and cancelled, formatted with the built-in template. To be told only about failures:

with:
bot_token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
chat_id: ${{ secrets.TELEGRAM_CHAT_ID }}
status: ${{ job.status }}
notify_on: failure
Terminal window
brew install jtprogru/tap/notiflow # or: cargo install notiflow
export NOTIFLOW_BOT_TOKEN=123456789:AAHdqTcv...
export NOTIFLOW_CHAT_ID=-1001234567890
notiflow send --message "deploy finished"

Anything on stdin becomes the message, which makes notiflow a drop-in end to a pipeline:

Terminal window
./deploy.sh 2>&1 | tail -20 | notiflow send --stdin

Templates work outside Actions too — repository, branch and commit come from the local git checkout when the GITHUB_* variables are absent:

Terminal window
notiflow send --template '{{.StatusEmoji}} deployed `{{.ShortSha}}` from {{.Branch}}'

To see what a template produces without sending anything:

Terminal window
notiflow render --template '{{.Repo}} @ {{.ShortSha}}' --explain