Triggering pipelines from Telegram
If you’ve configured notifications.telegram (see Route escalations to a
real channel), you already have
more than a one-way notification channel — the same bot also long-polls for
incoming messages and understands one command:
/run <pipeline-name> [key=value ...]No extra setup, no second bot, no new credentials. The moment
notifications.telegram.bot_token/chat_id are both set, the poller
starts automatically alongside the rest of the service.
Try it
Section titled “Try it”From the same Telegram chat your notifications already arrive in:
/run alert-triageThe bot replies immediately — “⏳ Pipeline alert-triage started (run
a1b2c3d4…) — I’ll notify you when it’s done.” — and a real run appears
in VectorStep’s UI, exactly as if you’d curl’d /webhook yourself.
Pass extra data as key=value pairs:
/run alert-triage service=payments-api environment=stagingQuoted values with spaces work too (summary="high error rate"), and the
/run@YourBotName variant Telegram appends in group chats is handled the
same as a plain /run.
Only from the configured chat
Section titled “Only from the configured chat”Commands from any chat other than notifications.telegram.chat_id are
silently ignored — this isn’t a public bot command available to whoever
finds it, only to the specific chat/group already trusted with your
notifications.
Using the extra data in a pipeline
Section titled “Using the extra data in a pipeline”Each key=value pair becomes a field in the underlying webhook’s data
dict, which lands in NormalisedContext.metadata — see Webhooks — generic
source for the full mapping.
To actually use it in a prompt, include the bare metadata key (not a
specific metadata.field subpath) in the pipeline’s context_template:
context_template: include: - metadataprompt_template: | Investigate {{metadata.service | default("the reported service")}} in {{metadata.environment | default("an unspecified environment")}}./run alert-triage service=payments-api environment=staging then renders
that as “Investigate payments-api in staging.” — /run alert-triage
alone (no extra data) falls back to the default() values instead of
rendering blank, since metadata is genuinely just an empty dict in that
case, not an error.
/run bypasses trigger.match entirely
Section titled “/run bypasses trigger.match entirely”/run always names the pipeline explicitly, and an explicit pipeline name
resolves by exact lookup — the target pipeline’s own trigger.match block
is never consulted, the same way a sub-pipeline
call
never consults the sub-pipeline’s trigger.match either. A pipeline you
only ever intend to trigger this way doesn’t need a matchable
trigger.match at all — an empty one (trigger: {match: {}}) is fine,
since it’s never evaluated on this path.
/run does not bypass stage: testing
Section titled “/run does not bypass stage: testing”Unlike the UI’s Run now button (which always sets allow_testing=true)
or a manual curl with &allow_testing=true, /run posts to
/webhook?source=generic with no override. A stage: testing pipeline is
correctly not triggered, and the bot says so honestly: “⚠️ Pipeline
alert-triage is stage: testing — not triggered. Promote it to stage: production first, or trigger it another way with
allow_testing=true.” — rather than falsely claiming a run started that
never did.
“I’ll notify you when it’s done” — only if something configured says so
Section titled ““I’ll notify you when it’s done” — only if something configured says so”Worth being precise about, since it’s easy to over-read: the bot’s own
confirmation message is a promise about this specific run, not a
guarantee VectorStep will follow up automatically. A follow-up only
actually arrives if the pipeline’s own notifications:
block reacts to an escalate/abort/stop/
notify transition — there is no “on plain success” notification hook
anywhere in the system. Trigger a healthy pipeline that simply completes,
and — correctly — nothing else arrives in the chat; you’d need to check
the UI (or the run’s own accuracy feedback) to see the outcome. If you want
a real completion message for every run regardless of outcome, add an
executor: notify step (see Notifications)
as the pipeline’s own last step instead of relying on the slash command’s
reply to tell you.
A different mechanism from approval buttons
Section titled “A different mechanism from approval buttons”The same long-poller also resolves Approve/Reject button clicks for
executor: human steps routed to Telegram — that’s a completely separate
feature (Human-in-the-loop) sharing
the same underlying connection, not something /run triggers or
interacts with.
If auth.teams is configured
Section titled “If auth.teams is configured”/run’s internal call to /webhook needs a Bearer token once your service
requires one — notifications.telegram.team names which configured team
this bot authenticates as, so runs triggered from Telegram are correctly
attributed rather than 401ing:
notifications: telegram: bot_token: ${TELEGRAM_BOT_TOKEN} chat_id: ${TELEGRAM_CHAT_ID} team: platform # must match a name under auth.teamsIf this series is the only thing you’ve configured, you haven’t set up
auth.teams at all, so there’s nothing to authenticate against and /run
already works unauthenticated, same as every other webhook call in the
series. See Team attribution for the full
auth.teams reference.
Where next
Section titled “Where next”- Route escalations to a real channel — the tutorial that sets up the bot this guide builds on.
- Webhooks — generic source
— the full payload schema
/runconstructs under the hood. - Notifications — the full
notifications:reference, includingexecutor: notifyfor a real completion message regardless of outcome. - Human-in-the-loop — the separate approval-button mechanism sharing the same Telegram connection.