Query icon
IonToJson icon
Script icon
SlackIncomingWebhook icon
Schedule icon

Send a daily Odoo sales digest to Slack

Scheduled Kestra flow that summarizes the previous day's Odoo sales orders per currency and posts a JSON-safe Slack digest, with retry and alerting.

Categories
Business

Give your sales and revenue team a daily snapshot of Odoo bookings without anyone logging into the ERP. This Kestra flow reads the previous business day's confirmed Odoo sales orders, aggregates revenue per currency and identifies the top customer with a short Python step, then posts a clean Slack Block Kit digest every morning. It runs unattended with timezone-aware, backfill-safe date math, retries on transient Odoo and Slack errors, and a failure alert so a missing digest is explained rather than silently absent. Use it for automated daily sales reporting, revenue summaries, and Odoo-to-Slack notifications.

How it works

  1. A io.kestra.plugin.core.trigger.Schedule trigger (every_morning) fires at 0 7 * * * in Europe/Paris and reports the prior day. The window_date variable derives the target day from {{ trigger.date ?? execution.startDate }} so a manual replay or backfill regenerates the correct past date.
  2. query_orders (io.kestra.plugin.odoo.Query) runs a SEARCH_READ against the sale.order model, filtering on state in sale or done and date_order within the reported day, and stores the result as ION (fetchType: STORE).
  3. to_jsonl (io.kestra.plugin.serdes.json.IonToJson) converts the ION result to newline-delimited JSON so pandas can read it.
  4. build_digest (io.kestra.plugin.scripts.python.Script) loads the rows with pandas, groups revenue by currency, finds the top customer, and assembles the entire Slack Block Kit payload with json.dumps, so names with quotes or ampersands stay JSON-safe.
  5. send_digest (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) posts the pre-built payload verbatim to your channel.

What you get

  • A daily Slack digest with order count, revenue broken down per currency, and the top customer.
  • Multi-currency totals kept separate instead of summed into a meaningless single number.
  • A distinct "No confirmed orders for this day" message instead of a misleading zero.
  • A failure alert in Slack (with execution id and date) via the flow-level errors block.

Who it's for

  • Sales and RevOps teams that want a morning revenue summary without opening Odoo.
  • Finance and leadership who want a lightweight daily booking signal in Slack.
  • Data engineers automating ERP reporting on a schedule.

Why orchestrate this with Kestra

Odoo's built-in scheduled actions can run server-side cron, but they cannot reach across to Slack with retries, alert on their own failure, or replay a specific past day on demand. Kestra adds an event-driven Schedule trigger, per-task retry on transient Odoo and Slack errors, a flow-level failure alert, and backfill-safe date math so any day can be regenerated. Everything is declarative YAML, version-controlled, with full execution lineage and visible outputs for each step.

Prerequisites

  • A reachable Odoo instance with XML-RPC enabled and the Sales app installed.
  • An Odoo user allowed to read sale.order records.
  • A Slack incoming webhook URL for the target channel.

Secrets

  • ODOO_URL: Base URL of the Odoo instance, including scheme and port (for example https://erp.example.com).
  • ODOO_DB: Odoo database name to connect to.
  • ODOO_USERNAME: Odoo login used for XML-RPC authentication.
  • ODOO_PASSWORD: Password for that Odoo user.
  • SLACK_WEBHOOK: Slack incoming webhook URL used to post the digest and any failure alert.

Quick start

  1. Add the five secrets above to your namespace or tenant.
  2. Create a Slack incoming webhook and store its URL in SLACK_WEBHOOK.
  3. Set the timezone on the trigger and the Europe/Paris value in vars.window_date to your business timezone.
  4. Run the flow manually to test, then let the Schedule trigger run it each morning. To regenerate a past day's digest, start a backfill from the Triggers tab.

How to extend

  • Push aggregation into Odoo with read_group for very high order volumes instead of fetching every row.
  • Add channels per region by branching on currency before send_digest.
  • Append a weekly or monthly rollup by reusing the same query with a wider date window.
  • Swap the Slack step for email or Microsoft Teams while keeping the Python summary.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.