How to Get a Daily AI Briefing on MarketMan Waste Events

Build a Spojit workflow that pulls yesterday's MarketMan waste events every morning, uses an AI agent to group them by reason and cost, and posts a clean daily waste briefing to a Slack channel.

What This Integration Does

Waste is one of the quietest costs in a restaurant. MarketMan records each waste event as it happens, but nobody on the floor opens the dashboard at 6am to add it all up. This workflow does that work for you: once a day it reads the previous day's waste events from MarketMan, lets an AI agent total the dollars and rank the biggest offenders by reason, and drops a short, readable briefing into the Slack channel your kitchen managers already watch. Instead of a raw export, the team sees "$284 wasted yesterday, mostly spoilage on produce" before the first prep shift starts.

The workflow runs on a Schedule trigger, so no one has to start it. Each morning it computes the previous day's date window, calls MarketMan's get-waste-events tool for that window, hands the events to an AI agent in Agent mode that returns a fixed JSON shape via a Response Schema, formats that JSON into a message, and posts it to Slack with send-message. It writes nothing back to MarketMan and leaves no state behind, so a re-run for the same day simply produces the same briefing again and posts it again. That makes it safe to re-run by hand while you are tuning the prompt.

Prerequisites

  • A MarketMan connection added under Connections in Spojit, authorised for the buyer account whose waste you want to report on.
  • A Slack connection with permission to post to your target channel, plus the channel ID or name (for example #kitchen-ops).
  • The buyer's GUID if your MarketMan login has access to more than one buyer account. With a single account you can leave it blank and the default is used.
  • Access to the Workflow Designer and enough AI credits in your workspace, since Agent mode consumes credits per run.

Step 1: Add a Schedule trigger

Start a new workflow and set the Trigger node type to Schedule. A Schedule trigger uses a 5-field Unix cron expression and an IANA timezone. To run at 6am every day in Sydney, use:

0 6 * * *
Australia/Sydney

Set the timezone to the one your venue operates in so the "previous day" window lines up with your trading day, not UTC. The trigger output is { scheduledAt }, which you can reference downstream as {{ scheduledAt }} if you want to stamp the briefing with its run time.

Step 2: Compute yesterday's date window

MarketMan's waste tool expects a start and end timestamp in yyyy/mm/dd hh:mm:ss format. Add a Connector node in Direct mode using the date utility connector to build that window. First call subtract to take one day off the run time, then format to render the start and end of that day.

A reliable approach is to format the previous day's start as 2024/01/15 00:00:00 and its end as 2024/01/15 23:59:59. Capture them as {{ window.from }} and {{ window.to }}. If you prefer to scaffold this quickly, ask Miraxa, the intelligent layer across your automation, to "add a date Connector node that produces yesterday's start and end timestamps in yyyy/mm/dd hh:mm:ss format" and then fine-tune the field mapping in the properties panel.

Step 3: Fetch the waste events from MarketMan

Add a Connector node in Direct mode, choose the MarketMan connector, and select the get-waste-events tool. Map its inputs:

  • dateTimeFromUTC{{ window.from }}
  • dateTimeToUTC{{ window.to }}
  • buyerGuid → leave blank for the default buyer, or set the GUID of the account you are reporting on.

Store the result as {{ waste }}. This returns the raw list of waste events for that window, each typically carrying the wasted item, a reason, a quantity, and a cost. Direct mode keeps this step deterministic and free of AI cost, which matters because this is the call that runs every single day.

Step 4: Summarise with an AI agent and a Response Schema

Add a Connector node and switch it to Agent mode. Agent mode lets an AI agent reason over the waste list and return structured output you can trust. Pass {{ waste }} into the prompt and define a Response Schema so the agent always answers in the same JSON shape rather than free prose.

Use a prompt along these lines:

You are preparing a daily kitchen waste briefing.
Here are yesterday's MarketMan waste events:
{{ waste }}

Total the cost of all waste. Group the events by reason
(for example spoilage, prep error, expired, over-portioning),
and within each reason report the total cost and the top items.
Be concise and factual. Use the venue's currency as recorded.

Set a Response Schema so the output is predictable:

{
  "type": "object",
  "properties": {
    "totalCost": { "type": "number" },
    "currency": { "type": "string" },
    "eventCount": { "type": "integer" },
    "byReason": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "reason": { "type": "string" },
          "cost": { "type": "number" },
          "topItems": { "type": "array", "items": { "type": "string" } }
        }
      }
    },
    "headline": { "type": "string" }
  }
}

Store the agent output as {{ briefing }}. Because the schema is fixed, downstream steps can rely on fields like {{ briefing.totalCost }} and {{ briefing.byReason }} existing.

Step 5: Format the Slack message

Add a Transform node to turn the structured briefing into a readable Slack message. Build a string that leads with the headline and total, then lists each reason and its cost. For example, produce text like:

:wastebasket: Daily Waste Briefing - {{ scheduledAt }}
{{ briefing.headline }}
Total wasted: {{ briefing.totalCost }} {{ briefing.currency }} across {{ briefing.eventCount }} events

Then iterate over {{ briefing.byReason }} to append one line per reason with its cost and top items. Save the finished text as {{ message }}. Keeping formatting in a Transform node, rather than in the Slack step, makes the message easy to tweak without touching the connector mapping.

Step 6: Post the briefing to Slack

Add a Connector node in Direct mode, choose the Slack connector, and select the send-message tool. Map the channel to your target (for example #kitchen-ops or its channel ID) and the message text to {{ message }}. On completion you have a daily waste briefing waiting for the team before service.

If you would rather email the briefing as well, add a Send Email node after this step. It sends from Spojit's built-in mail service, so no extra connection is needed, and you can template the same {{ message }} into the body. External recipients must be on your org's allowlist under Settings → General → Email recipients.

Tips

  • Set the Schedule timezone to your venue's local time so "yesterday" matches your trading day. A workflow scheduled in UTC will report the wrong day for kitchens in Sydney or Auckland.
  • Keep the MarketMan fetch in Direct mode and reserve Agent mode for the single summarisation step. That keeps your daily AI credit spend to one call per run.
  • If your kitchen runs late, end the window at 23:59:59 rather than midnight so you never clip events recorded just before close.
  • Use Slack emoji and short lines: kitchen managers read this on a phone between prep tasks, so a tight headline plus a few reason lines lands better than a full table.

Common Pitfalls

  • Timezone drift: if the date window is computed in UTC but your venue runs on local time, a 6am run can report events from the wrong calendar day. Compute the window and the schedule in the same timezone.
  • Wrong buyer account: if your MarketMan login covers several buyers, leaving buyerGuid blank reports only the default. Set the GUID explicitly when reporting on a specific venue.
  • Quiet days: on a day with zero waste, get-waste-events returns an empty list. Add a Condition node before the Slack step to skip posting (or post "No waste recorded yesterday") so the channel does not get a confusing empty briefing.
  • Unstructured AI output: without a Response Schema, the agent may return prose that your Transform node cannot parse reliably. Always define the schema so fields like {{ briefing.byReason }} are guaranteed.

Testing

Before relying on the schedule, run the workflow by hand. Temporarily point the date window at a recent day you know had waste recorded, then use the Run button and watch the execution. Confirm the MarketMan step returns events, check that {{ briefing }} came back in the expected shape, and verify the Slack message reads cleanly in a test channel before pointing it at #kitchen-ops. Once the output looks right for a known day, restore the dynamic "yesterday" window and let the Schedule trigger take over. You can ask Miraxa "why did my last run fail?" if any step errors during testing.

Learn More

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.