Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions examples/by-domain/e-learning/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# E-Learning

Automations for online course providers and training platforms: enrollment-lead intake, CRM handoff, form-based signups.

## Recurring app stack

**Facebook Lead Ads, Typeform, Google Sheets, HubSpot.** E-learning marketers run heavy paid-acquisition funnels (course-interest ads, webinar signups) that need both a lightweight log and a CRM handoff for the sales/enrollment team.

## Canonical workflows

Each entry is a filesystem symlink to the canonical directory under `by-pattern/`. Follow it to read the workflow source and README.

| Shape | Workflow | Apps |
|---|---|---|
| Flagship intake | [`facebook-lead-ads-to-google-sheets/`](./facebook-lead-ads-to-google-sheets) | Facebook Lead Ads -> Google Sheets |
| CRM routing | [`facebook-lead-ads-to-hubspot/`](./facebook-lead-ads-to-hubspot) | Facebook Lead Ads -> HubSpot |
| Trigger swap | [`typeform-to-google-sheets/`](./typeform-to-google-sheets) | Typeform -> Google Sheets |

## Where e-learning teams typically wire these

- **Flagship intake**: Meta lead-ads webhook (course-interest, webinar, free-trial forms). Marketing keeps a running log independent of the CRM.
- **CRM routing**: the same lead, upserted into HubSpot for the enrollment/sales team to work — HubSpot ranks in e-learning's top-5 apps.
- **Trigger swap**: quiz results, application forms, or webinar-registration Typeforms feed the same sheet-log destination as the Meta path.

## Patterns not yet covered

Common shapes an e-learning team would want that don't have workflows yet:

- **Course-completion event -> certificate email**: platform webhook triggers a Gmail send with a completion certificate attached.
- **Google Sheets waitlist -> Gmail cohort-start reminder**: scheduled digest to everyone on a cohort's waitlist sheet.
- **Webinar-attendee (chat-triggered) -> Google Sheets log**: a chat-message trigger logging attendance for follow-up, per the AI-agent-adjacent pattern seen in e-learning's usage data.

PRs welcome.
1 change: 1 addition & 0 deletions examples/by-domain/e-learning/facebook-lead-ads-to-hubspot
1 change: 1 addition & 0 deletions examples/by-domain/e-learning/typeform-to-google-sheets
33 changes: 33 additions & 0 deletions examples/by-domain/hospitality/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Hospitality

Automations for hotels, restaurants, and event venues: lead-capture ingest, sheet-native intake, guest follow-up.

## Recurring app stack

**Facebook Lead Ads, Typeform, Google Sheets, Gmail.** Hospitality accounts run lighter-weight ops than an enterprise CRM shop — a spreadsheet is often the CRM, and Gmail is often the notification layer.

## Canonical workflows

Each entry is a filesystem symlink to the canonical directory under `by-pattern/`. Follow it to read the workflow source and README.

| Shape | Workflow | Apps |
|---|---|---|
| Flagship intake | [`facebook-lead-ads-to-google-sheets/`](./facebook-lead-ads-to-google-sheets) | Facebook Lead Ads -> Google Sheets |
| Sheet-as-trigger | [`google-sheets-row-to-gmail/`](./google-sheets-row-to-gmail) | Google Sheets -> Gmail |
| Chain | [`typeform-submission-to-gmail/`](./typeform-submission-to-gmail) | Typeform -> Gmail |

## Where hospitality teams typically wire these

- **Flagship intake**: Meta lead-ads webhook (booking inquiry, event inquiry forms). Every lead lands in a shared sheet the front-desk or events team already checks.
- **Sheet-as-trigger**: a booking or waitlist sheet gets a new row (added by staff, a POS integration, or another Zap), and the workflow emails the guest or the on-duty manager.
- **Chain**: a Typeform booking or feedback form triggers an immediate confirmation email to the respondent.

## Patterns not yet covered

Common shapes a hospitality team would want that don't have workflows yet:

- **Facebook Lead Ads -> Mailchimp**: warm up event/booking inquiries in a nurture sequence — Mailchimp is hospitality's #5 app by usage.
- **Calendly/booking-tool -> Google Sheets + Discord**: reservation booked triggers a row plus a staff ping.
- **Guest checkout (Stripe/Square) -> feedback-request email**: post-stay NPS or review-request follow-up.

PRs welcome.
1 change: 1 addition & 0 deletions examples/by-domain/hospitality/google-sheets-row-to-gmail
33 changes: 33 additions & 0 deletions examples/by-domain/non-profit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Non-Profit

Automations for non-profit and NGO teams: donor and volunteer intake, event registration, donor follow-up.

## Recurring app stack

**Gravity Forms, Eventbrite, Typeform, Google Sheets, Gmail.** Non-profits skew WordPress-native for their donation and volunteer forms, and lean on Eventbrite for fundraisers and galas more than any other vertical.

## Canonical workflows

Each entry is a filesystem symlink to the canonical directory under `by-pattern/`. Follow it to read the workflow source and README.

| Shape | Workflow | Apps |
|---|---|---|
| WordPress intake | [`gravity-forms-to-google-sheets/`](./gravity-forms-to-google-sheets) | Gravity Forms -> Google Sheets |
| Event registration | [`eventbrite-to-google-sheets/`](./eventbrite-to-google-sheets) | Eventbrite -> Google Sheets |
| Chain | [`typeform-submission-to-gmail/`](./typeform-submission-to-gmail) | Typeform -> Gmail |

## Where non-profit teams typically wire these

- **WordPress intake**: a donation or volunteer-signup Gravity Form on the org's site logs every entry to a shared sheet the program team already works from.
- **Event registration**: a fundraiser or gala's Eventbrite listing feeds the same log-to-sheet shape, giving the events team one roster view.
- **Chain**: a Typeform intake or interest form (volunteer application, newsletter signup) sends an immediate thank-you email to the respondent.

## Patterns not yet covered

Common shapes a non-profit team would want that don't have workflows yet:

- **Gravity Forms -> CRM upsert**: donation/volunteer form entry creates or updates a donor record in the org's CRM, with a donor-stage field set.
- **Google Sheets donor roster -> scheduled Gmail digest**: weekly summary of new donors/volunteers to the program lead.
- **CRM record change -> CRM update (donor lifecycle)**: donor-stage transitions triggering related record updates — a strong signal in non-profit usage data, but the CRM in question (Salesforce) is outside this corpus's current app coverage.

PRs welcome.
1 change: 1 addition & 0 deletions examples/by-domain/non-profit/eventbrite-to-google-sheets
1 change: 1 addition & 0 deletions examples/by-domain/non-profit/typeform-submission-to-gmail
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# eventbrite-to-google-sheets

A Zapier durable workflow that appends every new Eventbrite attendee as a row in a Google Sheet. Eventbrite doesn't crack the top 10 for most verticals, but it's a distinctive top-5 pattern for non-profits — fundraisers and galas run their registration through it more than any other vertical.

## What it does

- **Trigger:** a `{ attendeeId, eventName, name, email, ticketClass }` object delivered to the workflow input (validated by Zod).
- **Step 1: `append-row-<attendeeId>`:** `GoogleSheetsV2CLIAPI.add_row`. Per-attendee step name keeps retries idempotent.

## Parameters to edit before deploy

| Constant | Purpose | How to determine the value |
|---|---|---|
| `GOOGLE_SHEETS_CONNECTION` | Deploy-time alias for the Google Sheets connection | `zapier-sdk list-connections` |
| `SPREADSHEET` | Target spreadsheet name or id | `zapier-sdk list-action-input-field-choices google-sheets write add_row spreadsheet` |
| `WORKSHEET` | Target worksheet/tab name | `zapier-sdk list-action-input-field-choices google-sheets write add_row worksheet` (depends on `SPREADSHEET`) |

The row column names (`"Name"`, `"Email"`, ...) are `// dynamic` — they must match your worksheet's header row exactly.

## Discovery

```bash
zapier-sdk list-actions google-sheets --action-type write
zapier-sdk list-action-input-fields google-sheets write add_row

zapier-sdk list-actions eventbrite
```

## Deploy

See [`../../README.md#deploying-a-durable-workflow`](../../README.md#deploying-a-durable-workflow).

Wire Eventbrite's `new_attendee_hook` ("New Attendee Registered") trigger to this workflow's endpoint. The attendee payload passes through as the workflow input.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "eventbrite-to-google-sheets",
"type": "module",
"dependencies": {
"@zapier/zapier-sdk": "0.80.0",
"@zapier/zapier-durable": "0.6.1",
"zod": "4.4.3"
},
"devDependencies": {
"typescript": "latest"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { defineDurable } from "@zapier/zapier-durable";
import { createZapierSdk } from "@zapier/zapier-sdk";
import { z } from "zod";

const sdk = createZapierSdk();

// Edit these three constants before deploying. See README.md for how to discover them.
const GOOGLE_SHEETS_CONNECTION = "google_sheets_primary";
const SPREADSHEET = "Registrations";
const WORKSHEET = "Sheet1";

const GOOGLE_SHEETS_APP_KEY = "GoogleSheetsV2CLIAPI";

const InputSchema = z.object({
attendeeId: z.string(),
eventName: z.string(),
name: z.string(),
email: z.string().email(),
ticketClass: z.string().optional(),
});
type Input = z.infer<typeof InputSchema>;

export default defineDurable<Input, { rowAdded: boolean }>(
"eventbrite-to-google-sheets",
async (ctx, rawInput) => {
const { attendeeId, eventName, name, email, ticketClass } = InputSchema.parse(rawInput);

await ctx.step(`append-row-${attendeeId}`, async () =>
sdk.runAction({
appKey: GOOGLE_SHEETS_APP_KEY,
actionType: "write",
actionKey: "add_row",
connection: GOOGLE_SHEETS_CONNECTION,
inputs: {
drive: "My Drive",
spreadsheet: SPREADSHEET,
worksheet: WORKSHEET,
// Row columns are dynamic — they must match your worksheet's header
// row exactly.
Name: name,
Email: email,
Event: eventName,
"Ticket Type": ticketClass,
},
}),
);

return { rowAdded: true };
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# facebook-lead-ads-to-google-sheets

A Zapier durable workflow that appends every new Facebook Lead Ads lead as a row in a Google Sheet. This is the single highest-volume shape in Zapier's own usage data — the flagship "log the lead" pattern that shows up in nearly every vertical's top 3.

## What it does

- **Trigger:** a `{ leadgen_id, form_name, ad_name, campaign_name, field_data }` object delivered to the workflow input (validated by Zod) — the raw Meta Lead Ads webhook shape.
- **Step 1: `append-row-<leadgen_id>`:** `GoogleSheetsV2CLIAPI.add_row`. Maps the Meta field-data array onto named worksheet columns. Per-lead step name keeps retries idempotent.

## Parameters to edit before deploy

| Constant | Purpose | How to determine the value |
|---|---|---|
| `GOOGLE_SHEETS_CONNECTION` | Deploy-time alias for the Google Sheets connection | `zapier-sdk list-connections` |
| `SPREADSHEET` | Target spreadsheet name or id | `zapier-sdk list-action-input-field-choices google-sheets write add_row spreadsheet` |
| `WORKSHEET` | Target worksheet/tab name | `zapier-sdk list-action-input-field-choices google-sheets write add_row worksheet` (depends on `SPREADSHEET`) |
| `FIELD_EMAIL`, `FIELD_PHONE`, `FIELD_FIRST_NAME`, `FIELD_LAST_NAME` | Meta form field labels to pull from `field_data` | Match your Lead Ads form's field names exactly (case-insensitive) |

The row column names (`"First Name"`, `"Email"`, ...) are `// dynamic` — they must match your worksheet's header row exactly. Adding, renaming, or removing a header column changes the accepted input shape.

## Discovery

```bash
zapier-sdk list-actions google-sheets --action-type write
zapier-sdk list-action-input-fields google-sheets write add_row

zapier-sdk list-actions facebook-lead-ads
```

## Deploy

See [`../../README.md#deploying-a-durable-workflow`](../../README.md#deploying-a-durable-workflow).

Wire Facebook Lead Ads' `lead` webhook (or Zapier's polling trigger) to this workflow's endpoint. The raw lead payload passes through as the workflow input.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "facebook-lead-ads-to-google-sheets",
"type": "module",
"dependencies": {
"@zapier/zapier-sdk": "0.80.0",
"@zapier/zapier-durable": "0.6.1",
"zod": "4.4.3"
},
"devDependencies": {
"typescript": "latest"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { defineDurable } from "@zapier/zapier-durable";
import { createZapierSdk } from "@zapier/zapier-sdk";
import { z } from "zod";

const sdk = createZapierSdk();

// Edit these three constants before deploying. See README.md for how to discover them.
const GOOGLE_SHEETS_CONNECTION = "google_sheets_primary";
const SPREADSHEET = "Leads";
const WORKSHEET = "Sheet1";

const GOOGLE_SHEETS_APP_KEY = "GoogleSheetsV2CLIAPI";

// Meta lead field labels are set by the form owner. Edit if your form uses different names.
const FIELD_EMAIL = "email";
const FIELD_PHONE = "phone_number";
const FIELD_FIRST_NAME = "first_name";
const FIELD_LAST_NAME = "last_name";

const InputSchema = z.object({
leadgen_id: z.string(),
form_name: z.string().optional(),
ad_name: z.string().optional(),
campaign_name: z.string().optional(),
field_data: z.array(
z.object({ name: z.string(), values: z.array(z.string()) }),
),
});
type Input = z.infer<typeof InputSchema>;

function pickField(fd: Input["field_data"], key: string): string | undefined {
return fd.find((f) => f.name.toLowerCase() === key.toLowerCase())?.values[0];
}

export default defineDurable<Input, { rowAdded: boolean }>(
"facebook-lead-ads-to-google-sheets",
async (ctx, rawInput) => {
const lead = InputSchema.parse(rawInput);

const email = pickField(lead.field_data, FIELD_EMAIL);
const phone = pickField(lead.field_data, FIELD_PHONE);
const firstName = pickField(lead.field_data, FIELD_FIRST_NAME) ?? "Lead";
const lastName = pickField(lead.field_data, FIELD_LAST_NAME) ?? "(from Meta)";

await ctx.step(`append-row-${lead.leadgen_id}`, async () =>
sdk.runAction({
appKey: GOOGLE_SHEETS_APP_KEY,
actionType: "write",
actionKey: "add_row",
connection: GOOGLE_SHEETS_CONNECTION,
inputs: {
drive: "My Drive",
spreadsheet: SPREADSHEET,
worksheet: WORKSHEET,
// Row columns are dynamic — they must match your worksheet's header
// row exactly. Verify names with list-action-input-fields against
// your connection (worksheet header changes alter this shape).
"First Name": firstName,
"Last Name": lastName,
Email: email,
Phone: phone,
Form: lead.form_name,
Ad: lead.ad_name,
Campaign: lead.campaign_name,
},
}),
);

return { rowAdded: true };
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# gravity-forms-to-google-sheets

A Zapier durable workflow that appends every new Gravity Forms entry as a row in a Google Sheet. Gravity Forms is the dominant WordPress form plugin behind donation and volunteer-signup intake, so this is the WordPress-ecosystem sibling to `typeform-to-google-sheets` — same destination, different intake.

## What it does

- **Trigger:** a `{ entryId, formTitle, fields }` object delivered to the workflow input (validated by Zod). `fields` is a flattened field-label -> value map.
- **Step 1: `append-row-<entryId>`:** `GoogleSheetsV2CLIAPI.add_row`. Spreads `fields` onto worksheet columns alongside entry metadata. Per-entry step name keeps retries idempotent.

## Parameters to edit before deploy

| Constant | Purpose | How to determine the value |
|---|---|---|
| `GOOGLE_SHEETS_CONNECTION` | Deploy-time alias for the Google Sheets connection | `zapier-sdk list-connections` |
| `SPREADSHEET` | Target spreadsheet name or id | `zapier-sdk list-action-input-field-choices google-sheets write add_row spreadsheet` |
| `WORKSHEET` | Target worksheet/tab name | `zapier-sdk list-action-input-field-choices google-sheets write add_row worksheet` (depends on `SPREADSHEET`) |

The `fields` spread is `// dynamic` — each key must match your worksheet's header row exactly. Gravity Forms' native field labels are set per-form by the site admin.

## Discovery

```bash
zapier-sdk list-actions google-sheets --action-type write
zapier-sdk list-action-input-fields google-sheets write add_row

zapier-sdk list-actions gravity-forms
```

## Deploy

See [`../../README.md#deploying-a-durable-workflow`](../../README.md#deploying-a-durable-workflow).

Wire Gravity Forms' `getEntry` ("Form Submission") trigger to this workflow's endpoint, flattening the raw field-id-keyed entry to the `fields` map shape first (a Formatter/Code step ahead of this workflow, or equivalent transform on your trigger).
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "gravity-forms-to-google-sheets",
"type": "module",
"dependencies": {
"@zapier/zapier-sdk": "0.80.0",
"@zapier/zapier-durable": "0.6.1",
"zod": "4.4.3"
},
"devDependencies": {
"typescript": "latest"
}
}
Loading
Loading