Skip to content

Action reference

Input Required Default Description
bot_token yes — Telegram bot token (use a repository secret).
chat_id yes — Target chat: an integer id (possibly negative) or @channelusername. Exactly one chat — the comma-separated form accepted by v1.5 was removed in v2. To notify several chats, use a job matrix or repeat the step.
status yes — Job status to report. Must be passed explicitly from the workflow, typically from the job.status or needs..result expression. Allowed values: success, failure, cancelled, skipped. Cannot be defaulted here — composite-action input defaults do not have access to the job context.
parse_mode no MarkdownV2 Telegram parse_mode: MarkdownV2 (default), HTML, Markdown, or none.
notify_on no success,failure,cancelled Comma-separated list of statuses that should trigger a notification. any or all means every status.
message no — Verbatim message text. Overrides every template. No placeholder substitution and no escaping are applied.
message_template no — Template string with {{.Field}} placeholders, used for all statuses not overridden by template_.
template_success no — Template used when status=success. Overrides message_template.
template_failure no — Template used when status=failure. Overrides message_template.
template_cancelled no — Template used when status=cancelled. Overrides message_template.
template_skipped no — Template used when status=skipped. Overrides message_template.
disable_web_page_preview no true Suppress link previews. Sent as link_preview_options.is_disabled; the flat field Telegram deprecated is no longer used.
disable_notification no false Send the message silently (no sound for recipients).
message_thread_id no — Forum-chat thread (topic) ID. Integer.
fail_on_error no false If true, the action exits non-zero when the Telegram request ultimately fails. Default false keeps the job result intact.
edit_message_id no — If set, the message is edited via editMessageText instead of sent fresh. One integer, typically wired from the message_id output of an earlier notiflow step. disable_notification and message_thread_id are dropped when editing, because Telegram rejects them there.
version no — notiflow release to install. Empty pins to the version stamped in the Action tree; “latest” resolves the newest release at run time.
verify_signature no false Verify the release archive with cosign before installing. Requires sigstore/cosign-installer earlier in the job.
github_token no ${{ github.token }} Token used to call the GitHub Releases API when resolving “latest”.
Output Description
ok true when the message was delivered, false otherwise.
message_id Telegram message_id on success, empty otherwise. A single value — v1 returned a comma-separated list for multi-chat sends.
http_status HTTP status of the last attempt (0 when skipped or when no response arrived).
error Failure reason — Telegram .description when available, otherwise a synthesized reason. Empty on success and on skip.

Required, with no default. Composite-action manifests evaluate ${{ }} expressions when the manifest loads, before any job context exists, so default: ${{ job.status }} would abort the whole workflow with Unrecognized named-value: 'job'. Pass it from the caller: ${{ job.status }} inside the job, ${{ needs.<job>.result }} from another one.

One chat. An integer id — negative for groups and supergroups — or @channelusername between 4 and 32 word characters. A comma is rejected with exit code 11; see the migration guide.

MarkdownV2 (default), HTML, or none. Markdown is accepted as an alias for MarkdownV2 and logs a warning: notiflow escapes substituted values per V2 rules, and sending those to Telegram’s legacy parser produces broken or rejected messages.

The input name is unchanged from v1, but the wire representation moved to link_preview_options.is_disabled, because Telegram deprecated the flat field.

Turns the call into editMessageText. disable_notification and message_thread_id are dropped when editing — Telegram rejects them there, and passing them through would turn a working configuration into a 400.

false by default. A failed notification does not overwrite the result your job actually produced; set it to true when delivery is part of the contract.

The wrapper maps every input into an NF_* variable and hands it to the binary. Two more are read directly, and both are constrained inside a workflow:

Variable Meaning
NF_API_BASE Bot API base URL. Inside Actions only https://api.telegram.org and loopback are honoured — anything else is ignored with a warning, so a variable planted by an earlier step in the same job cannot redirect your token.
NF_BIN Path to the binary, for testing the wrapper against a local build.

From the CLI, --api-base accepts any http(s) URL: a self-hosted Bot API server is a legitimate setup and there the value is the user’s own explicit choice.