How to Generate a Scheduled Daily Operations Digest Email with AI
Build a Spojit workflow that wakes up every morning, gathers yesterday's Shopify orders, Slack support volume, and MySQL business metrics in parallel, has an AI agent write a clean structured digest, and emails it to your team with the Send Email node.
What This Integration Does
Operations leaders usually start the day stitching together numbers from three or four systems: how many orders came in overnight, how busy the support channel was, and what the headline numbers look like in the reporting database. This workflow does that gathering for you on a cron schedule, then hands the raw figures to an AI agent that turns them into a short, readable digest and emails it before anyone logs in. Instead of opening Shopify, Slack, and a database every morning, your team gets one message that already tells the story.
The run model is simple and self-contained. A Schedule trigger fires on a morning cron in your timezone, producing a {{ scheduledAt }} timestamp. A Parallel node fans out into three branches that pull yesterday's data concurrently from Shopify, Slack, and MySQL. Those results converge on a Connector node running in Agent mode, which composes the digest text. A Send Email node delivers it. The workflow holds no state between runs: each execution reads a fresh date window, builds a fresh digest, and stops. If a run is skipped or fails, the next morning's run simply reports on its own day, so there is nothing to clean up or replay.
Prerequisites
- A Shopify connection with permission to read orders (used by
list-ordersandget-shop). - A Slack connection that can read your support channel history (used by
get-channel-history), plus the channel ID of the support channel. - A MySQL connection to your reporting database, with the table and column names you want to summarize.
- An AI model available in your workspace for the Agent-mode Connector node that drafts the digest.
- Each recipient of the digest must be on your organization allowlist under Settings → General → Email recipients so the Send Email node can deliver to them.
- The IANA timezone your team works in (for example
Australia/Sydney) so the schedule and date windows line up.
Step 1: Add a Schedule trigger for the morning run
On the canvas, set the Trigger type to Schedule. Add a 5-field Unix cron expression and an IANA timezone. To run at 7:00 AM on weekdays, use:
0 7 * * 1-5
Set the timezone field to your operating region, for example Australia/Sydney. A single Schedule trigger can hold more than one cron entry, so you could add a second weekend expression later if you want a 7-day digest. The trigger output is {{ scheduledAt }}, an ISO timestamp of the moment the run started, which you will use to compute "yesterday".
Step 2: Compute yesterday's date window
Add a Connector node using the built-in date connector in Direct mode. Use the subtract tool to step back one day from {{ scheduledAt }}, then the start-of and end-of tools (or format) to produce the boundaries of yesterday in your timezone. Capture the start and end as variables you can reference downstream, for example {{ window.start }} and {{ window.end }}. Having an explicit window means every branch reports on exactly the same 24 hours, regardless of when the run actually fired.
start: 2026-06-19T00:00:00+10:00
end: 2026-06-19T23:59:59+10:00
Step 3: Fan out with a Parallel node to gather data
Add a Parallel node after the date step and create three branches. Running them concurrently means the digest is ready in about the time of the slowest single call rather than the sum of all three.
Branch A - Shopify orders. Add a Connector node for Shopify in Direct mode and pick the list-orders tool. Filter to yesterday using your computed window (created-at on or after {{ window.start }} and on or before {{ window.end }}). Optionally add a get-shop call so the digest can name the store. Save the result as {{ orders }}.
Branch B - Slack support volume. Add a Connector node for Slack in Direct mode and pick get-channel-history. Point it at your support channel ID and bound it to yesterday's window. The message list gives you a rough support-volume figure (a count of messages, or threads). Save the result as {{ support }}.
Branch C - MySQL key metrics. Add a Connector node for MySQL in Direct mode and pick execute-query. Run a read-only aggregate over your reporting table for the same window:
SELECT
COUNT(*) AS order_count,
SUM(total) AS revenue,
AVG(total) AS avg_order_value
FROM orders
WHERE created_at >= '{{ window.start }}'
AND created_at <= '{{ window.end }}';
Save the result as {{ metrics }}. The three branches join automatically when the Parallel node completes.
Step 4: Draft the digest with an Agent-mode Connector node
Add a Connector node and switch it to Agent mode. Agent mode lets the AI agent read all three result sets and reason about them into prose, which is exactly the judgment task you want here. Write a prompt that hands it the data and asks for a structured digest, referencing your variables:
Write a daily operations digest for {{ scheduledAt }}.
Use these inputs:
- Orders (Shopify): {{ orders }}
- Support activity (Slack): {{ support }}
- Key metrics (MySQL): {{ metrics }}
Produce three short sections: Orders, Support, Metrics.
Lead with a one-line headline summary. Call out anything
notable (a spike or drop versus a normal day). Keep it under
200 words, plain text, no markdown headings.
To make the output predictable enough to drop straight into an email, you can attach a Response Schema so the agent returns structured JSON (for example a headline string and a body string), then reference those fields in the next step. Save the result as {{ digest }}. This is the only step that uses AI credits; the gathering steps are deterministic Direct-mode calls. Miraxa, the intelligent layer across your automation, can scaffold this whole node for you if you describe the digest you want in the chat panel, then you fine-tune the prompt in the properties panel.
Step 5: Send the digest with the Send Email node
Add a Send Email node. It sends from Spojit's built-in mail service, so no connection is required. Configure:
- Recipients: your operations list, comma-separated, for example
ops@yourco.com, founders@yourco.com. All external recipients must be on the org allowlist. - Subject: templated, for example
Daily Ops Digest - {{ scheduledAt }}(or reference{{ digest.headline }}if you used a Response Schema). - Body: the digest text, for example
{{ digest.body }}or{{ digest }}. - If sending fails: choose Fail the workflow so a delivery problem is visible in your execution history rather than silently swallowed.
If you would rather send from your own domain instead of Spojit's mail service, swap this node for a Connector node using the Resend or SMTP connector and its send-email tool.
Step 6: Optionally post a short version to Slack
If your team lives in Slack, add one more Connector node for Slack in Direct mode using send-message, posting the headline line of {{ digest }} to a leadership channel. This gives you the same digest in two places without re-running any of the data gathering, since both the email and the Slack message read the one {{ digest }} variable.
Tips
- Keep the heavy lifting in Direct mode and reserve Agent mode for the single drafting step. That keeps AI credit usage low and the data figures exact.
- Use a Response Schema on the Agent node so the email body is always shaped the same way and never includes stray formatting.
- If Slack history is paginated, request only what you need for a count; you are after volume, not the full transcript.
- Add a second cron entry to the same Schedule trigger if you later want a weekend or end-of-day variant rather than building a separate workflow.
Common Pitfalls
- Timezone drift. If the cron timezone and the date-window timezone differ, "yesterday" can land on the wrong calendar day. Set the same IANA timezone in both the Schedule trigger and the date connector calls.
- Unbounded queries. Always bound the MySQL
execute-queryand Shopifylist-orderscalls to the computed window. An open-ended query can pull far more than a single day and slow the run. - Recipients not allowlisted. The Send Email node will not deliver to addresses missing from Settings → General → Email recipients. Add every recipient before turning the schedule on.
- Empty days. On a quiet day a branch may return no rows. Make the agent prompt explicit about reporting zeros gracefully so the digest still reads cleanly.
Testing
Before enabling the schedule, validate the workflow against a known day. Temporarily hard-code yesterday's window into the date step (or override {{ scheduledAt }}) and use the Run button to execute once. Check the execution history: confirm each Parallel branch returned data, open the Agent node output to read the drafted digest, and verify the Send Email node delivered to a single test recipient you control. Once the figures match what you see directly in Shopify, Slack, and your database, point the recipients at the real distribution list and enable the Schedule trigger.