chore: add loger for the telegram sender
This commit is contained in:
@@ -7,11 +7,13 @@ import { ConfigModule } from "@nestjs/config";
|
||||
import { ThrottlerModule } from "@nestjs/throttler";
|
||||
import { TypeOrmModule } from "@nestjs/typeorm";
|
||||
import { MailerModule } from "@nestjs-modules/mailer";
|
||||
import { TelegrafModule } from "nestjs-telegraf";
|
||||
|
||||
import { bullMqConfig } from "./configs/bullmq.config";
|
||||
import { cacheConfig } from "./configs/cache.config";
|
||||
import { mailerConfig } from "./configs/mailer.config";
|
||||
import { rateLimitConfig } from "./configs/rateLimit.config";
|
||||
import { telegrafConfig } from "./configs/telegraf.config";
|
||||
import { databaseConfigs } from "./configs/typeorm.config";
|
||||
import { HTTPLogger } from "./core/middlewares/logger.middleware";
|
||||
import { AddressModule } from "./modules/address/address.module";
|
||||
@@ -24,6 +26,7 @@ import { DanakServicesModule } from "./modules/danak-services/danak-services.mod
|
||||
import { DashboardModule } from "./modules/dashboards/dashboard.module";
|
||||
import { InvoicesModule } from "./modules/invoices/invoices.module";
|
||||
import { LearningModule } from "./modules/learnings/learning.module";
|
||||
import { LoggerModule } from "./modules/logger/logger.module";
|
||||
import { NotificationModule } from "./modules/notifications/notifications.module";
|
||||
import { PaymentsModule } from "./modules/payments/payments.module";
|
||||
import { SettingModule } from "./modules/settings/settings.module";
|
||||
@@ -35,6 +38,7 @@ import { WalletsModule } from "./modules/wallets/wallets.module";
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TelegrafModule.forRootAsync(telegrafConfig()),
|
||||
MailerModule.forRootAsync(mailerConfig()),
|
||||
BullModule.forRootAsync(bullMqConfig()),
|
||||
ThrottlerModule.forRootAsync(rateLimitConfig()),
|
||||
@@ -61,6 +65,7 @@ import { WalletsModule } from "./modules/wallets/wallets.module";
|
||||
AdsModule,
|
||||
AddressModule,
|
||||
DashboardModule,
|
||||
LoggerModule,
|
||||
],
|
||||
controllers: [],
|
||||
providers: [],
|
||||
|
||||
@@ -9,10 +9,9 @@ export function bullMqConfig(): SharedBullAsyncConfiguration {
|
||||
url: configService.getOrThrow<string>("REDIS_URI"),
|
||||
},
|
||||
defaultJobOptions: {
|
||||
removeOnComplete: 2000, // Consider lower values in high-volume production
|
||||
removeOnFail: 5000, // Consider lower values to reduce Redis memory usage
|
||||
attempts: 3, // Reasonable default, adjust based on job criticality
|
||||
backoff: { type: "exponential", delay: 2000 }, // Consider adding for better retry behavior
|
||||
removeOnComplete: false,
|
||||
removeOnFail: false,
|
||||
attempts: 5, // Reasonable default, adjust based on job criticality
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { ConfigService } from "@nestjs/config";
|
||||
import { TelegrafModuleAsyncOptions } from "nestjs-telegraf";
|
||||
|
||||
export function telegrafConfig(): TelegrafModuleAsyncOptions {
|
||||
return {
|
||||
inject: [ConfigService],
|
||||
useFactory: async (configService: ConfigService) => ({
|
||||
token: configService.getOrThrow<string>("TELEGRAM_BOT_TOKEN"),
|
||||
botName: configService.getOrThrow<string>("TELEGRAM_BOT_NAME"),
|
||||
}),
|
||||
};
|
||||
}
|
||||
@@ -5,7 +5,7 @@ export const ANNOUNCEMENT = Object.freeze({
|
||||
//
|
||||
ANNOUNCEMENT_SEND_JOB_PRIORITY: 1,
|
||||
ANNOUNCEMENT_SEND_JOB_ATTEMPTS: 3,
|
||||
ANNOUNCEMENT_SEND_JOB_BACKOFF: 1000,
|
||||
ANNOUNCEMENT_SEND_JOB_BACKOFF: 5 * 1000,
|
||||
ANNOUNCEMENT_SEND_JOB_TIMEOUT: 10000,
|
||||
//
|
||||
ANNOUNCEMENT_PUBLISH_JOB_PRIORITY: 1,
|
||||
|
||||
@@ -57,7 +57,7 @@ export class AnnouncementService {
|
||||
{
|
||||
delay: dayjs(announcement.publishAt).diff(dayjs(), "millisecond"),
|
||||
attempts: ANNOUNCEMENT.ANNOUNCEMENT_SEND_JOB_ATTEMPTS,
|
||||
backoff: ANNOUNCEMENT.ANNOUNCEMENT_SEND_JOB_BACKOFF,
|
||||
backoff: { type: "exponential", delay: ANNOUNCEMENT.ANNOUNCEMENT_SEND_JOB_BACKOFF },
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -3,17 +3,17 @@ export const INVOICE = Object.freeze({
|
||||
INVOICE_REMINDER_JOB_NAME: "reminderInvoice",
|
||||
INVOICE_RECURRING_JOB_NAME: "recurringInvoice",
|
||||
//
|
||||
INVOICE_REMINDER_JOB_PRIORITY: 1, // High priority
|
||||
INVOICE_REMINDER_JOB_ATTEMPTS: 3, // Retry 3 times
|
||||
INVOICE_REMINDER_JOB_BACKOFF: 1000, // Retry after 1 second
|
||||
INVOICE_REMINDER_JOB_TIMEOUT: 10000, // Timeout after 10 seconds
|
||||
INVOICE_REMINDER_REPEAT_DELAY: 86400000, // 1 day delay in milliseconds
|
||||
INVOICE_REMINDER_JOB_PRIORITY: 1, // high priority
|
||||
INVOICE_REMINDER_JOB_ATTEMPTS: 3, // 3 times
|
||||
INVOICE_REMINDER_JOB_BACKOFF: 5 * 1000, // ms
|
||||
INVOICE_REMINDER_JOB_TIMEOUT: 10000, // timeout after 10 seconds
|
||||
INVOICE_REMINDER_REPEAT_DELAY: 1 * 24 * 60 * 60 * 1000, // 1 day delay in milliseconds
|
||||
//
|
||||
|
||||
INVOICE_RECURRING_JOB_PRIORITY: 1, // High priority
|
||||
INVOICE_RECURRING_JOB_ATTEMPTS: 3, // Retry 3 times
|
||||
INVOICE_RECURRING_JOB_BACKOFF: 1000, // Retry after 1 second
|
||||
INVOICE_RECURRING_JOB_TIMEOUT: 10000, // Timeout after 10 seconds
|
||||
INVOICE_RECURRING_JOB_PRIORITY: 1, // high priority
|
||||
INVOICE_RECURRING_JOB_ATTEMPTS: 3, // retry 3 times
|
||||
INVOICE_RECURRING_JOB_BACKOFF: 5 * 1000, // retry after 1 second
|
||||
INVOICE_RECURRING_JOB_TIMEOUT: 10000, // timeout after 10 seconds
|
||||
//
|
||||
FINE_PERCENTAGE: 0.01, // 1% of the total price
|
||||
MAX_DAYS_AFTER_OVERDUE: 10,
|
||||
|
||||
@@ -18,9 +18,11 @@ import { UtilsModule } from "../utils/utils.module";
|
||||
import { WalletsModule } from "../wallets/wallets.module";
|
||||
import { InvoiceProcessor } from "./queue/invoice.processor";
|
||||
import { InvoiceItemsRepository } from "./repositories/invoice-items.repository";
|
||||
import { LoggerModule } from "../logger/logger.module";
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
LoggerModule,
|
||||
BullModule.registerQueue({ name: INVOICE.INVOICE_QUEUE_NAME }),
|
||||
TypeOrmModule.forFeature([Invoice, InvoiceItem, Discount, UsageDiscount]),
|
||||
UsersModule,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { InjectQueue, Processor } from "@nestjs/bullmq";
|
||||
import { Logger } from "@nestjs/common";
|
||||
import { Job, Queue } from "bullmq";
|
||||
import dayjs from "dayjs";
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
@@ -7,6 +6,7 @@ import Decimal from "decimal.js";
|
||||
import { DataSource, QueryRunner } from "typeorm";
|
||||
|
||||
import { WorkerProcessor } from "../../../common/queues/worker.processor";
|
||||
import { LoggerService } from "../../logger/logger.service";
|
||||
import { NotificationsService } from "../../notifications/providers/notifications.service";
|
||||
import { SubscriptionStatus } from "../../subscriptions/enums/subscription-status.enum";
|
||||
import { User } from "../../users/entities/user.entity";
|
||||
@@ -16,21 +16,22 @@ import { Invoice } from "../entities/invoice.entity";
|
||||
import { InvoiceStatus } from "../enums/invoice-status.enum";
|
||||
import { InvoicesService } from "../providers/invoices.service";
|
||||
|
||||
@Processor(INVOICE.INVOICE_QUEUE_NAME)
|
||||
@Processor(INVOICE.INVOICE_QUEUE_NAME, { concurrency: 5 })
|
||||
export class InvoiceProcessor extends WorkerProcessor {
|
||||
protected readonly logger = new Logger(InvoiceProcessor.name);
|
||||
// protected readonly logger = new Logger(InvoiceProcessor.name);
|
||||
|
||||
constructor(
|
||||
@InjectQueue(INVOICE.INVOICE_QUEUE_NAME) private readonly invoiceQueue: Queue,
|
||||
private readonly invoicesService: InvoicesService,
|
||||
private readonly dataSource: DataSource,
|
||||
private readonly notificationService: NotificationsService,
|
||||
protected readonly logger: LoggerService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async process(job: Job, token?: string) {
|
||||
this.logger.log(job, token);
|
||||
this.logger.log(job);
|
||||
switch (job.name) {
|
||||
case INVOICE.INVOICE_REMINDER_JOB_NAME:
|
||||
return this.sendBillInvoiceReminder(job, token);
|
||||
@@ -234,7 +235,7 @@ export class InvoiceProcessor extends WorkerProcessor {
|
||||
{
|
||||
delay: INVOICE.INVOICE_REMINDER_REPEAT_DELAY, // 1 day delay in milliseconds
|
||||
attempts: INVOICE.INVOICE_REMINDER_JOB_ATTEMPTS,
|
||||
backoff: INVOICE.INVOICE_REMINDER_JOB_BACKOFF,
|
||||
backoff: { type: "exponential", delay: INVOICE.INVOICE_REMINDER_JOB_BACKOFF },
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -261,7 +262,7 @@ export class InvoiceProcessor extends WorkerProcessor {
|
||||
};
|
||||
|
||||
await Promise.all(
|
||||
admins.map((admin) => this.notificationService.createRucurringInvoiceNotification(admin.id, notificationPayload, queryRunner)),
|
||||
admins.map((admin) => this.notificationService.createRecurringInvoiceNotification(admin.id, notificationPayload, queryRunner)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
|
||||
import { LoggerService } from "./logger.service";
|
||||
|
||||
@Module({
|
||||
providers: [LoggerService],
|
||||
exports: [LoggerService],
|
||||
})
|
||||
export class LoggerModule {}
|
||||
@@ -0,0 +1,43 @@
|
||||
import { Injectable, Logger } from "@nestjs/common";
|
||||
import { ConfigService } from "@nestjs/config";
|
||||
import { InjectBot } from "nestjs-telegraf";
|
||||
import { Telegraf } from "telegraf";
|
||||
|
||||
@Injectable()
|
||||
export class LoggerService extends Logger {
|
||||
private chatId: string;
|
||||
|
||||
constructor(
|
||||
@InjectBot() private bot: Telegraf,
|
||||
private configService: ConfigService,
|
||||
) {
|
||||
super();
|
||||
this.chatId = this.configService.getOrThrow<string>("TELEGRAM_CHAT_ID");
|
||||
}
|
||||
|
||||
async sendLogToTelegram(level: string, message: string) {
|
||||
try {
|
||||
const logMessage = `🚨 *${level.toUpperCase()} Log:*\n${message}`;
|
||||
await this.bot.telegram.sendMessage(this.chatId, logMessage, {
|
||||
parse_mode: "Markdown",
|
||||
});
|
||||
} catch (error) {
|
||||
super.error(`Failed to send log to Telegram:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
override log(message: any) {
|
||||
this.sendLogToTelegram("test", message);
|
||||
super.log(message);
|
||||
}
|
||||
|
||||
override error(message: any, trace?: any) {
|
||||
super.error(message, trace);
|
||||
this.sendLogToTelegram("error", `${message}\nTrace: ${trace}`);
|
||||
}
|
||||
|
||||
override warn(message: any) {
|
||||
super.warn(message);
|
||||
this.sendLogToTelegram("warn", message);
|
||||
}
|
||||
}
|
||||
@@ -317,7 +317,7 @@ export class NotificationsService {
|
||||
|
||||
// //************************ */
|
||||
|
||||
async createRucurringInvoiceNotification(recipientId: string, data: IInvoiceNotificationData, queryRunner: QueryRunner) {
|
||||
async createRecurringInvoiceNotification(recipientId: string, data: IInvoiceNotificationData, queryRunner: QueryRunner) {
|
||||
const message = NotificationMessage.RECURRING_INVOICE_MESSAGE.replace("[invoiceNumber]", data.invoiceId);
|
||||
//sent notification based on the userSettings
|
||||
const { isActive } = await this.userSettingsService.getUserNotificationSettingWithType(NotifType.RECURRING_INVOICE, recipientId);
|
||||
|
||||
Reference in New Issue
Block a user