Back to Articles How-to

How to Send Notifications from GitHub Actions to Telegram, Discord, or Slack

Julio Andres April 12, 2026 6 min read CI/CD · GitHub Actions · DevOps

GitHub Actions tells you a workflow failed by putting a red X next to a commit. If you're not staring at the repo page, you won't notice until someone asks why the deploy didn't go out. GitHub can send email notifications, but those get lost in the noise fast — especially if you have multiple repos with active workflows.

A better approach: get a Telegram message on your phone, a Discord ping in your team server, or a Slack alert in your dev channel the moment a workflow fails. Here's how to set that up, from a quick platform-specific approach to a cleaner solution that works across all three.

Option 1: Platform-Specific Webhooks (The Quick Way)

Each platform has its own webhook format. For Discord, you create a webhook URL in your channel settings and POST to it. For Slack, you set up an Incoming Webhook app. For Telegram, you call the Bot API directly.

Here's what a Discord webhook step looks like in a GitHub Actions workflow:

GitHub Actions — Discord webhook
name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Deploy to production
        run: ./scripts/deploy.sh

      - name: Notify on failure
        if: failure()
        run: |
          curl -s -X POST "$DISCORD_WEBHOOK_URL" \
            -H "Content-Type: application/json" \
            -d "{
              \"content\": \"Deploy failed on \`${{ github.repository }}\` — commit ${{ github.sha }}\"
            }"
        env:
          DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}

This works for one platform in one repo. But the problems show up quickly:

For a single repo with one platform, webhooks are fine. For a team with multiple repos and people on different platforms, it becomes a mess of duplicated YAML and secrets.

Option 2: A Notification API (The Cleaner Way)

Instead of calling each platform's API directly, you send the alert to a single notification endpoint. With NotificationsBot, one API call can reach Telegram, Discord, and Slack — whoever is subscribed to that channel. The same cURL command, the same payload format, every time.

GitHub Actions — NotificationsBot
name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Deploy to production
        run: ./scripts/deploy.sh

      - name: Notify on failure
        if: failure()
        run: |
          curl -s -X POST https://api.notificationsbot.com/event \
            -H "Authorization: Bearer $NOTIFICATIONSBOT_API_KEY" \
            -H "Content-Type: application/json" \
            -d "{
              \"channel\": \"deploys\",
              \"title\": \"Deploy failed\",
              \"message\": \"${{ github.repository }} — commit ${{ github.sha }}\"
            }"
        env:
          NOTIFICATIONSBOT_API_KEY: ${{ secrets.NOTIFICATIONSBOT_API_KEY }}

One API key across all your repos. One payload format. If you want to add a new team member on Telegram, you add them in the dashboard — no YAML changes, no new secrets.

The key difference

With platform-specific webhooks, your CI pipeline is coupled to a delivery platform. With a notification API, your pipeline just reports what happened — who gets notified and on which platform is managed separately. You can add subscribers, switch platforms, or split alerts into different channels without editing a single workflow file.

Setting Up CI/CD Alerts with NotificationsBot

If you don't have an account yet, the setup takes about 5 minutes:

From here, any event sent to your channel reaches whoever is subscribed. You can add more people later — different team members, different platforms — without changing your workflows.

Alert on Failure Only

The most common pattern is alerting only when something goes wrong. GitHub Actions has a built-in failure() condition that makes this easy:

Only on failure
      - name: Notify on failure
        if: failure()
        run: |
          curl -s -X POST https://api.notificationsbot.com/event \
            -H "Authorization: Bearer $NOTIFICATIONSBOT_API_KEY" \
            -H "Content-Type: application/json" \
            -d "{
              \"channel\": \"ci-alerts\",
              \"title\": \"CI failed: ${{ github.repository }}\",
              \"message\": \"Branch: ${{ github.ref_name }}\nCommit: ${{ github.sha }}\nAuthor: ${{ github.actor }}\"
            }"
        env:
          NOTIFICATIONSBOT_API_KEY: ${{ secrets.NOTIFICATIONSBOT_API_KEY }}

This step runs only if a previous step in the job failed. It includes the repo name, branch, commit hash, and who pushed — enough context to know what broke without opening GitHub.

Alert on Success and Failure

For deploy workflows, you might want to know when a deploy succeeds too — especially if it takes a few minutes and you're waiting on it. Use the always() condition and include the job status:

On both success and failure
      - name: Notify deploy result
        if: always()
        run: |
          if [ "${{ job.status }}" == "success" ]; then
            TITLE="Deploy succeeded"
          else
            TITLE="Deploy failed"
          fi

          curl -s -X POST https://api.notificationsbot.com/event \
            -H "Authorization: Bearer $NOTIFICATIONSBOT_API_KEY" \
            -H "Content-Type: application/json" \
            -d "{
              \"channel\": \"deploys\",
              \"title\": \"$TITLE\",
              \"message\": \"${{ github.repository }} — ${{ github.ref_name }}\nby ${{ github.actor }}\"
            }"
        env:
          NOTIFICATIONSBOT_API_KEY: ${{ secrets.NOTIFICATIONSBOT_API_KEY }}
Good to know

Use if: failure() for test and build workflows — you only care when they break. Use if: always() for deploy workflows — knowing that a deploy finished successfully is just as useful as knowing it failed.

Reusable Workflow for Multiple Repos

If you have multiple repos that should all send notifications, you can extract the notification step into a reusable workflow. Define it once, call it from any repo:

.github/workflows/notify.yml — reusable workflow
name: Notify
on:
  workflow_call:
    inputs:
      channel:
        required: true
        type: string
      title:
        required: true
        type: string
      message:
        required: true
        type: string
    secrets:
      NOTIFICATIONSBOT_API_KEY:
        required: true

jobs:
  notify:
    runs-on: ubuntu-latest
    steps:
      - name: Send notification
        run: |
          curl -s -X POST https://api.notificationsbot.com/event \
            -H "Authorization: Bearer $NOTIFICATIONSBOT_API_KEY" \
            -H "Content-Type: application/json" \
            -d "{
              \"channel\": \"${{ inputs.channel }}\",
              \"title\": \"${{ inputs.title }}\",
              \"message\": \"${{ inputs.message }}\"
            }"
        env:
          NOTIFICATIONSBOT_API_KEY: ${{ secrets.NOTIFICATIONSBOT_API_KEY }}

Then call it from any workflow:

Calling the reusable workflow
  notify:
    if: failure()
    needs: deploy
    uses: your-org/shared-workflows/.github/workflows/notify.yml@main
    with:
      channel: deploys
      title: Deploy failed
      message: ${{ github.repository }} — ${{ github.ref_name }}
    secrets:
      NOTIFICATIONSBOT_API_KEY: ${{ secrets.NOTIFICATIONSBOT_API_KEY }}

Platform Webhooks vs NotificationsBot

Bonus: Separate Channels for Tests and Deploys

A common setup for teams is having two notification channels: one for CI failures (test/lint/build) and one for deploy results. The CI channel goes to a Slack channel where the whole team can see what's broken. The deploy channel sends a Telegram ping to the person responsible for releases.

With NotificationsBot, this is just two channels with different subscribers. Your test workflow sends to ci-alerts, your deploy workflow sends to deploys. Each channel has its own set of subscribers on whatever platform they prefer. No workflow changes needed when people join or leave the team.

Get Your First CI/CD Alert in 5 Minutes

Create a free account, add a subscriber on Telegram, Discord, or Slack, and wire up your first GitHub Actions notification.

Start for free

Related Articles