databeginner8 min setupby Mantle

Daily spreadsheet summary by e-mail

Read a range from a Google Sheet every morning and e-mail the rows to a distribution list.

Every day 07:00Read yesterday'sSend the summary

Drag to pan, pinch to zoom. This is the real graph the template installs.

Purpose

Read a range from a Google Sheet every morning and e-mail the rows to a distribution list.

How it works

What it does

  • Runs at 07:00 every day.
  • Reads a range from a Google Sheet as objects keyed by the header row.
  • E-mails the row count and the rows to a distribution list.

Validation

This template is contract-validated: the unit suite checks every node type, every config key and the whole graph against the same rules a saved workflow passes. It has not been run against the live provider — the ids, names and columns below are placeholders to replace with your own.

Nodes 3

  1. 01Every day 07:00trigger.scheduleTrigger
  2. 02Read yesterday's rowsgoogle_sheets.readApp
  3. 03Send the summarymail.sendDestination
View template JSON
{
  "format": "mantle-workflow/v1",
  "id": "sheets-daily-summary-email",
  "name": "Daily spreadsheet summary by e-mail",
  "graph": {
    "nodes": [
      {
        "id": "cron",
        "type": "trigger.schedule",
        "label": "Every day 07:00",
        "config": {
          "cron_expr": "0 7 * * *",
          "timezone": "UTC"
        },
        "worker_type": "generic-worker",
        "position": {
          "x": 60,
          "y": 220
        }
      },
      {
        "id": "read",
        "type": "google_sheets.read",
        "label": "Read yesterday's rows",
        "config": {
          "spreadsheet_id": "1AbCdEfGhIjKlMnOpQrStUvWxYz0123456789",
          "range": "Orders!A1:F500",
          "as_objects": true
        },
        "worker_type": "generic-worker",
        "position": {
          "x": 380,
          "y": 220
        }
      },
      {
        "id": "email",
        "type": "mail.send",
        "label": "Send the summary",
        "config": {
          "to": "team@example.com",
          "subject": "Daily sheet summary — {{ $today }}",
          "body_text": "{{ steps.read.row_count }} row(s) in {{ steps.read.range }}.\n\n{{ steps.read.rows }}"
        },
        "worker_type": "generic-worker",
        "position": {
          "x": 700,
          "y": 220
        }
      }
    ],
    "edges": [
      {
        "from": "cron",
        "to": "read"
      },
      {
        "from": "read",
        "to": "email"
      }
    ]
  }
}

Requirements

The connections and permissions each step needs, from the node contracts in the catalog.

  • Google SheetsOAuth 2.0

    Used by Read yesterday's rows.

    Credential: {"client_id", "client_secret", "refresh_token"}

  • SendGridAPI key

    Used by Send the summary.

    Credential: {"api_key"} or {"username", "password"}

Setup

  • Set spreadsheet_id and range (Tab!A1:F500); the first row of the range is the header.
  • Pick a Google Sheets connection and a mail connection (SendGrid, SMTP, Gmail or Outlook all work on Send the summary).
  • Change the recipient in to and the schedule in cron_expr.

Sample input and output

Synthetic examples: node-contract samples or placeholders, never customer data.

Input

Runs on the cron schedule 0 7 * * * (UTC). There is no incoming payload: the first step fetches the data.

Output

Send the summary mail.send

{
  "body": null,
  "message_id": "",
  "provider": "",
  "sent": true,
  "status_code": 0,
  "thread_id": ""
}

Failure handling

What the graph does when a step fails, read from its retry settings, error branches and error policies.

  • A step that fails, after any retries, fails the run. The failed step is kept with its input and error.

See it run, then make it yours.

Templates install as drafts. Edit any step, and Workflow Health re-checks the graph on every save.