Webhook icon
XExecution icon
SlackIncomingWebhook icon

Post an Incident Resolution Notice on X from an Ops Webhook

Close public incident comms automatically. When ops marks an incident resolved, Kestra posts the resolution notice on X and confirms in Slack.

Categories
Business

Teams are disciplined about announcing incidents and forgetful about announcing recoveries, which leaves customers staring at an open-ended status post. This blueprint makes the resolution follow-up automatic. When the ops tooling marks the incident resolved, its webhook fires the flow, and io.kestra.plugin.x.XExecution posts the resolution notice. The task is an execution notification poster, so the post always leads with the execution state and flow id, carries the resolution line from customMessage, and ends with a link to the execution, a status-page-style format that fits public incident communication. Slack receives an internal confirmation so the comms item can be checked off the incident timeline. Posts on X are public and instant, so the resolution line is assembled from the ops payload and reviewed input fallbacks, never improvised, and the 280 character cap covers the full rendered post.

How it works

  1. on_resolved (io.kestra.plugin.core.trigger.Webhook) receives a POST from the ops tooling when the incident closes, carrying service_name and resolution_summary in the JSON body.
  2. post_resolution (io.kestra.plugin.x.XExecution) authenticates with OAuth 1.0a credentials and publishes the resolution notice. The task renders its bundled execution template, so the post opens with the execution state and flow id, carries the customMessage resolution line, and closes with a link to the execution. Every dynamic fragment uses {{ trigger.body.service_name ?? inputs.service_name }} fallbacks so manual runs work during setup.
  3. confirm_internal (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) posts the confirmation and execution id to the incident channel.
  4. The errors block raises a distinct Slack alert when posting fails, because an incident that opened publicly and never closed publicly reads as still ongoing.

What you get

  • A resolution notice that goes out the moment the incident is closed internally, not whenever someone remembers.
  • Symmetry with the opening notice, the same account, tone, and status page link.
  • An internal confirmation in the incident channel, so the comms step is visible in the timeline.
  • A failure alert that distinguishes a missing public follow-up from a quiet success.

Who it's for

  • Incident commanders who own the customer communication checklist.
  • SRE teams whose retrospectives keep flagging late or missing resolution posts.
  • Support teams tired of answering questions about incidents that ended hours ago.

Why orchestrate this with Kestra

The resolution post is the easiest step to drop because it happens after the pressure is off. Wiring it to the same event that closes the incident removes the human dependency, and Kestra adds what a script cannot, secrets management for the OAuth credentials, an execution history showing exactly what was posted and when, and an errors block that guarantees a failed post is reported to the channel that cares.

Prerequisites

  • An X developer app with OAuth 1.0a user context credentials for the status account.
  • Ops tooling able to POST JSON to the webhook URL when an incident is resolved.
  • A Slack incoming webhook in the incident channel.

Secrets

  • X_CONSUMER_KEY: X app consumer key (API key).
  • X_CONSUMER_SECRET: X app consumer secret (API secret).
  • X_ACCESS_TOKEN: OAuth 1.0a access token for the posting account.
  • X_ACCESS_SECRET: OAuth 1.0a access secret for the posting account.
  • SLACK_WEBHOOK_URL: Slack incoming webhook for confirmations and failure alerts.
  • RESOLVED_WEBHOOK_KEY: secret key guarding the resolution webhook endpoint.

Quick start

  1. Add the six secrets to your Kestra namespace.
  2. Execute the flow manually with the default inputs, confirm the post appears on the X account and Slack confirms, then delete the test post.
  3. Review the copy pattern, it is public the moment the task runs.
  4. Wire the ops tooling's resolved event to the webhook URL.

How to extend

  • Pair with the incident notice blueprint so opening and closing posts share inputs and tone.
  • Add a human confirmation gate with core.execution.Fail when resolution wording needs review, as shown in the incident notice blueprint.
  • Thread the resolution under the original incident post by extending the request through the url and options properties.
  • Include downtime duration from trigger.body as a customFields entry when the ops tooling provides it, it renders as its own key-value line in the post.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.