---
name: google-sheets-daily-metrics-log
description: "Every morning: one new row in your metrics sheet with yesterday's Stripe revenue, GA4 signups and sessions, and a note on how the day compares. Use when the user asks for this, or when it runs on a schedule."
---

# Google Sheets daily metrics log

Every morning: one new row in your metrics sheet with yesterday's Stripe revenue, GA4 signups and sessions, and a note on how the day compares.

A daily metrics sheet is the cheapest dashboard there is, and it only works if someone fills in yesterday's row before coffee, every day. Miss a week and the charts built on it have a hole nobody wants to backfill.

This skill writes the row for you: revenue from Stripe, signups and sessions from Google Analytics, appended under the last row with the date in column A. It checks the date first, so a rerun never writes the same day twice, and it fills in days it missed.

## Two ways to get the data

Use the API or MCP route when you have an MCP server, a CLI or an API token for the app. Otherwise, if you can drive a browser the user is signed in to (Claude in Chrome, a Playwright or Chrome DevTools MCP server), use the browser route. Say which one you used.

## Route A: API or MCP server

### What you need

- Edit access to the spreadsheet for the agent's Google account or service account, and the spreadsheet ID.
- Read access to Stripe (a restricted key in `STRIPE_API_KEY` or the Stripe MCP server) and to the GA4 property (Viewer, through a Google Analytics MCP server or a service account).

If something is missing, say what and stop; do not invent numbers.

### Steps

1. **Total yesterday's revenue** (Stripe): List `GET /v1/charges` with `created[gte]` and `created[lt]` for yesterday in your timezone and add up `amount_captured` minus `amount_refunded` for charges with `status: succeeded`, in the account's default currency.
2. **Pull sessions and signups** (Google Analytics): Call `runReport` with `dateRanges: [{ startDate: "yesterday", endDate: "yesterday" }]` and metrics `sessions` and `totalUsers`, then `eventCount` with a `dimensionFilter` on `eventName` equal to `sign_up` (or whichever key event marks a signup).
3. **Check the date isn't there yet** (Google Sheets): Read `Daily!A:A` with `spreadsheets.values.get`. If yesterday is already in column A, stop; if the last date is older than the day before yesterday, queue the missing days too, oldest first.
4. **Append the row** (Google Sheets): Call `spreadsheets.values.append` on `Daily!A:F` with `valueInputOption=USER_ENTERED` and `insertDataOption=INSERT_ROWS`, values `[date, revenue, signups, sessions, users, "agent"]`, and read the row number from `updates.updatedRange`.
5. **Report the row**: The values written, the row number, and how each compares with the average of the 7 rows above it.

## Route B: the browser

### What you need

- Signed in to Stripe with the Analyst role or higher, and to Google with an account that has Viewer access to the GA4 property and Editor access to the spreadsheet.

If something is missing, say what and stop; do not invent numbers.

### Steps

Start at https://dashboard.stripe.com/payments. The user is signed in already; never type passwords or codes, and ask if a sign-in page appears.

1. **Total yesterday's revenue in Stripe**: Open `https://dashboard.stripe.com/payments` in live mode, set the **Date** filter to yesterday in your time zone and the **Succeeded** view, and total the **Amount** column (click **Export** when the list runs past a page). Switch to the **Refunded** view for the same day and subtract the refunded amounts.
2. **Read sessions and users in GA4**: Open `https://analytics.google.com/`, pick the property, go to **Reports** > **Acquisition** > **Traffic acquisition**, set the date picker to **Yesterday** and read the **Sessions** and **Total users** totals at the top of the table.
3. **Count signups**: In the same property go to **Reports** > **Engagement** > **Events**, keep the date on **Yesterday**, find the `sign_up` row (or whichever event marks a signup) and read its **Event count**.
4. **Check the sheet for the date**: Open the metrics spreadsheet from `https://docs.google.com/spreadsheets/`, click the **Daily** tab and jump to the last row of column A (Ctrl+Down on the column). If yesterday is already there, stop. If the last date is older than the day before yesterday, note the missing days to fill first, oldest first.
5. **Type the row**: In the first empty row type date, revenue, signups, sessions, users and `agent` across columns A to F, in the date format the column already uses, and press Enter after the last cell. Then report the row number and how each value compares with the average of the 7 rows above.

Note: GA4 standard reports can take 24 to 48 hours to finalize, so yesterday's sessions may rise a little after the row is written; the API route has the same lag. Stripe Payments amounts are in the charge currency, not the settlement currency. Typing into a sheet through a browser agent is fragile: check the row after it is written.

## The report

- The row added: date, revenue, signups, sessions, users.
- Where it went: tab and row number.
- Each value against the 7-day average from the sheet.
- Any day it had to backfill, or a source it couldn't reach.

## Post it to Briefkin

When `BRIEFKIN_TOKEN` is set, or `~/.config/briefkin/env` exists (the installer from https://briefkin.dev/docs writes it), also send the result to the user's Briefkin board as one card. Keep the `item_key` the same on every run so the card updates in place, use a new `event_id` per run, and put today's real numbers in place of the example ones. If the request fails, say so once and carry on.

```bash
[ -n "${BRIEFKIN_TOKEN:-}" ] || . ~/.config/briefkin/env
curl -sS -X POST "${BRIEFKIN_URL:-https://briefkin.dev}/v1/events" \
  -H "authorization: Bearer $BRIEFKIN_TOKEN" \
  -H "content-type: application/json" \
  -d @- <<'JSON'
{
  "v": 1,
  "event_id": "google-sheets-daily-metrics-log/<date of this run, e.g. 2026-10-16>",
  "item_key": "google-sheets-daily-metrics-log",
  "project": "Acme",
  "source": "Google Sheets daily metrics log skill",
  "kind": "update",
  "title": "Oct 15 logged: $3,212 revenue, 41 signups",
  "summary": "Added row **289** to the Daily tab. Revenue and signups are above the 7-day average; sessions are flat.",
  "widget": [
    {
      "type": "KeyValue",
      "props": {
        "items": [
          {
            "key": "Date",
            "value": "2026-10-15"
          },
          {
            "key": "Revenue",
            "value": "$3,212 (7-day average $2,980)"
          },
          {
            "key": "Signups",
            "value": "41 (average 34)"
          },
          {
            "key": "Sessions",
            "value": "2,876 (average 2,851)"
          },
          {
            "key": "Users",
            "value": "2,204"
          },
          {
            "key": "Written to",
            "value": "Daily!A289:F289"
          }
        ]
      }
    },
    {
      "type": "Sparkline",
      "props": {
        "values": [
          3010,
          3150,
          2710,
          3050,
          2890,
          2900,
          3150,
          3212
        ],
        "label": "Revenue, last 8 days",
        "prefix": "$"
      }
    }
  ]
}
JSON
```

Widgets come from the Briefkin catalog (https://briefkin.dev/v1/catalog). Without a token, just give the user the report.

## Run it on a schedule

Suggested: Every day at 6:30 (`30 6 * * *`). From cron, with the agent signed in on that machine:

```bash
30 6 * * * claude -p "Run the google-sheets-daily-metrics-log skill"
# Codex: codex exec, Gemini CLI: gemini -p, Copilot CLI: copilot -p, OpenCode: opencode run
```

Or use the agent's own scheduler (Claude Code routines, Codex automations, Claude or ChatGPT scheduled tasks): https://briefkin.dev/skills/google-sheets-daily-metrics-log#schedule

Source: https://briefkin.dev/skills/google-sheets-daily-metrics-log
