refactor: optimize newsletter subscribe and check status logic
This commit is contained in:
parent
d94e777dde
commit
f607bae96e
@ -112,7 +112,7 @@
|
|||||||
"remark": "^15.0.1",
|
"remark": "^15.0.1",
|
||||||
"remark-code-import": "^1.2.0",
|
"remark-code-import": "^1.2.0",
|
||||||
"remark-gfm": "^4.0.1",
|
"remark-gfm": "^4.0.1",
|
||||||
"resend": "^4.3.0",
|
"resend": "^4.4.1",
|
||||||
"shiki": "^2.4.2",
|
"shiki": "^2.4.2",
|
||||||
"sonner": "^2.0.0",
|
"sonner": "^2.0.0",
|
||||||
"stripe": "^17.6.0",
|
"stripe": "^17.6.0",
|
||||||
|
18
pnpm-lock.yaml
generated
18
pnpm-lock.yaml
generated
@ -294,8 +294,8 @@ importers:
|
|||||||
specifier: ^4.0.1
|
specifier: ^4.0.1
|
||||||
version: 4.0.1
|
version: 4.0.1
|
||||||
resend:
|
resend:
|
||||||
specifier: ^4.3.0
|
specifier: ^4.4.1
|
||||||
version: 4.3.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
version: 4.4.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
shiki:
|
shiki:
|
||||||
specifier: ^2.4.2
|
specifier: ^2.4.2
|
||||||
version: 2.4.2
|
version: 2.4.2
|
||||||
@ -3197,8 +3197,8 @@ packages:
|
|||||||
'@types/node@20.17.23':
|
'@types/node@20.17.23':
|
||||||
resolution: {integrity: sha512-8PCGZ1ZJbEZuYNTMqywO+Sj4vSKjSjT6Ua+6RFOYlEvIvKQABPtrNkoVSLSKDb4obYcMhspVKmsw8Cm10NFRUg==}
|
resolution: {integrity: sha512-8PCGZ1ZJbEZuYNTMqywO+Sj4vSKjSjT6Ua+6RFOYlEvIvKQABPtrNkoVSLSKDb4obYcMhspVKmsw8Cm10NFRUg==}
|
||||||
|
|
||||||
'@types/node@20.17.24':
|
'@types/node@20.17.32':
|
||||||
resolution: {integrity: sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA==}
|
resolution: {integrity: sha512-zeMXFn8zQ+UkjK4ws0RiOC9EWByyW1CcVmLe+2rQocXRsGEDxUCwPEIVgpsGcLHS/P8JkT0oa3839BRABS0oPw==}
|
||||||
|
|
||||||
'@types/pg@8.11.11':
|
'@types/pg@8.11.11':
|
||||||
resolution: {integrity: sha512-kGT1qKM8wJQ5qlawUrEkXgvMSXoV213KfMGXcwfDwUIfUHXqXYXOfS1nE1LINRJVVVx5wCm70XnFlMHaIcQAfw==}
|
resolution: {integrity: sha512-kGT1qKM8wJQ5qlawUrEkXgvMSXoV213KfMGXcwfDwUIfUHXqXYXOfS1nE1LINRJVVVx5wCm70XnFlMHaIcQAfw==}
|
||||||
@ -5115,8 +5115,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
resend@4.3.0:
|
resend@4.4.1:
|
||||||
resolution: {integrity: sha512-4OBHeusMVSl0vcba2J3AaGzdZ1SXAAhX/Wkcwobe16AHmlW9h3li8wG62Fhvlsc61e+wlQoxcwJZP6WrBTbghQ==}
|
resolution: {integrity: sha512-FR22bzMW3VfoyZSBc8ScGo8ShrMWHmWB0G3FrispzWCnYSEEK5M7pyRvZtInKmM/09lsJETKc2q66mX+dXPSmg==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
resolve-pkg-maps@1.0.0:
|
resolve-pkg-maps@1.0.0:
|
||||||
@ -8567,7 +8567,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 6.19.8
|
undici-types: 6.19.8
|
||||||
|
|
||||||
'@types/node@20.17.24':
|
'@types/node@20.17.32':
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 6.19.8
|
undici-types: 6.19.8
|
||||||
optional: true
|
optional: true
|
||||||
@ -8580,7 +8580,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/pg@8.11.6':
|
'@types/pg@8.11.6':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.17.24
|
'@types/node': 20.17.32
|
||||||
pg-protocol: 1.9.5
|
pg-protocol: 1.9.5
|
||||||
pg-types: 4.0.2
|
pg-types: 4.0.2
|
||||||
optional: true
|
optional: true
|
||||||
@ -10927,7 +10927,7 @@ snapshots:
|
|||||||
|
|
||||||
require-directory@2.1.1: {}
|
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:
|
dependencies:
|
||||||
'@react-email/render': 1.0.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
'@react-email/render': 1.0.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
@ -43,25 +43,14 @@ export class ResendNewsletterProvider implements NewsletterProvider {
|
|||||||
*/
|
*/
|
||||||
async subscribe({ email }: SubscribeNewsletterParams): Promise<boolean> {
|
async subscribe({ email }: SubscribeNewsletterParams): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
// First, list all contacts to find the one with the matching email
|
// Check if the contact exists
|
||||||
const listResult = await this.resend.contacts.list({
|
const getResult = await this.resend.contacts.get({
|
||||||
|
email,
|
||||||
audienceId: this.audienceId,
|
audienceId: this.audienceId,
|
||||||
});
|
});
|
||||||
if (listResult.error) {
|
|
||||||
console.error('Error listing contacts:', listResult.error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log('subscribe list result:', listResult);
|
// If contact doesn't exist, create a new one
|
||||||
// Check if the contact with the given email exists in the list
|
if (getResult.error) {
|
||||||
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) {
|
|
||||||
console.log('Creating new contact', email);
|
console.log('Creating new contact', email);
|
||||||
const createResult = await this.resend.contacts.create({
|
const createResult = await this.resend.contacts.create({
|
||||||
email,
|
email,
|
||||||
@ -69,7 +58,6 @@ export class ResendNewsletterProvider implements NewsletterProvider {
|
|||||||
unsubscribed: false,
|
unsubscribed: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// console.log('subscribe create result:', createResult);
|
|
||||||
if (createResult.error) {
|
if (createResult.error) {
|
||||||
console.error('Error creating contact', createResult.error);
|
console.error('Error creating contact', createResult.error);
|
||||||
return false;
|
return false;
|
||||||
@ -78,20 +66,13 @@ export class ResendNewsletterProvider implements NewsletterProvider {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the contact already exists, update it
|
// If the contact 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
|
|
||||||
const updateResult = await this.resend.contacts.update({
|
const updateResult = await this.resend.contacts.update({
|
||||||
email,
|
email,
|
||||||
audienceId: this.audienceId,
|
audienceId: this.audienceId,
|
||||||
unsubscribed: false,
|
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) {
|
if (updateResult.error) {
|
||||||
console.error('Error updating contact', updateResult.error);
|
console.error('Error updating contact', updateResult.error);
|
||||||
return false;
|
return false;
|
||||||
@ -142,31 +123,21 @@ export class ResendNewsletterProvider implements NewsletterProvider {
|
|||||||
email,
|
email,
|
||||||
}: CheckSubscribeStatusParams): Promise<boolean> {
|
}: CheckSubscribeStatusParams): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
// TODO: use get method to check if the contact exists with email,
|
const result = await this.resend.contacts.get({
|
||||||
// the new Resend API is not ready yet, so we use the old way to check
|
email,
|
||||||
|
|
||||||
// First, list all contacts to find the one with the matching email
|
|
||||||
const listResult = await this.resend.contacts.list({
|
|
||||||
audienceId: this.audienceId,
|
audienceId: this.audienceId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (listResult.error) {
|
if (result.error) {
|
||||||
console.error('Error listing contacts:', listResult.error);
|
console.error('Error getting contact:', result.error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('check newsletter params:', { email, listResult });
|
const status = !result.data?.unsubscribed;
|
||||||
// Check if the contact with the given email exists in the list
|
console.log('Check subscribe status:', { email, status });
|
||||||
if (listResult.data?.data && Array.isArray(listResult.data.data)) {
|
return status;
|
||||||
return listResult.data.data.some(
|
|
||||||
(contact) => contact.email === email && contact.unsubscribed === false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log('check newsletter status:', { email, subscribed: false });
|
|
||||||
return false;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error checking subscription status:', error);
|
console.error('Error checking subscribe status:', error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user