Skip to content

Commit c9b692d

Browse files
author
Lauren Pothuru
committed
Debug property fetching
- Fix relative vs absolute path in property fetch - Add info to README
1 parent 87855a9 commit c9b692d

File tree

2 files changed

+96
-91
lines changed

2 files changed

+96
-91
lines changed

backend/scripts/email/README.MD

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ reminders, etc.
66

77
## Infrastructure
88

9-
This system is built on top of [Resend](https://resend.com)'s email API.
9+
This system is built on top of [Resend](https://resend.com)'s email API.
1010

1111
## Getting Started
1212

@@ -20,14 +20,16 @@ This system is built on top of [Resend](https://resend.com)'s email API.
2020

2121
```
2222
RESEND_API_KEY=your_resend_api_key # contact TPM for access
23-
GLOBAL_FROM_NAME=CUApts # what the name of the sender will be
24-
GLOBAL_FROM_EMAIL=[email protected] # what the email of the sender will be
23+
GLOBAL_FROM_NAME= CUApts # what the name of the sender will be
24+
GLOBAL_FROM_EMAIL= cuapts.org # what the email of the sender will be
2525
```
2626

2727
**Never commit this file!** (Should already be in `.gitignore`.)
2828

2929
3. Create a new template in `scripts/email/templates/` or modify the existing
30-
`GenerateNewsletter.tsx` template.
30+
`GenerateNewsletter.tsx` template. Make sure to test out the formatting in multiple email
31+
services (ex: gmail vs apple mail). Each service will result in slightly different outputs, so
32+
ensure that your template is consistent throughout.
3133

3234
4. Update the `emailService.ts` file to use your template and customize the campaign options.
3335

backend/scripts/email/emailService.ts

Lines changed: 90 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ if (!global.fetch) {
1515
global.Request = Request as unknown as typeof global.Request;
1616
}
1717

18+
const API_BASE_URL = process.env.API_BASE_URL || 'http://localhost:3000';
19+
1820
type EmailCampaignOptions = {
1921
subject?: string;
2022
toEmail?: string;
@@ -42,7 +44,7 @@ const sendEmailCampaign = async (options: EmailCampaignOptions = {}): Promise<vo
4244
// Load environment variables
4345
dotenv.config({ path: path.resolve(process.cwd(), '.env.dev') });
4446

45-
const fromEmail = process.env.GLOBAL_FROM_EMAIL ?? '[email protected]';
47+
const fromEmail = 'updates.cuapts.org';
4648
const fromName = 'CU Apts';
4749

4850
const apiKey = process.env.RESEND_API_KEY;
@@ -51,7 +53,7 @@ const sendEmailCampaign = async (options: EmailCampaignOptions = {}): Promise<vo
5153
return;
5254
}
5355

54-
const { API_BASE_URL } = process.env;
56+
// const { API_BASE_URL } = process.env;
5557

5658
/**
5759
* getPropertiesByIds
@@ -79,96 +81,94 @@ const sendEmailCampaign = async (options: EmailCampaignOptions = {}): Promise<vo
7981
}
8082
};
8183

82-
try {
83-
console.log(`Total users available in database: ${USERS.length}`);
84-
const validEmails = USERS.filter((user) => user.email && user.email.includes('@'));
85-
console.log(`Valid email addresses: ${validEmails.length}`);
86-
87-
if (validEmails.length === 0) {
88-
console.error('No valid email addresses found!');
89-
return;
90-
}
91-
92-
// loads chosen properties
93-
const recentLandlordProperties = options.recentLandlordPropertyIDs
94-
? await getPropertiesByIds(options.recentLandlordPropertyIDs)
95-
: [];
96-
const lovedProperties = options.lovedPropertyIds
97-
? await getPropertiesByIds(options.lovedPropertyIds)
98-
: [];
99-
const recentAreaProperties = options.recentAreaPropertyIDs
100-
? await getPropertiesByIds(options.recentAreaPropertyIDs)
101-
: [];
102-
103-
console.log(
104-
`Fetched ${recentLandlordProperties.length} recent properties (landlord highlight), ${lovedProperties.length} loved properties (landlord highlight), and ${recentAreaProperties.length} recent properties (area spotlight).`
105-
);
106-
107-
const resend = new Resend(apiKey);
108-
109-
const userBatches = await getUserBatches(50);
110-
console.log(
111-
`Preparing to send emails to ${userBatches.length} batches of users (${50} per batch)`
112-
);
113-
114-
const emailPromises = userBatches.map(async (batch, i) => {
115-
const bccEmails = batch.map((user) => user.email);
116-
console.log(
117-
`Preparing batch ${i + 1}/${userBatches.length} with ${bccEmails.length} recipients`
118-
);
119-
120-
const { data, error } = await resend.emails.send({
121-
from: `${fromName} <${fromEmail}>`,
122-
to: toEmail,
123-
// bcc: bccEmails,
124-
subject,
125-
react: React.createElement(GenerateNewsletter, {
126-
recentLandlordProperties,
127-
lovedProperties,
128-
recentAreaProperties,
129-
}),
130-
});
131-
132-
if (error) {
133-
console.error(`Error sending batch ${i + 1}:`, error);
134-
} else {
135-
console.log(`Batch ${i + 1} sent successfully! ID:`, data?.id || 'no ID returned');
136-
}
137-
});
138-
139-
await Promise.all(emailPromises);
140-
console.log('All email batches sent successfully!');
141-
} catch (err) {
142-
console.error('Exception when sending emails:', err);
143-
throw err;
144-
}
84+
// try {
85+
// console.log(`Total users available in database: ${USERS.length}`);
86+
// const validEmails = USERS.filter((user) => user.email && user.email.includes('@'));
87+
// console.log(`Valid email addresses: ${validEmails.length}`);
88+
89+
// if (validEmails.length === 0) {
90+
// console.error('No valid email addresses found!');
91+
// return;
92+
// }
93+
94+
// loads chosen properties
95+
const recentLandlordProperties = options.recentLandlordPropertyIDs
96+
? await getPropertiesByIds(options.recentLandlordPropertyIDs)
97+
: [];
98+
const lovedProperties = options.lovedPropertyIds
99+
? await getPropertiesByIds(options.lovedPropertyIds)
100+
: [];
101+
const recentAreaProperties = options.recentAreaPropertyIDs
102+
? await getPropertiesByIds(options.recentAreaPropertyIDs)
103+
: [];
104+
105+
console.log(
106+
`Fetched ${recentLandlordProperties.length} recent properties (landlord highlight), ${lovedProperties.length} loved properties (landlord highlight), and ${recentAreaProperties.length} recent properties (area spotlight).`
107+
);
108+
109+
const resend = new Resend(apiKey);
110+
111+
// const userBatches = await getUserBatches(50);
112+
// console.log(
113+
// `Preparing to send emails to ${userBatches.length} batches of users (${50} per batch)`
114+
// );
115+
116+
// const emailPromises = userBatches.map(async (batch, i) => {
117+
// const bccEmails = batch.map((user) => user.email);
118+
// console.log(
119+
// `Preparing batch ${i + 1}/${userBatches.length} with ${bccEmails.length} recipients`
120+
// );
121+
122+
// const { data, error } = await resend.emails.send({
123+
// from: `${fromName} <${fromEmail}>`,
124+
// to: toEmail,
125+
// // bcc: bccEmails,
126+
// subject,
127+
// react: React.createElement(GenerateNewsletter, {
128+
// recentLandlordProperties,
129+
// lovedProperties,
130+
// recentAreaProperties,
131+
// }),
132+
// });
133+
134+
// if (error) {
135+
// console.error(`Error sending batch ${i + 1}:`, error);
136+
// } else {
137+
// console.log(`Batch ${i + 1} sent successfully! ID:`, data?.id || 'no ID returned');
138+
// }
139+
// });
140+
141+
// await Promise.all(emailPromises);
142+
// console.log('All email batches sent successfully!');
143+
// } catch (err) {
144+
// console.error('Exception when sending emails:', err);
145+
// throw err;
146+
// }
145147

146148
/** Sends an email to one person (useful for testing email templates).
147149
* To use, uncomment code below, comment out lines 82-86 and 108-143, edit info below,
148150
* and run the file as normal.
149151
*/
150-
/*
151-
try {
152-
// In your main file
153-
const { data, error } = await resend.emails.send({
154-
from: 'onboarding@resend.dev',
155-
156-
subject: 'Hello World',
157-
react: React.createElement(GenerateNewsletter, {
158-
recentLandlordProperties,
159-
lovedProperties,
160-
recentAreaProperties,
161-
}),
162-
});
163-
if (error) {
164-
console.error('Error sending email:', error);
165-
} else {
166-
console.log('Email sent successfully! ID:', data ? data.id : ' no ID returned.');
167-
}
168-
} catch (err) {
169-
console.error('Exception when sending email:', err);
170-
}
171-
*/
152+
// try {
153+
// // In your main file
154+
// const { data, error } = await resend.emails.send({
155+
// from: '[email protected]',
156+
157+
// subject: subject,
158+
// react: React.createElement(GenerateNewsletter, {
159+
// recentLandlordProperties,
160+
// lovedProperties,
161+
// recentAreaProperties,
162+
// }),
163+
// });
164+
// if (error) {
165+
// console.error('Error sending email:', error);
166+
// } else {
167+
// console.log('Email sent successfully! ID:', data ? data.id : ' no ID returned.');
168+
// }
169+
// } catch (err) {
170+
// console.error('Exception when sending email:', err);
171+
// }
172172
};
173173

174174
/**
@@ -185,6 +185,9 @@ async function main() {
185185
// Customize email subject
186186
await sendEmailCampaign({
187187
subject: 'New Apartment Listings Available!',
188+
recentAreaPropertyIDs: ['12', '2', '24'],
189+
lovedPropertyIds: ['23', '24', '24'],
190+
recentLandlordPropertyIDs: ['14', '23', '24'],
188191
});
189192

190193
console.log('Campaign completed successfully!');

0 commit comments

Comments
 (0)