Publish icon
SlackIncomingWebhook icon
Webhook icon

Bridge HTTP Webhooks to MQTT Topics

Bridge HTTP webhooks to MQTT with Kestra. Forward selected webhook fields as a JSON message to a broker topic and confirm each publish in Slack.

Categories
Infrastructure

Plenty of systems can send a webhook; far fewer can speak MQTT. This blueprint turns Kestra into the translator: io.kestra.plugin.core.trigger.Webhook accepts a JSON POST from any HTTP-capable tool, and io.kestra.plugin.mqtt.Publish republishes selected body fields as a JSON message onto the broker. The target topic comes from the request body with a safe default, so one endpoint serves many event types, and Slack notes every bridged event with the resolved topic and publish count.

How it works

  1. http_event (io.kestra.plugin.core.trigger.Webhook) exposes a URL containing the webhook key; any system that can POST JSON can start the flow. Replace the placeholder key with a strong random value before sharing the URL.
  2. forward_to_mqtt (io.kestra.plugin.mqtt.Publish) connects to the broker from the MQTT_SERVER secret. The topic is {{ trigger.body.topic ?? 'bridge/events' }}, letting the sender route per event while unrouted events land on the default topic.
  3. The published payload is a curated JSON map, not a blind passthrough: event, source, and detail are lifted from the body with ?? defaults, and bridged_by plus execution_id are stamped on so subscribers can trace any message back to the exact execution that bridged it.
  4. qos: 1 gives at-least-once delivery to the broker, and the task's messagesCount output feeds the notification.
  5. notify posts the event name, resolved topic, and count to Slack; the errors block posts a distinct alert when an event was received over HTTP but failed to reach the broker, which is exactly the gap a bridge must never hide.

What you get

  • An MQTT publishing endpoint for CI pipelines, SaaS webhooks, cron jobs, and internal tools that only speak HTTP.
  • Sender-controlled routing through the topic body field, with a default that keeps malformed requests flowing.
  • A curated payload contract instead of raw body forwarding, so subscribers never parse surprise fields.
  • Per-event traceability: every bridged message carries the execution id that produced it.

Who it's for

  • IoT platform teams who need business systems to reach devices without embedding an MQTT client anywhere.
  • Integration engineers replacing a hand-rolled Flask-to-Paho bridge and its pager burden.
  • Teams standardizing event entry points: one authenticated URL in, governed topics out.

Why orchestrate this with Kestra

A bridge is infrastructure the moment two teams depend on it. Kestra gives this one authentication via the webhook key, secret management for the broker, retries on transient broker failures, an execution per event with the full request logged, and an alert when forwarding fails. The translation logic stays a few lines of YAML that review like configuration, not a service to deploy and monitor.

Prerequisites

  • An MQTT broker reachable from Kestra. Public test brokers accept anonymous connections; for authenticated brokers, add the username and password properties to the task from secrets.
  • A Slack incoming webhook for notes and failure alerts.
  • HTTP access to your Kestra instance from the sending systems.

Secrets

  • MQTT_SERVER: broker URI, e.g. tcp://broker.example.com:1883.
  • SLACK_WEBHOOK_URL: Slack incoming webhook URL.

Quick start

  1. Add the MQTT_SERVER and SLACK_WEBHOOK_URL secrets to your Kestra namespace.
  2. Replace change-me-strong-webhook-key with a strong random key.
  3. Subscribe a test client, e.g. mosquitto_sub -t 'bridge/#', then POST an event: curl -X POST https://your-kestra/api/v1/executions/webhook/company.team/mqtt-webhook-to-mqtt-bridge/YOUR_KEY -H 'Content-Type: application/json' -d '{"topic": "bridge/deploys", "event": "deploy_finished", "source": "ci", "detail": "v2.1.0"}'.
  4. Confirm the message arrives on bridge/deploys and Slack notes the bridged event.

How to extend

  • Validate the body before publishing with an If task that fails fast on missing required fields.
  • Constrain sender-controlled topics by prefixing, e.g. bridge/{{ trigger.body.topic ?? 'events' }}, so HTTP callers can never publish outside the bridge namespace.
  • Add retain: true for event types that represent state rather than occurrences, as shown in the retained config push blueprint.
  • Run the bridge in reverse with the plugin's realtime trigger to turn MQTT messages into HTTP calls.

Links

Orchestrate with Kestra
Orchestrate Slack with Kestra
Share this Blueprint
See How

New to Kestra?

Use blueprints to kickstart your first workflows.