From b72e586d06345f553d05dbfb9cfbe7ab2caf2e3c Mon Sep 17 00:00:00 2001 From: isra el Date: Sat, 15 Mar 2025 17:24:02 +0300 Subject: [PATCH] chore(api): send reminder emails to new inactive and free users --- api/src/billing/billing.module.ts | 4 +- api/src/mail/templates/inactive-new-user.hbs | 84 +++++++++++++++++ api/src/mail/templates/upgrade-to-pro.hbs | 94 ++++++++++++++++++++ api/src/users/users.module.ts | 11 ++- api/src/users/users.service.ts | 86 +++++++++++++++++- 5 files changed, 275 insertions(+), 4 deletions(-) create mode 100644 api/src/mail/templates/inactive-new-user.hbs create mode 100644 api/src/mail/templates/upgrade-to-pro.hbs diff --git a/api/src/billing/billing.module.ts b/api/src/billing/billing.module.ts index edd2f5f..2c03b9f 100644 --- a/api/src/billing/billing.module.ts +++ b/api/src/billing/billing.module.ts @@ -18,8 +18,8 @@ import { PolarWebhookPayload, PolarWebhookPayloadSchema } from './schemas/polar- { name: Subscription.name, schema: SubscriptionSchema }, { name: PolarWebhookPayload.name, schema: PolarWebhookPayloadSchema }, ]), - AuthModule, - UsersModule, + forwardRef(() => AuthModule), + forwardRef(() => UsersModule), forwardRef(() => GatewayModule), ], controllers: [BillingController], diff --git a/api/src/mail/templates/inactive-new-user.hbs b/api/src/mail/templates/inactive-new-user.hbs new file mode 100644 index 0000000..66f5b74 --- /dev/null +++ b/api/src/mail/templates/inactive-new-user.hbs @@ -0,0 +1,84 @@ + + + + + Get Started with textbee.dev + + + +
+
+ {{! }} +
+ +
+

Hello {{name}},

+ +

Thank you for signing up for SMS Gateway! We noticed you haven't + registered any devices yet.

+ +

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!
  • +
+ +

To get started, you'll need to register your first device:

+ +
+
+ 1 + Install the SMS Gateway app on your Android device +
+
+ 2 + Log in with your account credentials +
+
+ 3 + Grant the necessary permissions +
+
+ 4 + Start sending and receiving SMS! +
+
+ +
+ Register Your Device + Now +
+ +

If you have any questions or need assistance, please don't hesitate + to contact our support team 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 new file mode 100644 index 0000000..d08cdae --- /dev/null +++ b/api/src/mail/templates/upgrade-to-pro.hbs @@ -0,0 +1,94 @@ + + + + + Upgrade to Pro - textbee.dev + + + +
+
+ {{! }} +
+ +
+

Hello {{name}},

+ +

Thank you for using textbee.dev! We hope you're enjoying our service + so far.

+ +

We wanted to let you know that you're currently on our + Free Plan, which provides basic functionality. To + unlock the full potential of textbee.dev, consider upgrading to our + Pro Plan.

+ +

Plan Comparison:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureFree PlanPro Plan
Daily Message Limit50Unlimited
Monthly Recipient Limit5005,000
Device Limit1Unlimited
Bulk SMS Recipients50Unlimited
SupportBasicPriority
+ +
+ Upgrade to Pro Now +
+ +

If you have any questions about our plans or need assistance, please + feel free to contact us at + support@textbee.dev.

+ +

Best regards,
The textbee.dev Team

+
+ + +
+ + \ No newline at end of file diff --git a/api/src/users/users.module.ts b/api/src/users/users.module.ts index e7f5882..eb6b192 100644 --- a/api/src/users/users.module.ts +++ b/api/src/users/users.module.ts @@ -1,8 +1,11 @@ -import { Module } from '@nestjs/common' +import { forwardRef, Module } from '@nestjs/common' import { MongooseModule } from '@nestjs/mongoose' import { User, UserSchema } from './schemas/user.schema' import { UsersController } from './users.controller' import { UsersService } from './users.service' +import { BillingModule } from 'src/billing/billing.module' +import { Device, DeviceSchema } from 'src/gateway/schemas/device.schema' +import { MailModule } from 'src/mail/mail.module' @Module({ imports: [ @@ -11,7 +14,13 @@ import { UsersService } from './users.service' name: User.name, schema: UserSchema, }, + { + name: Device.name, + schema: DeviceSchema, + }, ]), + forwardRef(() => BillingModule), + MailModule, ], controllers: [UsersController], providers: [UsersService], diff --git a/api/src/users/users.service.ts b/api/src/users/users.service.ts index 12c2e00..18b7f23 100644 --- a/api/src/users/users.service.ts +++ b/api/src/users/users.service.ts @@ -2,10 +2,19 @@ import { HttpException, HttpStatus, Injectable } from '@nestjs/common' import { InjectModel } from '@nestjs/mongoose' import { User, UserDocument } from './schemas/user.schema' import { Model } from 'mongoose' +import { Cron, CronExpression } from '@nestjs/schedule' +import { MailService } from '../mail/mail.service' +import { BillingService } from '../billing/billing.service' +import { Device, DeviceDocument } from '../gateway/schemas/device.schema' @Injectable() export class UsersService { - constructor(@InjectModel(User.name) private userModel: Model) {} + constructor( + @InjectModel(User.name) private userModel: Model, + @InjectModel(Device.name) private deviceModel: Model, + private mailService: MailService, + private billingService: BillingService, + ) {} async findOne(params) { return await this.userModel.findOne(params) @@ -62,4 +71,79 @@ export class UsersService { return await userToUpdate.save() } + + + @Cron('0 19 * * *') // Every day at 7 PM + async sendEmailToInactiveNewUsers() { + try { + // Get users who signed up in the last 24 hours + const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000) + const newUsers = await this.userModel.find({ + createdAt: { $gte: 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}`) + } + } + } catch (error) { + console.error('Error sending emails to inactive new users:', error) + } + } + + + @Cron('0 20 * * *') // Every day at 8 PM + async sendEmailToFreeUsers() { + try { + // Get users who signed up in the last 3 days + const threeDaysAgo = new Date(Date.now() - 3 * 24 * 60 * 60 * 1000) + const recentUsers = await this.userModel.find({ + createdAt: { $gte: threeDaysAgo }, + }) + + for (const user of recentUsers) { + // 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}`) + } + } + } catch (error) { + console.error('Error sending emails to free plan users:', error) + } + } }