Repository navigation
email-resend: pass the Resend Idempotency-Key HTTP header #18670
Replies: 2 comments 2 replies
|
+1, with a concrete case. Payload 3.90.2, Postgres, the jobs queue: a transactional mail is sent from a queued task. If the Resend request times out after Resend accepted it, the task retries and the same mail can go out twice. With an Is this planned? If not, would a PR be welcome that adds an optional idempotency key to |
|
Has anyone else been tempted to write an email marketing platform in Payload? Because after I got all my product management in payload, I started saying "Why can't I send product marketing? Why can I feed my analytics in to this and do personalized? Why can't I just use blocks as an email designer?" and now I am halfway down a rabbit hole. |
Uh oh!
There was an error while loading. Please reload this page.
Summary
@payloadcms/email-resendhas no way to send the ResendIdempotency-KeyHTTP header. Please add one.Facts (3.90.2)
sendEmailinpackages/email-resend/src/index.tssends only theAuthorizationandContent-TypeHTTP headers.message.headersgoes into the JSON body as email headers. Resend reads the idempotency key from the HTTP header onPOST /emails, not from an email header. Source: https://resend.com/docs/dashboard/emails/idempotency-keysWhy it matters
The Payload job queue claims a job with a read and then a write, with no row lock (
updateJobsin@payloadcms/drizzle). Two runs that start at the same time can claim the same job. An email task then sends the email twice. On Vercel, where the queue runs fromafter()and a cron, overlap is possible. An idempotency key per job makes the send safe.Proposal
One of these:
sendEmail({ ..., idempotencyKey: 'job-123' }), and send it as theIdempotency-KeyHTTP header.headershook in the adapter args that returns extra HTTP headers per message.Option 1 is the smallest change. I can open a PR if the team agrees on the shape.
All reactions