Publish icon
SlackIncomingWebhook icon

Dispatch Device Commands over MQTT with QoS 1 and Slack Confirmation

Dispatch JSON commands to per-device MQTT topics from a Kestra flow with QoS 1 delivery, Slack confirmation, and an audit trail for every command.

Categories
Infrastructure

Stop sending fleet commands with ad hoc mosquitto_pub calls from someone's laptop. This blueprint turns a device command into a first-class Kestra execution: the io.kestra.plugin.mqtt.Publish task builds a JSON command document from typed flow inputs, publishes it to devices/<device_id>/commands with QoS 1, and posts a Slack confirmation. Every dispatch carries the operator's inputs, a reason, and the execution id, so the question "who restarted that device and why" has an answer in the execution history instead of a shell history.

How it works

  1. Three typed inputs shape the command: device_id selects the target topic, command is constrained to a fixed verb list by a SELECT input, and reason records the justification.
  2. publish_command (io.kestra.plugin.mqtt.Publish) connects to the broker from the MQTT_SERVER secret and publishes the command as a JSON map (serdeType: JSON) to devices/{{ inputs.device_id }}/commands. qos: 1 makes the broker acknowledge delivery at least once, and the payload embeds execution_id and issued_at so the device can correlate and deduplicate.
  3. The task outputs messagesCount, the number of messages published, which flows into the confirmation.
  4. notify posts the command, target topic, publish count, and reason to Slack.
  5. The errors block posts a distinct Slack alert when the publish fails, naming the command and device that did not receive it.

What you get

  • Fleet commands as executions: every dispatch has inputs, timestamps, logs, and an outcome.
  • QoS 1 delivery instead of the fire-and-forget QoS 0 default of most CLI publishes.
  • A constrained command vocabulary via the SELECT input, so typos never reach devices.
  • A payload contract (command, reason, issued_by, execution_id, issued_at) devices can validate.

Who it's for

  • IoT platform teams replacing shell scripts and shared broker credentials with governed dispatch.
  • Operations engineers who need an audit trail for device restarts and firmware pushes.
  • Anyone building an approval or scheduling layer in front of device commands.

Why orchestrate this with Kestra

Publishing one MQTT message is easy; making it accountable is not. Kestra wraps the publish with typed inputs, secret management for the broker URI, retries on transient broker failures, a Slack paper trail, and an execution history that doubles as the command log. The same flow becomes an API endpoint, a scheduled job, or a subflow inside a larger maintenance pipeline without changing the publish task.

Prerequisites

  • An MQTT broker reachable from Kestra, e.g. a Mosquitto or EMQX instance. Public test brokers accept anonymous connections; for authenticated brokers, add the username and password properties to the task from secrets.
  • A device (or a test subscriber) listening on devices/+/commands.
  • A Slack incoming webhook for confirmations and failure alerts.

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. Subscribe a test client to devices/dev-001/commands, e.g. mosquitto_sub -t 'devices/+/commands'.
  3. Execute the flow with the default inputs and confirm the JSON command arrives and Slack reports one message published.
  4. Extend the command value list to match your device firmware's verbs.

How to extend

  • Put the flow behind io.kestra.plugin.core.trigger.Webhook so an internal tool can dispatch commands over HTTP.
  • Fan out to many devices by looping over a device list with io.kestra.plugin.core.flow.ForEach around the publish task.
  • Raise qos to 2 for exactly-once semantics where the broker and devices support it.
  • Pair with the retained config push blueprint to separate imperative commands from declarative configuration.

Links

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

New to Kestra?

Use blueprints to kickstart your first workflows.