← Index

L&D Cohort Automation

google apps script • clasp cli • the bradbury group

Automates the 11-step post-session SOP for The Bradbury Group's L&D Cohort program. Files are renamed and routed, sheets and docs are populated, transcripts are analyzed by AI, facilitator notes are generated, and follow-up drafts are created — all automatically. Humans review and release.

14
Files
8
Phases
11
SOP Steps
90+
Tests Pass
Overview

After every L&D Cohort session, Paige manually runs an 11-step SOP: rename recording & transcript files, move them to Drive folders, link them in the Schedule Sheet, run the transcript through Walter (AI) for homework/analysis, populate Facilitator Notes, update the Hub doc, and notify learners. This automation handles all of it — from file drop to Gmail draft — in a single pipeline triggered by runPipelineManual(weekNum, sessionLetter).

Architecture
Config.gs
Script Properties reader, folder ID constants, feature flags
Utils.gs
Naming parser/builder, date helpers, execution logger, pipeline state
FileManager.gs
Drive: detect type, rename, move, create shortcuts, extract text
SheetUpdater.gs
Schedule Sheet: find session rows, write links, mark steps complete
HubUpdater.gs
00_START_HERE doc: append session entry with synopsis & hyperlinks
WalterApi.gs
Claude/Gemini API: L&D analysis prompt, JSON parse, analysis doc
DocPopulator.gs
FN template: copy, fill {{placeholders}} from Walter JSON
GmailDrafter.gs
Create follow-up email draft with links, synopsis, homework
ClickUpApi.gs
Create review tasks in ClickUp (graceful skip if no key)
Orchestrator.gs
Sequences all phases, manages state, handles 6-min limit
Triggers.gs
Gmail poll trigger, weekly BAM trigger setup
TestHarness.gs
Per-phase test functions, setup helpers, E2E pipeline test
TestData.gs
Dummy transcript (~9K chars), metadata, Walter response
Pipeline Flow
graph TD
  START["Files dropped in
00_Incoming"] --> FM subgraph Phase1["Phase 1 — File Management"] FM["Detect file type
recording vs transcript"] --> RN["Rename per convention
LD-C1_W03A_Recording_2026-04-28"] RN --> MV["Move to destination
01_Recordings / 02_Transcripts"] MV --> SC["Create shortcuts
in 00_SHARED subfolders"] SC --> EX["Extract transcript text"] end EX --> SU subgraph Phase2["Phase 2 — Sheet Updates"] SU["Find session row
in Schedule Sheet"] --> LK["Write recording &
transcript links"] LK --> MS["Mark SOP steps
complete"] end MS --> HU subgraph Phase3["Phase 3 — Hub Doc"] HU["Append session entry
to 00_START_HERE"] end HU --> WA subgraph Phase4["Phase 4 — Walter AI Analysis"] WA["Send transcript to
Claude or Gemini API"] --> JP["Parse structured
JSON response"] JP --> AD["Create formatted
Analysis Doc in Drive"] end AD --> DP subgraph Phase5["Phase 5 — FN Population"] DP["Copy FN template"] --> PH["Replace placeholders
with Walter data"] end PH --> GD subgraph Phase6["Phase 6 — Notifications"] GD["Create Gmail draft
with links & analysis"] GD --> CU["Create ClickUp
review tasks"] end CU --> DONE["Pipeline Complete"] classDef p1 fill:#f472b622,stroke:#f472b6,stroke-width:2px classDef p2 fill:#a78bfa22,stroke:#a78bfa,stroke-width:2px classDef p3 fill:#34d39922,stroke:#34d399,stroke-width:2px classDef p4 fill:#60a5fa22,stroke:#60a5fa,stroke-width:2px classDef p5 fill:#fbbf2422,stroke:#fbbf24,stroke-width:2px classDef p6 fill:#f8717122,stroke:#f87171,stroke-width:2px classDef start fill:#818cf822,stroke:#818cf8,stroke-width:2px classDef done fill:#34d39944,stroke:#34d399,stroke-width:3px class START start class FM,RN,MV,SC,EX p1 class SU,LK,MS p2 class HU p3 class WA,JP,AD p4 class DP,PH p5 class GD,CU p6 class DONE done
Data Flow & Pipeline State
graph LR
  subgraph State["PIPELINE_W03A
Script Properties"] S1["transcriptText"] S2["recordingUrl"] S3["transcriptUrl"] S4["walterJson"] S5["analysisUrl"] S6["fnDocUrl"] S7["synopsis"] S8["draftId"] end FM2["FileManager"] -->|"writes"| S1 FM2 -->|"writes"| S2 FM2 -->|"writes"| S3 WA2["WalterApi"] -->|"reads"| S1 WA2 -->|"writes"| S4 WA2 -->|"writes"| S5 WA2 -->|"writes"| S7 DP2["DocPopulator"] -->|"reads"| S4 DP2 -->|"writes"| S6 GD2["GmailDrafter"] -->|"reads"| S4 GD2 -->|"reads"| S2 GD2 -->|"reads"| S3 GD2 -->|"reads"| S6 GD2 -->|"writes"| S8 HU2["HubUpdater"] -->|"reads"| S2 HU2 -->|"reads"| S3 HU2 -->|"reads"| S7 classDef state fill:#60a5fa22,stroke:#60a5fa,stroke-width:2px classDef mod fill:#a78bfa22,stroke:#a78bfa,stroke-width:2px class S1,S2,S3,S4,S5,S6,S7,S8 state class FM2,WA2,DP2,GD2,HU2 mod

Pipeline state is persisted to PIPELINE_{sessionId} in Script Properties as a JSON string. Each phase reads what it needs and writes what downstream phases will consume. If the 5-minute limit is approaching, the Orchestrator saves state and schedules a continuation trigger.

Naming Convention
LD-C1 _ W03A _ Recording _ 2026-04-28
PREFIX Cohort identifier: LD-C1
WEEK+SESSION Week number + letter: W03A
DESCRIPTION File type: Recording, Transcript, FacilitatorNotes, WalterAnalysis
DATE Session date: yyyy-MM-dd
Human-in-the-Loop Model

Auto-generated

  • File renaming & routing
  • Schedule Sheet links & status
  • Hub doc session entry
  • Walter AI transcript analysis
  • Analysis doc in Drive
  • Facilitator Notes population
  • Gmail follow-up draft
  • ClickUp review tasks

Human reviews & releases

  • Review Walter analysis accuracy
  • Edit Facilitator Notes before sharing
  • Review & send Gmail draft
  • Confirm deliverables in sheet
  • Check ClickUp tasks for completeness
Setup Guide
Install clasp: npm install -g @google/clasp
Login: clasp login (opens browser for Google OAuth)
Enable Apps Script API at https://script.google.com/home/usersettings
Clone the repo & create Apps Script project: clasp create --type standalone --title "LD Cohort Automation"
Push code: clasp push (confirm manifest overwrite)
Open editor: clasp open — run setupScriptProperties()
Set API key: run setClaudeApiKey() or setGeminiApiKey() (paste key in function body first)
Run testSprint0() to verify foundation
Run testFullPipeline() for end-to-end verification
Replace placeholder folder IDs with real Drive folder IDs in Script Properties
Enable feature flags one at a time via FEATURE_FLAGS JSON in Script Properties
Script Properties Reference
All Script Properties
PropertyPurposeSource
FOLDER_INCOMINGDrive ID: 00_Incoming folderDrive URL
FOLDER_RECORDINGSDrive ID: 01_Recordings folderDrive URL
FOLDER_TRANSCRIPTSDrive ID: 02_Transcripts folderDrive URL
FOLDER_FNDrive ID: 03_FacilitatorNotes folderDrive URL
FOLDER_ANALYSISDrive ID: 05_Analysis folderDrive URL
FOLDER_SHAREDDrive ID: 00_SHARED folder (with subfolders)Drive URL
SCHEDULE_SHEET_IDSchedule Sheet spreadsheet IDSheet URL
HUB_DOC_ID00_START_HERE overview doc IDDoc URL
FN_TEMPLATE_IDFacilitator Notes template doc IDDoc URL
CLAUDE_API_KEYAnthropic API key (checked first)console.anthropic.com
GEMINI_API_KEYGoogle AI key (fallback)aistudio.google.com
CLICKUP_API_KEYClickUp API token (optional)ClickUp settings
CLICKUP_LIST_IDClickUp list for review tasksClickUp URL
FACILITATOR_EMAILEmail for Gmail draftsManual
COHORT_PREFIXNaming prefix (e.g., LD-C1)Manual
EXECUTION_LOG_SHEETSheet ID for _ExecutionLog tabSheet URL
FEATURE_FLAGSJSON: which phases are enabledManual
Feature Flags JSON
{
  "fileManagement": false,
  "sheetUpdater":   false,
  "hubUpdater":     false,
  "walterApi":      false,
  "docPopulator":   false,
  "gmailDrafter":   false,
  "clickUpApi":     false,
  "weeklyBam":      false
}

Set to true one at a time as you validate each phase with real data.