InTouch Hub · Blue Isle Software

Content Calendar (Sheets-driven)

Sheet-driven weekly content calendar digest. Every Monday, reads a ContentPlan Sheet and sends the upcoming week's entries (with platform, topic, draft snippet, status, assignee) to the configured contact. Replaces the thin CSV-driven content-calendar workflow that sent a message with no actual plan in the body.

sheetscontentsocial-mediamarketingcalendarweeklydigest

content-calendar-sheets

Every Monday morning, reads a ContentPlan Sheet and sends a digest of the upcoming week's content — platform, topic, draft snippet, status, assignee — to the configured contact. Anyone on your team who needs to know "what are we posting this week" gets the answer over coffee, without opening a tool.

Why this exists

The original content-calendar hub workflow reads a local CSV but sends a static message ("Here's your content plan for this week. Time to create!") with no actual plan content in the body. You receive a Monday reminder telling you to go look at the plan — not the plan itself.

This variant reads the actual entries from a Sheet you edit on your phone, formats them into the digest, and groups by day. The Sheet doubles as your editorial workflow (status: planneddraftedreadyposted), and the digest surfaces what's ready to publish vs what still needs work.

Setup

  1. Credentials (Credentials view): - google-workspace — Google Workspace service-account JSON
  2. Runtime environment (Runtime Environments view): - python — auto-created on every install
  3. ContentPlan Sheet (one-time): - Create a Sheet with a tab ContentPlan and 8 columns: A date | B platform | C topic | D draft E hashtags | F status | G assignee | H notes - Row 1 is the header. Data starts at row 2. - Maintain it as your editorial backlog. Add far-future entries; this workflow only surfaces the current week. - status values: planned / drafted / ready / posted / skipped. The workflow doesn't update status — that's a human decision. The digest just rolls up the counts.
  4. Edit workflow.yaml — replace the two placeholders: - <<CONTENT_PLAN_SHEET_ID>> — spreadsheet ID - <<OWNER_PUBLISHER>> — user name for your contact
  5. Schedule every Monday at 7:00 AM (or your team's preferred start time).

Sample digest

CONTENT CALENDAR — week of 2026-05-11 to 2026-05-17

Monday May 11:
  [ready]     blog       Why we switched from Postgres to ClickHouse   (owner: Alice)
      | We migrated 400GB last quarter and learned a few things — most…
      | tags: #engineering #databases #postgres

Tuesday May 12:
  [drafted]   twitter    Thread: 5 things people get wrong about CDC
      | 1/ Change Data Capture is not just a backup strategy. …
      | tags: #data #infra

Wednesday May 13:
  [planned]   linkedin   Hiring announcement: Senior Backend           (owner: Bob)

Friday May 15:
  [ready]     newsletter May product update — index rebalancing       (owner: Carol)
      | Carol's draft is ready for review; link to doc in the Sheet
      | note: needs design review before send

Status this week: ready=2, drafted=1, planned=1

2 entries marked READY — review and publish them today.

Pipeline

  1. composeruntimeenv (python). Reads ContentPlan!A2:H, filters to the current week (Monday-Sunday), groups by date, formats each entry with status / platform / topic / draft snippet / hashtags / notes, computes status rollup and a "ready to publish" callout. Prints to stdout.
  2. notifymessage. Pipes the digest to your owner user.

Customization

Differences from the original content-calendar

content-calendar (CSV) content-calendar-sheets
Data source local CSV file on InTouch server Google Sheet (edit on phone)
Message body Static "here's your plan" string Actual week's entries grouped by day
Status tracking None planned/drafted/ready/posted/skipped in the Sheet
Owner tracking None assignee column with attribution
"Ready to publish" callout None Highlights entries needing immediate action
Snippet preview None First 180 chars of each draft

Verified

gog sheets get --json --results-only syntax verified against the bundled gog v0.19.0 (2026-06-01) — returns nested arrays of strings (re-verify on first run); row width padded to 8 columns to handle ragged data. Python date math standard datetime.timedelta.

Source

See workflow.yaml.