@m13v/seo-components 0.32.0 → 0.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/lib/book-call-route.ts +46 -8
package/package.json
CHANGED
|
@@ -91,6 +91,14 @@ export interface BookCallConfig {
|
|
|
91
91
|
emailSubject?: string;
|
|
92
92
|
/** Override the email HTML. Receives the email-click URL and the submitted email. */
|
|
93
93
|
emailHtml?: (emailClickUrl: string, subscriberEmail: string) => string;
|
|
94
|
+
/**
|
|
95
|
+
* Optional: log the outbound send. Called after the Resend send call returns;
|
|
96
|
+
* receives the subscriber email and the Resend email id (or null on failure).
|
|
97
|
+
* Errors thrown here are logged and swallowed so a flaky DB doesn't break the
|
|
98
|
+
* booking flow. Required for sites that want delivery / open / click webhook
|
|
99
|
+
* events to update the right `<slug>_emails` row by `resend_id`.
|
|
100
|
+
*/
|
|
101
|
+
onSent?: (email: string, resendEmailId: string | null) => Promise<void>;
|
|
94
102
|
}
|
|
95
103
|
|
|
96
104
|
/* ------------------------------------------------------------------ */
|
|
@@ -121,6 +129,7 @@ export function createBookCallHandler(config: BookCallConfig) {
|
|
|
121
129
|
apiKeyEnv = "RESEND_API_KEY",
|
|
122
130
|
emailSubject,
|
|
123
131
|
emailHtml,
|
|
132
|
+
onSent,
|
|
124
133
|
} = config;
|
|
125
134
|
|
|
126
135
|
return async function POST(req: NextRequest) {
|
|
@@ -175,14 +184,43 @@ export function createBookCallHandler(config: BookCallConfig) {
|
|
|
175
184
|
? emailHtml(emailClickUrl, email)
|
|
176
185
|
: defaultBookCallEmailHtml(brand, siteUrl, emailClickUrl);
|
|
177
186
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
187
|
+
if (onSent) {
|
|
188
|
+
// Sequential so the `onSent` callback receives the actual Resend id.
|
|
189
|
+
try {
|
|
190
|
+
const sendRes = await fetch("https://api.resend.com/emails", {
|
|
191
|
+
method: "POST",
|
|
192
|
+
headers: {
|
|
193
|
+
Authorization: `Bearer ${resendKey}`,
|
|
194
|
+
"Content-Type": "application/json",
|
|
195
|
+
},
|
|
196
|
+
body: JSON.stringify({ from: fromEmail, to: email, subject, html }),
|
|
197
|
+
});
|
|
198
|
+
let resendEmailId: string | null = null;
|
|
199
|
+
if (sendRes.ok) {
|
|
200
|
+
const data = (await sendRes.json().catch(() => ({}))) as { id?: string };
|
|
201
|
+
resendEmailId = data.id || null;
|
|
202
|
+
} else {
|
|
203
|
+
const detail = await sendRes.text().catch(() => "");
|
|
204
|
+
console.error("[book-call] email send failed:", sendRes.status, detail);
|
|
205
|
+
}
|
|
206
|
+
try {
|
|
207
|
+
await onSent(email, resendEmailId);
|
|
208
|
+
} catch (err) {
|
|
209
|
+
console.error("[book-call] onSent callback error:", err);
|
|
210
|
+
}
|
|
211
|
+
} catch (err) {
|
|
212
|
+
console.error("[book-call] email send threw:", err);
|
|
213
|
+
}
|
|
214
|
+
} else {
|
|
215
|
+
fetch("https://api.resend.com/emails", {
|
|
216
|
+
method: "POST",
|
|
217
|
+
headers: {
|
|
218
|
+
Authorization: `Bearer ${resendKey}`,
|
|
219
|
+
"Content-Type": "application/json",
|
|
220
|
+
},
|
|
221
|
+
body: JSON.stringify({ from: fromEmail, to: email, subject, html }),
|
|
222
|
+
}).catch((err) => console.error("[book-call] email send threw:", err));
|
|
223
|
+
}
|
|
186
224
|
|
|
187
225
|
return new Response(
|
|
188
226
|
JSON.stringify({ ok: true }),
|