Workflows: Part1-Pub-Generate-Weekly-Form, Part2-Pub-Generate-Shifts, Part3-Pub-Approve-and-Send-Mass-Email
System: n8n
Sources: n8n workflow exports in IHNYC-Remote/assets
Overview
- Sends a weekly Formbricks availability survey to active pub tenders.
- Normalizes the latest submissions, matches responses to Notion shifts, and writes assignments.
- Requires all shifts in a week to be Approved before emailing the final schedule.
- Sends the assignment email and archives the week in Notion.
Data sources
Notion databases
- Shifts DB (id
NOTION_DB_ID_SHIFTS)- Fields used:
Shift Status(status),Date/Time(date),Week Of(rich_text),Human Label (friendly)(rich_text),Human Label(rich_text),staff_needed(number or formula).
- Fields used:
- Assignments DB (id
NOTION_DB_ID_ASSIGNMENTS)- Fields used:
Week of (friendly)(rich_text),Date/Time(date),Name(title), relations toShifts DBandPub Tenders DB.
- Fields used:
- Pub Tenders DB (id
NOTION_DB_ID_PUB_TENDERS)- Fields used:
Active(checkbox),Name,Email,access_token.
- Fields used:
- Form Submissions DB (id
NOTION_DB_ID_FORM_SUBMISSIONS)- Fields written:
Selected Shifts,Week Of,Submission ID,Created At,Are you available, plus metadata (browser/os/device/country/form URL).
- Fields written:
Form submissions
- Formbricks survey id:
FORMBRICKS_SURVEY_ID(management API v1 for survey update, v2 for responses). - Question ids used in code:
- Shifts multi-select:
FORMBRICKS_Q_SHIFTS_ID - Availability:
FORMBRICKS_Q_AVAILABILITY_ID
- Shifts multi-select:
- EmailSend nodes are used for outgoing email; node names reference Resend.
- Actual provider and credentials are configured in n8n (unknown from export).
Scheduling / triggers
- Part 1 schedule: cron
0 0 10 * * 0(Sundays at 10:00, timezone from n8n settings). - Part 2 schedule: cron
0 0 12 * * TUE(Tuesdays at 12:00, timezone from n8n settings). - Part 3 schedule: cron
0 0 16-17 * * 2(Tuesdays at 16:00 and 17:00, timezone from n8n settings).
Flow breakdown by part
Part 1: Generate weekly form
- Trigger runs on the Part 1 cron schedule.
A2 - Get Shifts from Notionpulls Shifts DB whereShift StatusequalsCreatedand sorts byDate/Timeascending.A3 - Build Options for Formsortbuilds shift labels fromproperty_date_timeinAmerica/New_Yorkand generates shift ids likeYYYYMMDD-HHMM.A0 - Get Tenders from Notionpulls Pub Tenders DB (all);A5 - Mergefilters out inactive tenders (property_active === false) and dedupes by access token.HTTP Request - Get Survey ParametersGETs the Formbricks survey;A6 - Build Formbricks Payloadinjects weekOf text and dynamic shift choices, setsstatustoinProgress.HTTP RequestPUTs the updated survey payload to Formbricks.Edit Fieldsbuilds a survey link with token and name query params.Create Email Payloadbuilds HTML and text availability emails (one per tender) andSend email through Resenddelivers them.Loop Over ItemsandWaitexist for pacing (no parameters in export).Send email through Resend - Let Admin Know Completenotifies admin when availability emails are sent.- Disabled nodes:
A1b - Compute Current WeekandHTTP Request - Open Survey(the disabled PUT sets survey status tocompleteddespite the node name).
Part 2: Generate shifts and assignments
- Trigger runs on the Part 2 cron schedule.
HTTP Request - Close Surveysets the Formbricks survey status tocompleted.A1 - Get Responsespulls responses since the current week start (Sunday) with limit 250.B1 - Normalize Responses (Latest Submission)keeps only finished submissions and selects the latest pertoken. If availability isnot_available, selected shifts are cleared.B2 - Split OutandB3 - Rename Shifts to Shiftnormalize each response into a singleshiftfield.C1 - Find Corresponding Shifts Databasematches Shifts DB rows byHuman Label (friendly)equals the selected shift andWeek Ofequals the current week start.C2 - Attach shiftId to each itemattaches shift metadata, includingstaffNeeded.D1 - Pick Assigned Tendersgroups by shift, runs Fisher-Yates shuffle, and selects up tostaffNeededcandidates per shift.Create Page (Assignments DB)creates one assignment per selected tender with title=[{{ $json.weekOf }}] Assignment - {{ $json.tenderName }}and relations to Shifts DB and Pub Tenders DB.B_SubmissionsandMake Selected Shifts into a Stringprepare submission metadata;Update Form Submissions DBwrites results into the Form Submissions DB.Email Payload generationandSend emailnotify an admin that assignments are ready for approval.
Part 3: Approve and send mass email
- Trigger runs on the Part 3 cron schedule.
Get the Shifts that are NOT archivedpulls Shifts DB whereShift Statusdoes not equalArchived.Check all shifts in week are APPROVEDgroups byproperty_week_ofand only continues if every shift in a week hasproperty_shift_statusset toApproved. Otherwise it returnsreason: "No fully-approved weeks yet".Check if all shifts in the week are readygates downstream steps on that reason check.Get assignments for weekpulls Assignments DB whereWeek of (friendly)equals the ready week.Generate Mass Email Payloadbuilds the schedule email (plain text + HTML), sorts shifts by weekday and start time, and extracts tender names using the[YYYY-MM-DD] Assignment - Namepattern.Get Active Pub Tenderspulls Pub Tenders DB whereActiveis true.Combine Email + BCCbuilds a unique email list from active tenders and attaches it to the payload.Send assignments to all pub tenderssends the schedule email.Update shift statuses to archivedupdates each shift’sShift StatustoArchived.- Disabled node:
Send assignments to admin (test).
Key business rules
- Do not email the final schedule until every shift in the week is
Approvedin Shifts DB. - Assignment selection respects
staffNeededper shift and randomizes candidates via Fisher-Yates shuffle. - Assignments are created with title
[YYYY-MM-DD] Assignment - Name(value isweekOfandtenderNamefrom Part 2). - After emailing the schedule, shifts are marked
Archived. - Only finished Formbricks submissions are considered, and the latest submission per tender token is used.
- Inactive tenders are excluded from availability emails and BCC assembly.
Failure modes and troubleshooting
- “No fully-approved weeks yet”: Part 3 stops when any shift in a week is not
Approved. Confirm Shifts DB status for the week and rerun Part 3. - “No active shifts”: Part 3 returns
No active shiftswhen the Shifts DB query is empty. - Email send test node disabled:
Send assignments to admin (test)is disabled in Part 3; enable it for safe dry runs. - Notion rate limits or partial failures: GetAll and update calls can fail mid-run. Check execution logs, then rerun for only the affected week or shift pages.
- Formbricks response limits: the responses request uses
limit=250and a week-startstartDate. If submissions exceed the limit, add pagination or increase limits. - Safe reruns:
- Part 2 creates new Assignment pages every run. Remove or archive duplicate assignments before rerunning, or add a pre-check filter in Notion.
- Part 3 prevents resend by archiving shifts. To resend, temporarily un-archive the week’s shifts and disable the email send node if you only want to regenerate payloads.
Security and privacy notes
- Availability survey links include
tokenandnamequery params; treataccess_tokenvalues as secrets. - Email recipients are sourced from Pub Tenders DB email properties; admin recipients are configured in EmailSend nodes (redact in docs).
- The BCC list is built from active tenders in
Combine Email + BCC. The email node currently injects this list intoccEmailand uses a fixedbccEmail(redacted). Confirm this is intended before sharing. - Formbricks API keys are set in HTTP headers; store them in n8n credentials and avoid copying them into documentation.
Change log / maintenance
- If Notion schema changes, update filters and property keys:
- Shifts DB:
Shift Status,Date/Time,Week Of,Human Label (friendly),staff_needed. - Assignments DB:
Week of (friendly),Name,Shifts DBrelation,Pub Tenders DBrelation. - Pub Tenders DB:
Active,Email,access_token,Name. - Form Submissions DB: field names listed in
Update Form Submissions DB.
- Shifts DB:
- If Formbricks survey changes, update:
- Survey id
FORMBRICKS_SURVEY_ID. - Question ids
FORMBRICKS_Q_SHIFTS_IDandFORMBRICKS_Q_AVAILABILITY_ID.
- Survey id
- If assignment naming changes, update:
- Part 2 page title format.
- Part 3
extractTenderNameregex.
- If cron or timezone changes, update schedule triggers and any “week of” calculations.
- If email templates or recipients change, update
Create Email Payload,Generate Mass Email Payload,Combine Email + BCC, and the EmailSend node settings.
Diagrams
System overview (Mermaid)
flowchart LR subgraph Part1["Part 1: Generate weekly form"] P1Trig["Schedule Trigger"] P1Shifts["Notion: Shifts DB (Created)"] P1Tenders["Notion: Pub Tenders DB (Active)"] P1Form["Formbricks: Update survey"] P1Email["Email: Availability link"] end subgraph Part2["Part 2: Generate shifts"] P2Trig["Schedule Trigger"] P2Form["Formbricks: Close + responses"] P2Shifts["Notion: Shifts DB (lookup)"] P2Assign["Notion: Assignments DB (create)"] P2Subs["Notion: Form Submissions DB (update)"] P2Admin["Email: Approval request"] end subgraph Part3["Part 3: Approve + send"] P3Trig["Schedule Trigger"] P3Shifts["Notion: Shifts DB (not archived)"] P3Assign["Notion: Assignments DB (week)"] P3Tenders["Notion: Pub Tenders DB (Active)"] P3Email["Email: Mass schedule"] P3Archive["Notion: Shifts DB (archive)"] end P1Trig --> P1Shifts P1Trig --> P1Tenders P1Shifts --> P1Form P1Tenders --> P1Form P1Form --> P1Email P1Email --> P2Form P2Trig --> P2Form P2Form --> P2Shifts P2Form --> P2Assign P2Form --> P2Subs P2Assign --> P2Admin P3Trig --> P3Shifts P3Shifts --> P3Assign P3Assign --> P3Email P3Tenders --> P3Email P3Email --> P3Archive
Part 3 sequence (Mermaid)
sequenceDiagram participant Cron as Schedule Trigger participant N8N as n8n Workflow participant Shifts as Notion Shifts DB participant Assignments as Notion Assignments DB participant Tenders as Notion Pub Tenders DB participant Email as Email Provider Cron->>N8N: Fire on cron (0 0 16-17 * * 2) N8N->>Shifts: Get shifts where Shift Status != Archived Shifts-->>N8N: Shifts for all active weeks N8N->>N8N: Check all shifts in week are APPROVED alt Week fully approved N8N->>Assignments: Get assignments where Week of (friendly) == weekOf Assignments-->>N8N: Assignment pages N8N->>N8N: Generate mass email payload N8N->>Tenders: Get Active Pub Tenders (Active == true) Tenders-->>N8N: Tender emails N8N->>N8N: Combine payload + BCC list N8N->>Email: Send assignments email(s) N8N->>Shifts: Update Shift Status -> Archived else No fully-approved weeks yet N8N-->>Cron: Exit with reason end