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: planned → drafted → ready → posted), and the digest surfaces what's ready to publish vs what still needs work.
Setup
- Credentials (Credentials view):
-
google-workspace— Google Workspace service-account JSON - Runtime environment (Runtime Environments view):
-
python— auto-created on every install - ContentPlan Sheet (one-time):
- Create a Sheet with a tab
ContentPlanand 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. -statusvalues:planned/drafted/ready/posted/skipped. The workflow doesn't update status — that's a human decision. The digest just rolls up the counts. - Edit
workflow.yaml— replace the two placeholders: -<<CONTENT_PLAN_SHEET_ID>>— spreadsheet ID -<<OWNER_PUBLISHER>>— user name for your contact - 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
- compose —
runtimeenv(python). ReadsContentPlan!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. - notify —
message. Pipes the digest to your owner user.
Customization
- Week start —
WEEK_START_DAY = 0is Monday. Change to6for Sunday-Saturday weeks (US convention). - Draft snippet length — change
e["draft"][:180]. Trim shorter if your subscribers are SMS-only. - Add to-do reminders — extend the script: anything still
plannedon Friday triggers a separate alert. - Per-platform digest — if your team has separate owners per platform, split the digest by
platformand send a differentmessagetask to each platform owner. - Auto-publish hook — add a
postedstatus transition path: a second workflow runs daily, findsreadyrows for today, posts via the platform's API (Twitter/LinkedIn via Workspace--attach? Buffer? Hootsuite? — depends on your channel), and updates status toposted. Out of scope for this digest workflow but a natural follow-on.
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.