refactor: optimize newsletter subscribe and check status logic

This commit is contained in:
javayhu 2025-04-29 22:22:26 +08:00
parent d94e777dde
commit f607bae96e
3 changed files with 24 additions and 53 deletions

View File

@ -112,7 +112,7 @@
"remark": "^15.0.1",
"remark-code-import": "^1.2.0",
"remark-gfm": "^4.0.1",
"resend": "^4.3.0",
"resend": "^4.4.1",
"shiki": "^2.4.2",
"sonner": "^2.0.0",
"stripe": "^17.6.0",

18
pnpm-lock.yaml generated
View File

@ -294,8 +294,8 @@ importers:
specifier: ^4.0.1
version: 4.0.1
resend:
specifier: ^4.3.0
version: 4.3.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
specifier: ^4.4.1
version: 4.4.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
shiki:
specifier: ^2.4.2
version: 2.4.2
@ -3197,8 +3197,8 @@ packages:
'@types/node@20.17.23':
resolution: {integrity: sha512-8PCGZ1ZJbEZuYNTMqywO+Sj4vSKjSjT6Ua+6RFOYlEvIvKQABPtrNkoVSLSKDb4obYcMhspVKmsw8Cm10NFRUg==}
'@types/node@20.17.24':
resolution: {integrity: sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA==}
'@types/node@20.17.32':
resolution: {integrity: sha512-zeMXFn8zQ+UkjK4ws0RiOC9EWByyW1CcVmLe+2rQocXRsGEDxUCwPEIVgpsGcLHS/P8JkT0oa3839BRABS0oPw==}
'@types/pg@8.11.11':
resolution: {integrity: sha512-kGT1qKM8wJQ5qlawUrEkXgvMSXoV213KfMGXcwfDwUIfUHXqXYXOfS1nE1LINRJVVVx5wCm70XnFlMHaIcQAfw==}
@ -5115,8 +5115,8 @@ packages:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
resend@4.3.0:
resolution: {integrity: sha512-4OBHeusMVSl0vcba2J3AaGzdZ1SXAAhX/Wkcwobe16AHmlW9h3li8wG62Fhvlsc61e+wlQoxcwJZP6WrBTbghQ==}
resend@4.4.1:
resolution: {integrity: sha512-FR22bzMW3VfoyZSBc8ScGo8ShrMWHmWB0G3FrispzWCnYSEEK5M7pyRvZtInKmM/09lsJETKc2q66mX+dXPSmg==}
engines: {node: '>=18'}
resolve-pkg-maps@1.0.0:
@ -8567,7 +8567,7 @@ snapshots:
dependencies:
undici-types: 6.19.8
'@types/node@20.17.24':
'@types/node@20.17.32':
dependencies:
undici-types: 6.19.8
optional: true
@ -8580,7 +8580,7 @@ snapshots:
'@types/pg@8.11.6':
dependencies:
'@types/node': 20.17.24
'@types/node': 20.17.32
pg-protocol: 1.9.5
pg-types: 4.0.2
optional: true
@ -10927,7 +10927,7 @@ snapshots:
require-directory@2.1.1: {}
resend@4.3.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
resend@4.4.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies:
'@react-email/render': 1.0.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
transitivePeerDependencies:

View File

@ -43,25 +43,14 @@ export class ResendNewsletterProvider implements NewsletterProvider {
*/
async subscribe({ email }: SubscribeNewsletterParams): Promise<boolean> {
try {
// First, list all contacts to find the one with the matching email
const listResult = await this.resend.contacts.list({
// Check if the contact exists
const getResult = await this.resend.contacts.get({
email,
audienceId: this.audienceId,
});
if (listResult.error) {
console.error('Error listing contacts:', listResult.error);
return false;
}
// console.log('subscribe list result:', listResult);
// Check if the contact with the given email exists in the list
let contact = null;
if (listResult.data?.data && Array.isArray(listResult.data.data)) {
contact = listResult.data.data.find((c) => c.email === email);
}
// console.log('subscribe params:', { email, contact });
// If the contact does not exist, create a new one
if (!contact) {
// If contact doesn't exist, create a new one
if (getResult.error) {
console.log('Creating new contact', email);
const createResult = await this.resend.contacts.create({
email,
@ -69,7 +58,6 @@ export class ResendNewsletterProvider implements NewsletterProvider {
unsubscribed: false,
});
// console.log('subscribe create result:', createResult);
if (createResult.error) {
console.error('Error creating contact', createResult.error);
return false;
@ -78,20 +66,13 @@ export class ResendNewsletterProvider implements NewsletterProvider {
return true;
}
// If the contact already exists, update it
// NOTICE: we can not just create a new contact if this email already exists,
// because Resend will response 201, but user is not subscribed
// NOTICE: we can not update it with email if the contact not found, it will return 404,
// statusCode: 404, name: not_found, message: Contact not found
// If the contact exists, update it
const updateResult = await this.resend.contacts.update({
email,
audienceId: this.audienceId,
unsubscribed: false,
});
// console.log('subscribe update result:', updateResult);
// NOTICE: we can not request too many times, because of the rate limit of Resend
// statusCode: 429, name: rate_limit_exceeded, message: Too many requests, you can only make 2 requests per second.
if (updateResult.error) {
console.error('Error updating contact', updateResult.error);
return false;
@ -142,31 +123,21 @@ export class ResendNewsletterProvider implements NewsletterProvider {
email,
}: CheckSubscribeStatusParams): Promise<boolean> {
try {
// TODO: use get method to check if the contact exists with email,
// the new Resend API is not ready yet, so we use the old way to check
// First, list all contacts to find the one with the matching email
const listResult = await this.resend.contacts.list({
const result = await this.resend.contacts.get({
email,
audienceId: this.audienceId,
});
if (listResult.error) {
console.error('Error listing contacts:', listResult.error);
if (result.error) {
console.error('Error getting contact:', result.error);
return false;
}
// console.log('check newsletter params:', { email, listResult });
// Check if the contact with the given email exists in the list
if (listResult.data?.data && Array.isArray(listResult.data.data)) {
return listResult.data.data.some(
(contact) => contact.email === email && contact.unsubscribed === false
);
}
// console.log('check newsletter status:', { email, subscribed: false });
return false;
const status = !result.data?.unsubscribed;
console.log('Check subscribe status:', { email, status });
return status;
} catch (error) {
console.error('Error checking subscription status:', error);
console.error('Error checking subscribe status:', error);
return false;
}
}