Skip to content

Consolidate webhooks repo into virtualcoffee.io - #1501

Merged
JoeKarow merged 11 commits into
mainfrom
consolidate-webhooks
May 19, 2026
Merged

Consolidate webhooks repo into virtualcoffee.io#1501
JoeKarow merged 11 commits into
mainfrom
consolidate-webhooks

Conversation

@JoeKarow

@JoeKarow JoeKarow commented May 5, 2026

Copy link
Copy Markdown
Member

Linked Issue

No tracking issue; this lands the consolidation discussed alongside webhooks PR Virtual-Coffee/webhooks#28.

Description

This PR folds the standalone Virtual-Coffee/webhooks Netlify site into virtualcoffee.io so we maintain one repo, one deploy, and one set of secrets.

What's moving in

  • Three Slack/Zoom webhook endpoints, ported from webhooks/typescript-migration:
    • /zoom-meeting-webhook-handlernetlify/functions/zoom-meeting-webhook-handler/{index,airtable,slack}.ts
    • /slack-events and /slack-interactivitynetlify/functions/slack/{index,messages}.ts (a single function backs both routes)
  • Three scheduled functions with inline cron config (export const config: Config = { schedule: '…' }):
    • event-reminders-daily (0 12 * * *)
    • event-reminders-hourly (50 * * * *)
    • event-reminders-weekly (0 12 * * 1)
  • Shared utilities and types under netlify/functions/_shared/{env,slack,verify,types/*}.ts (the _shared/ prefix prevents Netlify from treating those folders as deployable functions).
  • A scripts/build-rooms.ts prebuild step that pulls co-working room records from Airtable into data/rooms.json. Wired into prebuild and pretypecheck. Writes an empty [] (with a warning) if AIRTABLE_COWORKING_BASE is not set, so contributors without webhook secrets can still build/typecheck locally.

What changed in-repo

  • Migrated existing CommonJS functions netlify/functions/join-{coffee,slack}.js to TS Functions v2 with default-exported (req: Request) => Response. Behavior preserved; missing env vars now throw via a shared requireEnv helper instead of silently 302-ing to Location: undefined.
  • netlify.toml: added [functions] included_files = ["data/*.json"] and three new redirects (/zoom-meeting-webhook-handler, /slack-events, /slack-interactivity). Existing /join-coffee and /join-slack redirects are unchanged — they target function names, so the JS→TS migration is transparent.
  • package.json: added @netlify/functions, @slack/bolt, slackify-html, plus @types/slackify-html/dotenv dev deps. Wired pnpm build-rooms into prebuild and pretypecheck.
  • netlify/env.d.ts: typed process.env for all webhook variables (CMS_*, SLACK_*, ZOOM_*, AIRTABLE_COWORKING_BASE, plus the existing ZOOM_TUESDAYS/THURSDAYS/SLACK_JOIN_LINK used by the migrated JS functions).
  • .env.example and README.md: documented the new env vars and a "Webhooks" section summarizing each endpoint and scheduled function.

Out of scope / follow-ups

  • External Slack and Zoom webhook URLs still point at the old webhooks host and will continue working through whatever DNS/redirect the maintainers set up at cutover. Updating Slack app + Zoom marketplace settings to hit virtualcoffee.io/... directly is a follow-up, not a blocker.
  • Once integrations are migrated and stable, archive Virtual-Coffee/webhooks and stop the old Netlify site.

Methodology

Two repos for one project's webhooks meant duplicate dependencies, duplicate Netlify config, duplicate env-var management, and two places to reason about the Slack/Zoom contract surface. The webhooks repo's typescript-migration branch had finished modernizing it (TS, Functions v2, ESM, pnpm) into the same stack virtualcoffee.io already uses, so consolidation was a clean port rather than a rewrite.

Concrete choices worth flagging:

  • Working-tree port, not a merge. I copied the post-migration source state of webhooks/ rather than preserving its git history, because the v1→v2 refactor on that branch contains files (functions/slack-{events,interactivity}/) that no longer exist and would need to be reverted post-merge. A clean port keeps this PR's diff readable.
  • _shared/ directory naming. Netlify treats every direct subdirectory of netlify/functions/ as a deployable function. Prefixing with _shared/ is the documented opt-out and keeps shared code co-located with the functions that import it.
  • requireEnv for join-coffee/join-slack env vars. Strictly stricter than the legacy JS — missing config now produces a 500 instead of a 302 to Location: undefined. Prod has these set; this only changes behavior in misconfigured environments, where loud failure is what we want.
  • build-rooms.ts writes [] on missing creds. Lets pnpm install && pnpm build succeed for contributors without webhook secrets. The Zoom handler then matches no rooms, which is the correct behavior in that environment anyway.
  • Cron declared inline on each function. Using export const config: Config = { schedule: '…' } per Netlify Functions v2 — no separate cron config needed. The stale /event-reminders → event-reminders-background redirect from the old netlify.toml was dropped (the function it referenced no longer exists; scheduled functions don't need an HTTP route).

Before merge: copy the webhook env vars from the old webhooks Netlify site to the virtualcoffee.io site (CMS_URL, CMS_TOKEN, SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET, SLACK_ANNOUNCEMENTS_CHANNEL, SLACK_EVENT_ADMIN_CHANNEL, ZOOM_WEBHOOK_SECRET_TOKEN, ZOOM_WEBHOOK_AUTH, AIRTABLE_COWORKING_BASE).

Code of Conduct

By submitting this pull request, you agree to follow our Code of Conduct

JoeKarow added 6 commits May 5, 2026 14:51
Adds @netlify/functions, @slack/bolt, slackify-html, dotenv, and
@types/slackify-html to support the consolidated webhook functions.
Adds scripts/build-rooms.ts to generate data/rooms.json from Airtable
during prebuild, and chains it into the existing prebuild pipeline.
Consolidates the Netlify Functions previously hosted in the standalone
webhooks repo (typescript-migration branch) into this codebase:

- slack/: unified Slack Events API + interactivity handler with custom
  Bolt receiver, signature verification, and team_join welcome flow.
- zoom-meeting-webhook-handler/: handles meeting.{started,ended,
  participant_joined,participant_left}, syncing co-working room state
  to Slack threads and Airtable room_instances records.
- event-reminders-{daily,hourly,weekly}/: scheduled functions that pull
  upcoming events from the CMS GraphQL API and post Block Kit messages
  to Slack. Schedules declared in-function via export const config.
- _shared/: HMAC verification helpers, Slack Web client wrapper,
  requireEnv helper, and CMS/Room types reused across functions.
- netlify/env.d.ts: typed ProcessEnv declarations for the new vars.
Replaces the CommonJS handler-style functions with TypeScript Netlify
Functions v2 (default-exported (req: Request) => Response). Aligns
with the rest of the netlify/functions/ directory now that the webhook
functions have landed. The /join-coffee and /join-slack redirects in
netlify.toml continue to work unchanged.
Adds [functions] included_files = ["data/*.json"] so the Zoom handler
can bundle the generated rooms.json. Adds /zoom-meeting-webhook-handler,
/slack-events, and /slack-interactivity rewrites pointing at the
corresponding functions, replacing the routing previously handled by
the standalone webhooks site.
Adds a Webhooks section to README.md summarizing the HTTP endpoints,
scheduled functions, and the rooms prebuild step. Documents the new
Slack/Zoom/Airtable env vars in .env.example. Carries over the
co-working-bot-ideation design doc from the previous webhooks repo.
Remove the co-working-bot ideation doc (and its README link) since
the design was never built. Add a pretypecheck script so tsc finds
data/rooms.json on a clean clone.
@JoeKarow
JoeKarow requested a review from a team as a code owner May 5, 2026 19:20
@netlify

netlify Bot commented May 5, 2026

Copy link
Copy Markdown

👷 Deploy Preview for virtual-coffee-io processing.

Name Link
🔨 Latest commit f95fc2f
🔍 Latest deploy log https://app.netlify.com/projects/virtual-coffee-io/deploys/6a0c76fee52e9d000806508e

@JoeKarow
JoeKarow requested a review from tkshill May 5, 2026 19:22
@JoeKarow JoeKarow self-assigned this May 5, 2026
@meg-gutshall
meg-gutshall requested a review from danieltott May 14, 2026 21:38
Comment thread netlify/functions/zoom-meeting-webhook-handler/index.ts Outdated
Comment thread netlify/functions/zoom-meeting-webhook-handler/index.ts
@BekahHW

BekahHW commented May 14, 2026

Copy link
Copy Markdown
Member

@JoeKarow I just bumped a couple of packages to removed the next.js vulnerabilities. You'll need to update the package.json.

JoeKarow added 4 commits May 16, 2026 13:46
Signed-off-by: Joe Karow <58997957+JoeKarow@users.noreply.github.com>
Signed-off-by: Joe Karow <58997957+JoeKarow@users.noreply.github.com>
Signed-off-by: Joe Karow <58997957+JoeKarow@users.noreply.github.com>

@meg-gutshall meg-gutshall left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! I would merge it, but I saw the note about the env variables that need to be added in Netlify. I'll hold off to make sure all our ducks are in a row first.

@JoeKarow

Copy link
Copy Markdown
Member Author

LGTM! I would merge it, but I saw the note about the env variables that need to be added in Netlify. I'll hold off to make sure all our ducks are in a row first.

env vars have been added to Netlify.

@JoeKarow
JoeKarow merged commit 38380ab into main May 19, 2026
4 of 5 checks passed
@JoeKarow
JoeKarow deleted the consolidate-webhooks branch May 19, 2026 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants