From 98d596e61ba7531e2e7c8f6b3bb877bcea3590d8 Mon Sep 17 00:00:00 2001 From: isra el Date: Sun, 16 Mar 2025 17:42:00 +0300 Subject: [PATCH] chore(api): update reminder emails --- .../templates/inactive-new-user-day-3.hbs | 85 ++++++++++++ api/src/mail/templates/upgrade-to-pro.hbs | 38 +++++- api/src/users/users.service.ts | 123 ++++++++++-------- 3 files changed, 193 insertions(+), 53 deletions(-) create mode 100644 api/src/mail/templates/inactive-new-user-day-3.hbs diff --git a/api/src/mail/templates/inactive-new-user-day-3.hbs b/api/src/mail/templates/inactive-new-user-day-3.hbs new file mode 100644 index 0000000..08c1b05 --- /dev/null +++ b/api/src/mail/templates/inactive-new-user-day-3.hbs @@ -0,0 +1,85 @@ + + + + + Get Started with textbee.dev + + + +
+
+
+ +
+

Hello {{name}},

+ +

We noticed it's been 3 days since you signed up for textbee.dev, but + you haven't registered any devices yet.

+ +

We'd love to help you get the most out of our platform! With + textbee.dev, you can:

+
    +
  • Send and receive SMS messages from your dashboard or API
  • +
  • Receive SMS notifications with webhooks
  • +
  • Integrate SMS functionality into your applications
  • +
  • And much more!
  • +
+ +

Getting started is quick and easy:

+ +
+
+ 1 + Install the textbee.dev android app on your device +
+
+ 2 + Grant the necessary permissions +
+
+ 3 + Login to your + dashboard + and generate a QR code +
+
+ 4 + Scan the QR code with the app to register your device +
+
+ 5 + Start sending and receiving SMS! +
+
+ +
+ Register Your Device + Now +
+ +

Is there anything we can help you with? If you're experiencing any + issues or have questions, our support team is ready to assist at + support@textbee.dev.

+ +

Best regards,
The textbee.dev Team

+
+ + +
+ + \ No newline at end of file diff --git a/api/src/mail/templates/upgrade-to-pro.hbs b/api/src/mail/templates/upgrade-to-pro.hbs index d08cdae..89c229e 100644 --- a/api/src/mail/templates/upgrade-to-pro.hbs +++ b/api/src/mail/templates/upgrade-to-pro.hbs @@ -25,7 +25,6 @@
- {{! }}
@@ -39,6 +38,12 @@ unlock the full potential of textbee.dev, consider upgrading to our Pro Plan.

+

Special Offer Just For You: + We're extending a + 30% discount + on all Pro plans exclusively for our most active users like you! This + offer is only available for a limited time.

+

Plan Comparison:

@@ -75,8 +80,39 @@
+
+

Pro + Plan Pricing

+
+
+

Monthly

+

$9.99 + $6.99

+

30% off - + limited time

+
+
+

Annual

+

$99.99 + $69.99

+

30% off - + limited time

+
+
+
+
Upgrade to Pro Now +

Hurry! This 30% discount offer is only available for a + limited time.

If you have any questions about our plans or need assistance, please diff --git a/api/src/users/users.service.ts b/api/src/users/users.service.ts index f933189..3c5077a 100644 --- a/api/src/users/users.service.ts +++ b/api/src/users/users.service.ts @@ -72,86 +72,105 @@ export class UsersService { return await userToUpdate.save() } - @Cron('0 12 * * *') // Every day at 12 PM async sendEmailToInactiveNewUsers() { try { // Get users who signed up between 24-48 hours ago (1-2 days ago) const twoDaysAgo = new Date(Date.now() - 48 * 60 * 60 * 1000) const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000) - + const newUsers = await this.userModel.find({ - createdAt: { + createdAt: { $gte: twoDaysAgo, - $lt: oneDayAgo + $lt: oneDayAgo, }, }) - for (const user of newUsers) { - // Check if user has any devices - const devices = await this.deviceModel.find({ user: user._id }) - - if (devices.length === 0) { - // User hasn't registered any device, send email - await this.mailService.sendEmailFromTemplate({ - to: user.email, - subject: 'Get Started with textbee.dev - Register Your First Device', - template: 'inactive-new-user', - context: { - name: user.name, - registerDeviceUrl: `${process.env.FRONTEND_URL}/dashboard`, - }, - }) - - console.log(`Sent inactive new user email to ${user.email}`) + const emailPromises = newUsers.map(async (user) => { + try { + // Check if user has any devices registered + const devices = await this.deviceModel.find({ user: user._id }) + + if (devices.length === 0) { + // User hasn't registered any device, send email + await this.mailService.sendEmailFromTemplate({ + to: user.email, + subject: + 'Get Started with textbee.dev - Register Your First Device', + template: 'inactive-new-user', + context: { + name: user.name, + registerDeviceUrl: `${process.env.FRONTEND_URL}/dashboard`, + }, + }) + + console.log(`Sent inactive new user email to ${user.email}`) + } + } catch (error) { + console.error(`Error processing email for user ${user.email}:`, error) } - } + }) + + await Promise.allSettled(emailPromises) } catch (error) { console.error('Error sending emails to inactive new users:', error) } } - @Cron('0 13 * * *') // Every day at 1 PM async sendEmailToFreeUsers() { try { - // Get users who signed up exactly 3 days ago (within a 24-hour window) + // Get users who signed up between 3-4 days ago const threeDaysAgo = new Date(Date.now() - 3 * 24 * 60 * 60 * 1000) const fourDaysAgo = new Date(Date.now() - 4 * 24 * 60 * 60 * 1000) - + const usersToEmail = await this.userModel.find({ - createdAt: { + createdAt: { $gte: fourDaysAgo, - $lt: threeDaysAgo + $lt: threeDaysAgo, }, }) - for (const user of usersToEmail) { - // Check if user is on free plan - const subscription = await this.billingService.getActiveSubscription(user._id.toString()) - - if (subscription && subscription.plan && subscription.plan.name === 'free') { - // User is still on free plan, send upgrade email - await this.mailService.sendEmailFromTemplate({ - to: user.email, - subject: 'Upgrade to Pro for More Features - textbee.dev', - template: 'upgrade-to-pro', - context: { - name: user.name, - upgradeUrl: `${process.env.FRONTEND_URL}/checkout/pro`, - features: [ - 'Increased SMS sending limits', - 'Priority support', - 'Unlimited devices', - 'Unlimited Bulk SMS Recipients', - 'and more...' - ] - }, - }) - - console.log(`Sent upgrade to pro email to ${user.email}`) + const emailPromises = usersToEmail.map(async (user) => { + try { + const subscription = await this.billingService.getActiveSubscription( + user._id.toString(), + ) + + if (subscription?.plan?.name === 'free') { + const devices = await this.deviceModel.find({ user: user._id }) + + if (devices.length === 0) { + await this.mailService.sendEmailFromTemplate({ + to: user.email, + subject: `${user.name?.split(' ')[0]}, Your textbee.dev account is waiting for you!`, + template: 'inactive-new-user-day-3', + context: { + name: user.name, + registerDeviceUrl: `${process.env.FRONTEND_URL}/dashboard`, + }, + }) + + console.log(`Sent inactive new user email to ${user.email}`) + } else { + await this.mailService.sendEmailFromTemplate({ + to: user.email, + subject: `${user.name?.split(' ')[0]}, Upgrade to Pro with a 30% Discount - textbee.dev`, + template: 'upgrade-to-pro', + context: { + name: user.name, + upgradeUrl: `${process.env.FRONTEND_URL}/checkout/pro`, + }, + }) + console.log(`Sent upgrade to pro email to ${user.email}`) + } + } + } catch (error) { + console.error(`Error processing email for user ${user.email}:`, error) } - } + }) + + await Promise.allSettled(emailPromises) } catch (error) { console.error('Error sending emails to free plan users:', error) }