Repository navigation
Build the Vote: our own sign-up forms, written to a Google Sheet for CJPAC - #112
Merged
Merged
Conversation
…e Sheet Build the Vote sign-ups now use our own two-step form. /api/volunteer writes each sign-up to a Google Sheet shared with CJPAC via the Sheets API (as a service account, signed with jose; no new dependencies) and identifies the volunteer to Customer.io. Step 2's optional answers go to /api/volunteer/details, which fills in the same row, found by an httpOnly cookie step 1 set, so the email never appears in a URL or the page. Removes FormstackForm, its stylesheet, and the proxy branch that moved the email off Formstack's redirect URL. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces CJPAC's Formstack embeds on /toronto/volunteer with our own two-step form. CJPAC now gets sign-ups through a Google Sheet that we write to with the Sheets API.
Flow
/toronto/volunteer#signup): name, email, phone, city and postal code, posted to/api/volunteer. That route:(416) 555-0123), and a valid postal codebtv_emailcookie scoped to/api/volunteer/details/api/volunteer/details, which fills in the same row, found by the cookie. The email never appears in a URL or in the page. These answers go to the Sheet only, not Customer.io. If the cookie has expired, the volunteer still goes on to the thanks page, since their sign-up is already saved.A hidden honeypot field drops form-filling bots.
The Sheet
src/lib/google-sheet.tscalls the Sheets REST API as a service account. It signs the token withjose, which is already a dependency, so there are no new packages.RAW, so input is never treated as a formula.Tab
Sign-ups, with columns:Signed up at·First name·Last name·Email·Phone·City·Postal code·Availability·Mayoral candidate·Issues·Details added at·Source·Medium·Campaign·PartnerSource, Medium and Campaign are the visitor's
utm_*tags. Partner is alwaysbuildcanada.Set these in the deployment environment:
GOOGLE_SERVICE_ACCOUNT_EMAILGOOGLE_SERVICE_ACCOUNT_PRIVATE_KEYGOOGLE_SHEET_IDThen share the Sheet with the service account as an Editor. In production, sign-ups fail if these aren't set (deliberately: better than silently losing them). Locally, the Sheet is skipped when they're unset.
Removed
FormstackForm,formstack.css, and the hidden-iframe redirect workaround.src/proxy.tsis back to exactly how it was before Add Build the Vote volunteer pages #110.Testing
pnpm test:sheet: 5 tests against an in-memory fake of the Sheets API and Google's token endpoint, using a generated RSA key. They cover JWT signing, header creation, upsert by email (case-insensitive), the Sheet's own column order, adding missing columns, token reuse, and skipping the Sheet when unconfigured.build-the-vote-sheet@build-the-vote.iam.gserviceaccount.com, projectbuild-the-vote): a step 1 → step 2 sign-up from local dev produced one complete row (header row created, phone and postal code normalized, UTM tags and Partner filled, step 2 answers in the same row), confirmed by reading the Sheet back through the API.🤖 Generated with Claude Code