Skip to content

Telegram PR Notify

Actions
Send Telegram notifications for GitHub Pull Request events
v1.1.0
Latest
Star (5)

Telegram PR Notify

A GitHub Action that sends Telegram notifications for Pull Request events. Built with Go, zero external dependencies.

Features

  • Notifications for PR opens, closes, merges, reopens, updates, and draft changes
  • Review notifications (approved, changes requested, commented)
  • Review comment notifications
  • Customizable message templates using Go html/template syntax
  • Telegram forum/topic support
  • Inline keyboard buttons linking to the PR/review/comment and linked issues
  • Minimal Docker image (distroless)

Inputs

Input Required Default Description
bot_token Yes - Telegram Bot API token
chat_id Yes - Telegram chat ID
topic_id No "" Telegram forum topic/thread ID
custom_template No "" Go template string to override default message
event_payload No ${{ toJSON(github) }} GitHub context JSON payload. Automatically populated by GitHub Actions. For the payload schema, see GitHub Actions context documentation. Override only for testing.

Supported Events

Event Actions
pull_request opened, closed (merged detection), reopened, synchronize, ready_for_review, converted_to_draft
pull_request_review submitted (approved, changes_requested, commented)
pull_request_review_comment created

Note: The pull_request_review event only has the submitted action type. To filter by review state (e.g., only approvals), add a condition to your workflow step:

- uses: andoniaf/telegram-pr-notify@v1
  if: github.event.review.state == 'approved'
  with:
    bot_token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
    chat_id: ${{ secrets.TELEGRAM_CHAT_ID }}

Linked Issue Buttons

When a PR body contains issue references using GitHub closing keywords or refs, the notification includes an extra inline button for each linked issue:

Keyword Example
close, closes, closed Closes #42
fix, fixes, fixed Fixes #7
resolve, resolves, resolved Resolves #15
ref, refs Refs #113

The colon variant is also supported (e.g., Closes: #10). Only same-repo references (#N) are detected.

Usage Examples

All PR Events

name: PR Notifications
on:
  pull_request:
    types: [opened, closed, reopened, synchronize, ready_for_review, converted_to_draft]
  pull_request_review:
    types: [submitted]
  pull_request_review_comment:
    types: [created]

jobs:
  notify:
    runs-on: ubuntu-latest
    steps:
      - uses: andoniaf/telegram-pr-notify@v1
        with:
          bot_token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
          chat_id: ${{ secrets.TELEGRAM_CHAT_ID }}

Only New PRs (with Topic Support)

name: New PR Notifications
on:
  pull_request:
    types: [opened]

jobs:
  notify:
    runs-on: ubuntu-latest
    steps:
      - uses: andoniaf/telegram-pr-notify@v1
        with:
          bot_token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
          chat_id: ${{ secrets.TELEGRAM_CHAT_ID }}
          topic_id: "12345"

PRs + Reviews with Custom Template

name: PR + Review Notifications
on:
  pull_request:
    types: [opened, closed]
  pull_request_review:
    types: [submitted]

jobs:
  notify:
    runs-on: ubuntu-latest
    steps:
      - uses: andoniaf/telegram-pr-notify@v1
        with:
          bot_token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
          chat_id: ${{ secrets.TELEGRAM_CHAT_ID }}
          custom_template: |
            [{{.Repo.FullName}}] {{.Actor.Login}}: {{.Action}} PR #{{.PR.Number}} {{.PR.Title}}

Common Workflow Patterns

Only notify for PRs targeting main

on:
  pull_request:
    types: [opened, closed]
    branches: [main]

Skip draft PRs

- uses: andoniaf/telegram-pr-notify@v1
  if: github.event.pull_request.draft == false
  with:
    bot_token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
    chat_id: ${{ secrets.TELEGRAM_CHAT_ID }}

Skip bot PRs (e.g., Dependabot)

- uses: andoniaf/telegram-pr-notify@v1
  if: github.actor != 'dependabot[bot]'
  with:
    bot_token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
    chat_id: ${{ secrets.TELEGRAM_CHAT_ID }}

Different templates per event type

jobs:
  notify-pr:
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    steps:
      - uses: andoniaf/telegram-pr-notify@v1
        with:
          bot_token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
          chat_id: ${{ secrets.TELEGRAM_CHAT_ID }}
          custom_template: "PR {{.Action}}: #{{.PR.Number}} {{.PR.Title}}"
  notify-review:
    if: github.event_name == 'pull_request_review'
    runs-on: ubuntu-latest
    steps:
      - uses: andoniaf/telegram-pr-notify@v1
        with:
          bot_token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
          chat_id: ${{ secrets.TELEGRAM_CHAT_ID }}
          custom_template: "Review {{.Review.State}} on #{{.PR.Number}}"

Custom Templates

Templates use Go html/template syntax. Since html/template is used, user-generated content (PR titles, usernames, etc.) is automatically HTML-escaped for safe use in Telegram HTML messages.

Security: The custom_template input should only contain trusted input defined by the workflow author. Do not pass user-controlled data (e.g., PR body, branch names) into the template string itself. Note that PR.Body may contain sensitive content submitted by external contributors; use {{truncate .PR.Body N}} to limit its length and avoid leaking large amounts of text into notifications.

Available Fields

Variable Type Description
{{.EventName}} string GitHub event name (pull_request, pull_request_review, pull_request_review_comment)
{{.Action}} string Event action (opened, closed, submitted, etc.)
{{.Actor.Login}} string User who triggered the event
{{.Actor.HTMLURL}} string URL to the actor's profile
{{.Repo.FullName}} string Repository full name (e.g., owner/repo)
{{.Repo.HTMLURL}} string URL to the repository
{{.PR.Number}} int Pull request number
{{.PR.Title}} string Pull request title
{{.PR.HTMLURL}} string URL to the pull request
{{.PR.Body}} string Pull request body/description
{{.PR.Draft}} bool Whether the PR is a draft
{{.PR.Merged}} bool Whether the PR was merged
{{.PR.Head.Ref}} string Source branch name
{{.PR.Base.Ref}} string Target branch name
{{.Review.State}} string Review state (approved, changes_requested, commented)
{{.Review.Body}} string Review body text
{{.Comment.Body}} string Review comment body text
{{.Comment.Path}} string File path of the review comment

Available Methods

Method Returns Description
{{.IsMerged}} bool true when a pull_request / closed event has PR.Merged == true

Template Functions

Function Description
{{truncate .Field 100}} Truncate a string to a maximum length, appending ... if truncated

Conditional Examples

Merged vs. closed:

custom_template: |
  {{if .IsMerged}}Merged{{else if eq .Action "closed"}}Closed{{else}}{{.Action}}{{end}} PR #{{.PR.Number}} {{.PR.Title}}

Include review body only when present:

custom_template: |
  Review on #{{.PR.Number}}: {{.Review.State}}
  {{- if .Review.Body}}
  Comment: {{truncate .Review.Body 200}}
  {{- end}}

Default Template Example

The default template for a new PR looks like this:

<emoji> <b>New Pull Request</b>
<a href="{{.PR.HTMLURL}}">#{{.PR.Number}}</a> {{.PR.Title}}
{{.PR.Head.Ref}} -> {{.PR.Base.Ref}}

by <a href="{{.Actor.HTMLURL}}">{{.Actor.Login}}</a> in <b>{{.Repo.FullName}}</b>

See pkg/templates/defaults.go for all default templates.

Setup

1. Create a Telegram Bot

  1. Message @BotFather on Telegram
  2. Send /newbot and follow the instructions
  3. Copy the bot token

2. Get Your Chat ID

  1. Add the bot to your group/channel
  2. Send a message in the group
  3. Visit https://api.telegram.org/bot<YOUR_TOKEN>/getUpdates
  4. Find the chat.id field in the response

Note: Group chat IDs are negative numbers. Supergroup IDs start with -100 (e.g., -1001234567890). Private chat IDs are positive numbers. Make sure to include the full number including the minus sign.

3. Get Topic ID (Optional)

For Telegram groups with topics/forums enabled:

  1. Open the topic in Telegram Web
  2. The topic ID is in the URL: https://web.telegram.org/.../<TOPIC_ID>

4. Add Secrets

Add TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID as repository secrets.

Troubleshooting

Problem Cause Solution
telegram API error: Bad Request: chat not found Bot not added to the group, or incorrect chat_id Ensure the bot is a member of the group. Verify chat_id using the /getUpdates API (see Setup).
telegram API error: Bad Request: message thread not found topic_id does not exist or topics are not enabled Verify the topic exists and that the group has topics/forums enabled.
telegram API error: Forbidden: bot was blocked by the user Bot lacks permissions or was removed Re-add the bot to the group and ensure it has permission to send messages.
parsing template: ... error Invalid Go template syntax in custom_template Check your template syntax against the Go template docs. Common issues: unmatched {{, missing closing {{end}}, referencing non-existent fields.
unsupported event: <name> Workflow triggers an event this action does not handle Only pull_request, pull_request_review, and pull_request_review_comment events are supported.
no template for event <name> action <action> Valid event but unrecognized action Check the Supported Events table. Ensure your workflow types filter matches supported actions.

Versioning

This action follows semantic versioning. Use a major version tag for stability:

uses: andoniaf/telegram-pr-notify@v1

The v1 tag always points to the latest v1.x.x release. You can also pin to a specific version (e.g., @v1.0.0) for maximum reproducibility.

License

MIT

Telegram PR Notify is not certified by GitHub. It is provided by a third-party and is governed by separate terms of service, privacy policy, and support documentation.

About

Send Telegram notifications for GitHub Pull Request events
v1.1.0
Latest

Telegram PR Notify is not certified by GitHub. It is provided by a third-party and is governed by separate terms of service, privacy policy, and support documentation.