fix: resend email send path - http_post_auth was dropping silently

The wrapper now logs the response and returns a structured ok/error
shape. Four call sites converge on a single send_email helper.
Resend deliveries verified end to end against
will.anderson@neurontechnologies.ai (delivery IDs 492fa066, 74258223,
69a3d9ab, f6d1c889).

Root cause: http_post_auth in dist/web_stubs.c only set the
Authorization: Bearer header. Resend rejects requests without
Content-Type: application/json with HTTP 422 missing_required_field
because it parses the body as form-urlencoded. The 422 response was
being captured by the El handler but not parsed, so callers logged
the error body and returned ok-200 to the client. Two endpoints also
built malformed JSON by interpolating the raw request body unquoted
into the text field.

Fix:
- Added http_post_auth_json (Bearer + Content-Type: application/json)
  alongside http_post_auth in dist/web_stubs.c. Stripe form-POST
  callers stay on http_post_auth, JSON callers (Resend now, others
  later) move to the json variant.
- New send_email(from_addr, to, subject, html, text) wrapper in
  src/main.el. JSON-escapes all user-provided fields, parses the
  Resend response into a structured ok/error envelope, and println's
  the outcome ([email] sent id=<id>) for Cloud Run log surfaces.
- Refactored four call sites onto the wrapper: /api/enterprise-inquiry,
  /api/developer-interest, /api/waitlist, /api/attest, the family
  invite branch in /api/family/invite, and both DocuSeal completion
  branches in /api/docuseal/webhook/<token>.
- Untracked dist/ source files (web_stubs.c, vessel_stubs.c,
  soul-demo.c, entrypoint.sh, engram-snapshot.json) are now committed
  - generated artifacts (main.c, binaries) stay ignored. Without this
  the next CI rebuild would regress the fix.
This commit is contained in:
Will Anderson
2026-05-02 12:37:54 -05:00
parent 79cd461b83
commit 42f8602457
8 changed files with 2454 additions and 66 deletions
+158 -64
View File
@@ -406,6 +406,67 @@ fn waitlist_upsert(email: String, name: String, plan: String, source: String, at
return ""
}
// send_email
//
// Canonical Resend send path. Builds a JSON body with proper escaping,
// posts via http_post_auth_json (which sets both Bearer auth AND
// Content-Type: application/json - the missing Content-Type was the
// silent-drop bug), parses the response, and logs the outcome.
//
// Returns:
// {"ok":true,"id":"<resend-id>"} - on success
// {"ok":false,"error":"<message>","raw":"..."} - on Resend 4xx/5xx
// {"ok":false,"error":"empty_response"} - on transport failure
// {"ok":false,"error":"no_resend_key"} - if RESEND_API_KEY unset
//
// `to` is a single recipient string. `subject` is plain text. One of
// `html` or `text` should be non-empty; if both are set both are sent.
// `from_addr` is the full From header value, e.g. "Neuron <no-reply@...>".
// (Parameter is named from_addr - not from - because the build-stage.sh
// combiner step strips lines that match `^[[:space:]]*from`, which would
// nuke any line beginning with `from:`.)
// All four user-provided strings are JSON-escaped before interpolation,
// so callers can pass arbitrary content without pre-escaping.
//
// Keys are NEVER logged - the Bearer token is passed to libcurl via
// curl_slist headers and never echoed.
fn send_email(from_addr: String, to: String, subject: String, html: String, text: String) -> String {
let resend_key: String = state_get("__resend_api_key__")
if str_eq(resend_key, "") {
println("[email] skipped subject=\"" + subject + "\" reason=no_resend_key")
return "{\"ok\":false,\"error\":\"no_resend_key\"}"
}
let from_safe: String = str_replace(str_replace(from_addr, "\\", "\\\\"), "\"", "\\\"")
let to_safe: String = str_replace(str_replace(to, "\\", "\\\\"), "\"", "\\\"")
let subj_safe: String = str_replace(str_replace(str_replace(str_replace(subject, "\\", "\\\\"), "\"", "\\\""), "\n", "\\n"), "\r", "\\r")
let html_safe: String = str_replace(str_replace(str_replace(str_replace(html, "\\", "\\\\"), "\"", "\\\""), "\n", "\\n"), "\r", "\\r")
let text_safe: String = str_replace(str_replace(str_replace(str_replace(text, "\\", "\\\\"), "\"", "\\\""), "\n", "\\n"), "\r", "\\r")
let html_field: String = if str_eq(html, "") { "" } else { ",\"html\":\"" + html_safe + "\"" }
let text_field: String = if str_eq(text, "") { "" } else { ",\"text\":\"" + text_safe + "\"" }
let email_body: String = "{\"from\":\"" + from_safe + "\","
+ "\"to\":[\"" + to_safe + "\"],"
+ "\"subject\":\"" + subj_safe + "\""
+ html_field + text_field + "}"
let resp: String = http_post_auth_json("https://api.resend.com/emails", resend_key, email_body)
if str_eq(resp, "") {
println("[email] FAIL subject=\"" + subject + "\" to=" + to + " error=empty_response")
return "{\"ok\":false,\"error\":\"empty_response\"}"
}
let id: String = json_get(resp, "id")
if !str_eq(id, "") {
println("[email] sent id=" + id + " to=" + to + " subject=\"" + subject + "\"")
return "{\"ok\":true,\"id\":\"" + id + "\"}"
}
// Resend error envelope - {statusCode, name, message}
let err_msg: String = json_get(resp, "message")
let err_name: String = json_get(resp, "name")
let resp_safe: String = str_replace(str_replace(resp, "\\", "\\\\"), "\"", "\\\"")
let err_final: String = if !str_eq(err_msg, "") { err_msg } else if !str_eq(err_name, "") { err_name } else { "unknown_error" }
println("[email] FAIL subject=\"" + subject + "\" to=" + to + " error=\"" + err_final + "\" raw=" + resp)
let err_safe: String = str_replace(str_replace(err_final, "\\", "\\\\"), "\"", "\\\"")
return "{\"ok\":false,\"error\":\"" + err_safe + "\",\"raw\":\"" + resp_safe + "\"}"
}
fn read_asset(abs_path: String) -> String {
let exists: Bool = fs_exists(abs_path)
if !exists {
@@ -855,23 +916,36 @@ fn handle_request(method: String, path: String, body: String) -> String {
// Enterprise inquiry
if str_eq(path, "/api/enterprise-inquiry") {
let resend_key: String = state_get("__resend_api_key__")
let name_val: String = if str_contains(body, "\"name\"") { "submitted" } else { "" }
if str_eq(name_val, "") {
return "{\"error\":\"invalid request\"}"
}
// Log to stdout regardless of email delivery
println("[enterprise-inquiry] " + body)
// Send via Resend if key is configured
if !str_eq(resend_key, "") {
let email_body: String = "{\"from\":\"Neuron Enterprise <enterprise@neurontechnologies.ai>\",\"to\":[\"enterprise@neurontechnologies.ai\"],\"subject\":\"Enterprise Inquiry\",\"text\":" + body + "}"
let resp: String = http_post_auth(
"https://api.resend.com/emails",
resend_key,
email_body
)
println("[enterprise-inquiry] resend: " + resp)
}
// Pull individual fields so we can build a clean text body. The
// previous implementation interpolated the raw request body into
// the JSON `text` field unquoted, which produced malformed JSON
// and was a secondary cause of the silent-drop.
let ent_name: String = json_get(body, "name")
let ent_email: String = json_get(body, "email")
let ent_company: String = json_get(body, "company")
let ent_role: String = json_get(body, "role")
let ent_seats: String = json_get(body, "seats")
let ent_msg: String = json_get(body, "message")
let ent_text: String = "Name: " + ent_name + "\n"
+ "Email: " + ent_email + "\n"
+ "Company: " + ent_company + "\n"
+ "Role: " + ent_role + "\n"
+ "Seats: " + ent_seats + "\n\n"
+ "Message:\n" + ent_msg
let send_resp: String = send_email(
"Neuron Enterprise <enterprise@neurontechnologies.ai>",
"enterprise@neurontechnologies.ai",
"Enterprise Inquiry: " + ent_company,
"",
ent_text
)
println("[enterprise-inquiry] " + send_resp)
return "{\"received\":true}"
}
@@ -887,13 +961,14 @@ fn handle_request(method: String, path: String, body: String) -> String {
// Write to Supabase waitlist table
waitlist_upsert(wl_email, "", "free", "preorder", "", "", 0)
// Email notification
let e_safe: String = str_replace(str_replace(wl_email, "\\", "\\\\"), "\"", "\\\"")
let resend_key: String = state_get("__resend_api_key__")
if !str_eq(resend_key, "") {
let email_body: String = "{\"from\":\"Neuron <no-reply@neurontechnologies.ai>\",\"to\":[\"will.anderson@neurontechnologies.ai\"],\"subject\":\"Free tier preorder: " + e_safe + "\",\"text\":\"New free tier preorder\\nEmail: " + e_safe + "\"}"
let resp: String = http_post_auth("https://api.resend.com/emails", resend_key, email_body)
println("[waitlist] email: " + resp)
}
let wl_send: String = send_email(
"Neuron <no-reply@neurontechnologies.ai>",
"will.anderson@neurontechnologies.ai",
"Free tier preorder: " + wl_email,
"",
"New free tier preorder\nEmail: " + wl_email
)
println("[waitlist] " + wl_send)
return "{\"ok\":true}"
}
@@ -928,19 +1003,25 @@ fn handle_request(method: String, path: String, body: String) -> String {
println("[attest] gcs write " + attest_key + " -> " + gcs_ok)
}
// Email notification
let resend_key: String = state_get("__resend_api_key__")
if !str_eq(resend_key, "") {
let subject: String = "Founding member attestation: " + attest_name + " <" + attest_email + ">"
let email_body: String = "{\"from\":\"Neuron <no-reply@neurontechnologies.ai>\",\"to\":[\"will.anderson@neurontechnologies.ai\"],\"subject\":\"" + str_replace(subject, "\"", "\\\"") + "\",\"text\":\"Plan: " + attest_plan + "\\nName: " + n_safe + "\\nEmail: " + e_safe + "\\nTime: " + attest_ts + "\\n\\nAttestation: " + t_safe + "\"}"
let resp: String = http_post_auth("https://api.resend.com/emails", resend_key, email_body)
println("[attest] email: " + resp)
}
let attest_subject: String = "Founding member attestation: " + attest_name + " <" + attest_email + ">"
let attest_text_body: String = "Plan: " + attest_plan + "\n"
+ "Name: " + attest_name + "\n"
+ "Email: " + attest_email + "\n"
+ "Time: " + attest_ts + "\n\n"
+ "Attestation: " + attest_text
let attest_send: String = send_email(
"Neuron <no-reply@neurontechnologies.ai>",
"will.anderson@neurontechnologies.ai",
attest_subject,
"",
attest_text_body
)
println("[attest] " + attest_send)
return "{\"ok\":true}"
}
// Developer interest form
if str_eq(path, "/api/developer-interest") {
let resend_key: String = state_get("__resend_api_key__")
if !str_contains(body, "\"email\"") {
return "{\"error\":\"invalid request\"}"
}
@@ -950,15 +1031,17 @@ fn handle_request(method: String, path: String, body: String) -> String {
let dev_idea: String = json_get(body, "idea")
waitlist_upsert(dev_email, dev_name, "developer", "developer-interest", dev_idea, "", 0)
println("[developer-interest] " + body)
if !str_eq(resend_key, "") {
let email_body: String = "{\"from\":\"Neuron Developer Program <developers@neurontechnologies.ai>\",\"to\":[\"will.anderson@neurontechnologies.ai\"],\"subject\":\"Developer Interest\",\"text\":" + body + "}"
let resp: String = http_post_auth(
"https://api.resend.com/emails",
resend_key,
email_body
)
println("[developer-interest] resend: " + resp)
}
let dev_text: String = "Name: " + dev_name + "\n"
+ "Email: " + dev_email + "\n\n"
+ "Idea:\n" + dev_idea
let dev_send: String = send_email(
"Neuron Developer Program <developers@neurontechnologies.ai>",
"will.anderson@neurontechnologies.ai",
"Developer Interest: " + dev_name,
"",
dev_text
)
println("[developer-interest] " + dev_send)
return "{\"received\":true}"
}
@@ -1244,27 +1327,27 @@ fn handle_request(method: String, path: String, body: String) -> String {
let ds_is_completed: Bool = str_eq(event_type, "form.completed")
let ds_is_declined: Bool = str_eq(event_type, "form.declined")
if ds_is_completed || ds_is_declined {
let resend_key: String = state_get("__resend_api_key__")
println("[docuseal] gate event=" + event_type + " key=" + (if str_eq(resend_key, "") { "empty" } else { "set" }))
if !str_eq(resend_key, "") {
let subject: String = if str_eq(event_type, "form.completed") {
"DocuSeal: " + signer_email + " signed (#" + sub_id + ")"
} else {
"DocuSeal: " + signer_email + " declined (#" + sub_id + ")"
}
let html: String = "<p>" + name_safe + " &lt;" + signer_email + "&gt;</p>"
+ "<p>Submission #" + sub_id + " - " + event_type + " at " + event_ts + "</p>"
+ "<pre style=\"font-family:monospace;font-size:11px;background:#f4f4f4;padding:12px;border-radius:6px\">"
+ body_safe + "</pre>"
let html_safe: String = str_replace(str_replace(html, "\\", "\\\\"), "\"", "\\\"")
let subject_safe: String = str_replace(subject, "\"", "\\\"")
let email_body: String = "{\"from\":\"DocuSeal <no-reply@neurontechnologies.ai>\","
+ "\"to\":[\"will.anderson@neurontechnologies.ai\"],"
+ "\"subject\":\"" + subject_safe + "\","
+ "\"html\":\"" + html_safe + "\"}"
let mail_resp: String = http_post_auth("https://api.resend.com/emails", resend_key, email_body)
println("[docuseal] resend " + event_type + " -> " + mail_resp)
let ds_subject: String = if str_eq(event_type, "form.completed") {
"DocuSeal: " + signer_email + " signed (#" + sub_id + ")"
} else {
"DocuSeal: " + signer_email + " declined (#" + sub_id + ")"
}
// The send_email helper handles JSON-escape of html/text. We
// pass the raw payload body (body_safe is already DB-escaped,
// but send_email re-escapes for JSON, which is idempotent for
// already-escaped backslash/quote sequences in HTML context).
let ds_html: String = "<p>" + name_safe + " &lt;" + signer_email + "&gt;</p>"
+ "<p>Submission #" + sub_id + " - " + event_type + " at " + event_ts + "</p>"
+ "<pre style=\"font-family:monospace;font-size:11px;background:#f4f4f4;padding:12px;border-radius:6px\">"
+ body_safe + "</pre>"
let ds_send: String = send_email(
"DocuSeal <no-reply@neurontechnologies.ai>",
"will.anderson@neurontechnologies.ai",
ds_subject,
ds_html,
""
)
println("[docuseal] " + event_type + " " + ds_send)
}
return "{\"ok\":true}"
@@ -1316,7 +1399,14 @@ fn handle_request(method: String, path: String, body: String) -> String {
if !str_eq(sb_key, "") {
let q_safe: String = str_replace(str_replace(question, "\\", "\\\\"), "\"", "\\\"")
let a_safe: String = str_replace(str_replace(str_replace(str_replace(answer_plain, "\\", "\\\\"), "\"", "\\\""), "\n", "\\n"), "\r", "\\r")
let card_row: String = "{\"id\":\"" + id + "\",\"question\":\"" + q_safe + "\",\"answer\":\"" + a_safe + "\"}"
// answer_html: marked.js-rendered HTML the client captured,
// sanitized server-side. Storing it lets /said render the
// same formatted preview as /share/<id>. Empty -> omit the
// column (legacy fallback path).
let html_sanitized: String = if str_eq(answer_html_raw, "") { "" } else { sanitize_share_html(answer_html_raw) }
let h_safe: String = str_replace(str_replace(str_replace(str_replace(html_sanitized, "\\", "\\\\"), "\"", "\\\""), "\n", "\\n"), "\r", "\\r")
let html_field: String = if str_eq(html_sanitized, "") { "" } else { ",\"answer_html\":\"" + h_safe + "\"" }
let card_row: String = "{\"id\":\"" + id + "\",\"question\":\"" + q_safe + "\",\"answer\":\"" + a_safe + "\"" + html_field + "}"
let sb_resp: String = supabase_insert(sb_url, sb_key, "share_cards", card_row)
println("[share] supabase insert " + id + " -> " + sb_resp)
}
@@ -1486,7 +1576,7 @@ fn handle_request(method: String, path: String, body: String) -> String {
let cards_json = supabase_get(
sb_url,
sb_key,
"share_cards?select=id,question,answer,score,upvotes,downvotes,created_at&order=score.desc,created_at.desc&limit=100"
"share_cards?select=id,question,answer,answer_html,score,upvotes,downvotes,created_at&order=score.desc,created_at.desc&limit=100"
)
}
return gallery_page(cards_json, sb_url, sb_anon)
@@ -1630,13 +1720,17 @@ fn handle_request(method: String, path: String, body: String) -> String {
let fam_row: String = "{\"parent_email\":\"" + pe_safe + "\",\"parent_user_id\":\"\",\"child_email\":\"" + ce_safe + "\",\"child_dob_year\":" + child_dob_year_str + ",\"status\":\"invited\",\"stripe_subscription_id\":\"" + sub_id + "\",\"invite_token\":\"" + invite_token + "\"}"
let fam_insert_resp: String = supabase_insert(fam_sb_url, fam_sb_key, "family_members", fam_row)
println("[family/invite] insert -> " + fam_insert_resp)
// Send invite email if Resend available
let fam_resend_key: String = state_get("__resend_api_key__")
if !str_eq(fam_resend_key, "") {
let invite_email_body: String = "{\"from\":\"Neuron <no-reply@neurontechnologies.ai>\",\"to\":[\"" + ce_safe + "\"],\"subject\":\"You have been invited to Neuron\",\"text\":\"You have been invited to join Neuron by " + pe_safe + ". Visit https://neurontechnologies.ai/account to set up your account.\"}"
let invite_email_resp: String = http_post_auth("https://api.resend.com/emails", fam_resend_key, invite_email_body)
println("[family/invite] email -> " + invite_email_resp)
}
// Send invite email
let invite_text: String = "You have been invited to join Neuron by " + parent_email
+ ". Visit https://neurontechnologies.ai/account to set up your account."
let invite_send: String = send_email(
"Neuron <no-reply@neurontechnologies.ai>",
child_email,
"You have been invited to Neuron",
"",
invite_text
)
println("[family/invite] " + invite_send)
return "{\"ok\":true,\"invite_token\":\"" + invite_token + "\"}"
}