Skip to content

Commit bebaf8f

Browse files
committed
feat(emails): Handle expiring loyalty points and start sending a default email template
1 parent e6449a2 commit bebaf8f

File tree

2 files changed

+88
-1
lines changed

2 files changed

+88
-1
lines changed
Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,93 @@
11
import { logger } from '@cloudcommerce/firebase/lib/config';
2+
import api from '@cloudcommerce/api';
3+
import { sendEmail } from '@cloudcommerce/emails';
4+
import { getStore, getMailRender } from './util/emails-utils';
25

36
const sendPointsEmails = async () => {
4-
logger.info('@TODO');
7+
const store = getStore();
8+
if (store.lang && store.lang !== 'pt_br') {
9+
return;
10+
}
11+
const startDate = new Date();
12+
startDate.setDate(startDate.getDate() + 1);
13+
const endDate = new Date();
14+
endDate.setDate(endDate.getDate() + 10);
15+
const {
16+
data: { result: customers },
17+
} = await api.get('customers', {
18+
params: {
19+
'loyalty_points_entries.valid_thru>': startDate.toISOString(),
20+
'loyalty_points_entries.valid_thru<': endDate.toISOString(),
21+
'loyalty_points_entries.active_points>': 0,
22+
},
23+
fields: [
24+
'_id',
25+
'display_name',
26+
'main_email',
27+
'loyalty_points_entries',
28+
] as const,
29+
sort: ['-updated_at'],
30+
limit: 300,
31+
});
32+
if (!customers.length) {
33+
return;
34+
}
35+
const render = await getMailRender('generic');
36+
const subject = `Seus pontos na ${store.name} estão expirando`;
37+
const startDateTime = startDate.getTime();
38+
const endDateTime = endDate.getTime();
39+
for (let i = 0; i < customers.length; i++) {
40+
const customer = customers[i];
41+
const activePoints = customer.loyalty_points_entries?.filter((pointsEntry) => {
42+
if (!pointsEntry.active_points) return false;
43+
const validThruTime = pointsEntry.valid_thru
44+
&& new Date(pointsEntry.valid_thru).getTime();
45+
if (!validThruTime) return false;
46+
return validThruTime >= startDateTime && validThruTime <= endDateTime;
47+
});
48+
if (!activePoints?.length) continue;
49+
const pointsToExpire = activePoints.reduce((acc, pointsEntry) => {
50+
return acc + pointsEntry.active_points;
51+
}, 0);
52+
if (pointsToExpire > 0) {
53+
// eslint-disable-next-line no-await-in-loop
54+
const html = await render(
55+
store,
56+
{
57+
'title': subject,
58+
'subtitle': 'Você tem pontos na loja, utilize antes de expirar ;)',
59+
'body': `
60+
Compre em nossa loja com desconto usando os
61+
<b>${pointsToExpire} pontos</b>
62+
ativos na sua conta.
63+
Aproveite enquanto os pontos estão disponíveis,
64+
<b>seus pontos estão expirando nos próximos dias!</b>
65+
`,
66+
'button_text': 'Usar meus pontos',
67+
'button_link': `https://${store.domain}/`
68+
+ '?utm_source=ecomplus&utm_medium=email&utm_campaign=loyalty_points',
69+
},
70+
'pt_br',
71+
);
72+
if (html) {
73+
// eslint-disable-next-line no-await-in-loop
74+
await sendEmail(
75+
{
76+
to: [{
77+
name: customer.display_name,
78+
email: customer.main_email,
79+
}],
80+
subject,
81+
html,
82+
},
83+
);
84+
logger.info(`Sending points expiration email to ${customer.main_email}`, {
85+
customer,
86+
html,
87+
});
88+
}
89+
}
90+
}
591
};
692

793
export default sendPointsEmails;

packages/apps/emails/src/transactional-emails.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const emails = {
2121
}),
2222

2323
cronExpiringPoints: functions.region(region)
24+
.runWith({ timeoutSeconds: 540 })
2425
.pubsub
2526
.schedule(process.env.CRONTAB_EMAILS_EXPIRING_POINTS || '37 14 * * 1,4')
2627
.onRun(() => {

0 commit comments

Comments
 (0)