Quiz Email Worklog
1. Why Cloud Run → Google Sheet stalled
- The original plan routed quiz submissions through
growth-quiz-writeron Cloud Run and then captured each lead in a Google Sheet so the team could inspect scores and tiers. AcurlPOST tohttps://growth-quiz-writer-825297113896.asia-southeast1.run.appkept returning HTTP 403 (Forbidden), and neither Netlify nor Cloud Run logged the invocation because the service never received a valid request. - Running
gcloud run services add-iam-policy-binding growth-quiz-writer --member="allUsers" --role="roles/run.invoker" --region="asia-southeast1" --project=growth-archetype-quizfailed withPERMISSION_DENIEDonlocations/asia-southeast1.The command was authenticated as the org owner, but an organization policy disallows the binding, so Cloud Run stayed locked down and nothing reached the Google Sheet. - Because the Cloud Run service never recorded any quiz attempts, we stopped pursuing that route and built the recording logic inside this repo (
netlify/functions/record-quiz.js) so we can iterate locally and observe Netlify logs.
2. Netlify function + MailerSend relay
- Netlify now receives every quiz submission and calls
email-quiz-lead.js, which talks to MailerSend. Early attempts to test the new endpoint produced{"message":"Invalid JSON"}because the JSON payload included stray newlines. The reliable pattern is to dump the payload into a temporary file viaprintfand letcurl -d @/tmp/quiz-payload.jsonsend it. - MailerSend trial accounts introduced their own guardrails. After switching to the new flow we saw
{"message":"Trial accounts can only send emails to the administrator's email. #MS42225","errors":{"to":["Trial accounts can only send emails to the administrator's email. #MS42225"],"from.email":["The from.email domain must be verified in your account to send emails. #MS42207"]}}. The fix was to:- Set the
toaddress equal to the MailerSend administrator email (the same asGROWTHQUIZ_EMAIL_TOduring development). - Verify the sender domain inside MailerSend so that
from.emailis allowed.
- Set the
- Once those toggles were in place, the same
curlcommand returned{"message":"Email sent"}and Netlify logs recordedrecord-quizinvoking the relay for the submitted email.
3. Testing checklist
- Run the docs preview (
npm run docs:preview) and visit/en/quizzes/revenue-ops/. - Enter a work email, answer the seven questions, and confirm the final tier screen appears with a status message like
Sending your Revenue Ops diagnostic.... - Inspect the Netlify
record-quizlogs; they should showTriggering email relay for <email>andEmail relay succeeded for <email>. - To reproduce the quiz payload manually, use this safe shell snippet:
bash
printf '%s' '{"email":"moses@growthflowengineering.xyz","answers":[5,3,1,5,3,1,5],"score":27,"tier":{"label":"Functional but Unstable Revenue Ops","description":"Growth is unpredictable and valuation multiples are suppressed.","action":"Align rituals, reporting, and incentives across GTM pods."}}' >/tmp/quiz-payload.json
curl -X POST https://websitegfe.netlify.app/.netlify/functions/email-quiz-lead \
-H "Content-Type: application/json" \
-H "x-growth-quiz-secret: GFEgfe@123#" \
-d @/tmp/quiz-payload.json- MailerSend trial mode still requires that the verified administrator address matches the
tofield and that the sender domain is verified before any mail can go out.
4. Result & next steps
- The Revenue Ops quiz now mirrors the Growth Archetype flow: email capture first, sequential question hub, tier summary, and MailerSend relay. The frontend sums the numeric responses, chooses a tier, displays the copy, and sends
{ email, answers, score, tier }torecord-quiz. - When you build future quizzes, copy
docs/en/quizzes/quiz-template.md, update the question values, and keep reusing therecord-quiz+ MailerSend helper. If you eventually need to write to Sheets or another datastore again, extendrecord-quizbefore the email call so no single path blocks the email relay.

