Skip to content

Commit

Permalink
Merge pull request #12 from poojakarma/push_notification_changes
Browse files Browse the repository at this point in the history
PS- 2201 Push notification changes
  • Loading branch information
snehal0904 authored Oct 25, 2024
2 parents 8a00ade + 45bbdb4 commit 9b46160
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 121 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@
"@nestjs/config": "^2.3.0",
"@nestjs/core": "^8.4.7",
"@nestjs/platform-express": "^8.0.0",
"@nestjs/typeorm": "^8.1.4",
"@nestjs/swagger": "^7.3.1",
"@nestjs/typeorm": "^8.1.4",
"@types/amqplib": "^0.10.5",
"amqp-connection-manager": "^4.1.14",
"axios": "^1.6.5",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"dotenv": "^16.0.1",
"firebase-admin": "^12.6.0",
"notifme-sdk": "^1.11.0",
"pg": "^8.11.3",
"reflect-metadata": "^0.1.13",
Expand Down
4 changes: 2 additions & 2 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { NotificationEventsModule } from './modules/notification_events/notifica
import { NotificationModule } from './modules/notification/notification.module';
import { DatabaseModule } from './common/database-modules';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { LoggerModule } from './logger/logger.module';
// import { LoggerModule } from './logger/logger.module';
import { NotificationQueueModule } from './modules/notification-queue/notificationQueue.module';
import { RabbitmqModule } from './modules/rabbitmq/rabbitmq.module';

Expand All @@ -15,7 +15,7 @@ import { RabbitmqModule } from './modules/rabbitmq/rabbitmq.module';
ConfigModule.forRoot({ isGlobal: true }),
DatabaseModule,
RabbitmqModule,
NotificationEventsModule, NotificationModule, LoggerModule, NotificationQueueModule],
NotificationEventsModule, NotificationModule, NotificationQueueModule],
controllers: [AppController],
providers: [AppService, ConfigService],
})
Expand Down
27 changes: 27 additions & 0 deletions src/common/utils/constant.util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export const SUCCESS_MESSAGES = {
NOTIFICATION_COMPLETED: 'Notification process completed',
SEND_NOTIFICATION: '/send Notification',
NOTIFICATION_QUEUE_SAVE_SUCCESSFULLY: 'Notification saved in queue successfully',
NOTIFICATION_SENT_SUCCESSFULLY: 'Notification sent successfully',
PUSH_NOTIFICATION_SEND_SUCCESSFULLY: 'Push notification sent successfully',



};
export const ERROR_MESSAGES = {
INVALID_REQUEST: "Invalid request",
NOT_FOUND: "Not found",
UNAUTHORIZED: "Unauthorized",
FORBIDDEN: "Forbidden",
BAD_REQUEST: "Bad request",
INVALID_REQUEST_BODY: "Invalid request body",
INTERNAL_SERVER_ERROR: "Internal Server Error",
TEMPLATE_NOTFOUND: 'Template not found',
NOTIFICATION_FAILED: `Failed to Send Notification`,
TEMPLATE_CONFIG_NOTFOUND: 'Template Config not found for this context: ',
NOTIFICATION_QUEUE_SAVE_FAILED: 'Failed to save notifications in queue',
NOTIFICATION_LOG_SAVE_FAILED: 'Failed to save Log of notification',
TOPIC_NOTIFICATION_FAILED: 'Failed to send topic notification',
PUSH_NOTIFICATION_FAILED: 'Failed to send push notification'

}
30 changes: 0 additions & 30 deletions src/logger/logger.module.ts

This file was deleted.

91 changes: 51 additions & 40 deletions src/modules/notification/adapters/pushService.adapter.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,51 @@
import { BadRequestException, Inject, Injectable, forwardRef } from "@nestjs/common";
import { Inject, Injectable, forwardRef } from "@nestjs/common";
import { NotificationServiceInterface } from "../interface/notificationService";
import { NotificationDto } from "../dto/notificationDto.dto";
import axios from "axios";
import * as admin from "firebase-admin";
import { ConfigService } from "@nestjs/config";
import { NotificationLog } from "../entity/notificationLogs.entity";
import { NotificationService } from "../notification.service";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import { NotificationActions } from "src/modules/notification_events/entity/notificationActions.entity";
import { NotificationActionTemplates } from "src/modules/notification_events/entity/notificationActionTemplates.entity";
import { LoggerService } from "src/common/logger/logger.service";
import { ERROR_MESSAGES, SUCCESS_MESSAGES } from "src/common/utils/constant.util";

@Injectable()
export class PushAdapter implements NotificationServiceInterface {
private fcmkey: string;
private fcmurl: string
private readonly fcmurl: string;
constructor(
@Inject(forwardRef(() => NotificationService)) private readonly notificationServices: NotificationService,
private readonly configService: ConfigService,
@InjectRepository(NotificationActions)
private notificationEventsRepo: Repository<NotificationActions>,
@InjectRepository(NotificationActionTemplates)
private notificationTemplateConfigRepository: Repository<NotificationActionTemplates>,
private logger: LoggerService
private readonly logger: LoggerService
) {
this.fcmkey = this.configService.get('FCM_KEY');
this.fcmurl = this.configService.get('FCM_URL')
this.fcmurl = this.configService.get('FCM_URL');

// Initialize Firebase Admin SDK with environment variables
const serviceAccount = {
projectId: this.configService.get('FIREBASE_PROJECT_ID'),
clientEmail: this.configService.get('FIREBASE_CLIENT_EMAIL'),
privateKey: this.configService.get('FIREBASE_PRIVATE_KEY').replace(/\\n/g, '\n'), // Replace escaped newlines
};

if (admin.apps.length === 0) {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
}
}
async sendNotification(notificationDataArray) {
const results = [];
for (const notificationData of notificationDataArray) {
try {
const result = await this.send(notificationData);
// return result;
if (result.data.success === 1) {
if (result.status === 200 && result.data.name) {
results.push({
recipient: notificationData.recipient,
status: 200,
result: 'Push notification sent successfully'
result: SUCCESS_MESSAGES.PUSH_NOTIFICATION_SEND_SUCCESSFULLY
});
} else if (result.data.failure === 1) {
throw new Error('Invalid token');
}

}
catch (error) {
this.logger.error('Failed to send push notification', error);
this.logger.error(ERROR_MESSAGES.PUSH_NOTIFICATION_FAILED, error.toString());
results.push({
recipient: notificationData.recipient,
status: 'error',
Expand All @@ -70,38 +71,48 @@ export class PushAdapter implements NotificationServiceInterface {
const notificationLogs = this.createNotificationLog(notificationData.context, notificationData.subject, notificationData.key, notificationData.body, notificationData.recipient);
try {
const notification = {
notification: {
title: notificationData.subject,
body: notificationData.body,
},
to: notificationData.recipient
};
message: {
notification: {
title: notificationData.subject,
body: notificationData.body,
},
token: notificationData.recipient
}
}

// Retrieve OAuth 2.0 access token
const accessToken = await this.getAccessToken(); // Function to get token

const result = await axios.post(this.fcmurl, notification, {
headers: {
'Content-Type': 'application/json',
Authorization: `key=${this.fcmkey}`,
Authorization: `Bearer ${accessToken}`,
},
});
if (result.data.success === 1) {
this.logger.log('Push notification sent successful')

if (result.status === 200 && result.data.name) {
this.logger.log('Push notification sent successfully');
notificationLogs.status = true;
await this.notificationServices.saveNotificationLogs(notificationLogs);
return result;
} else {
this.logger.log(ERROR_MESSAGES.PUSH_NOTIFICATION_FAILED);
throw new Error(ERROR_MESSAGES.PUSH_NOTIFICATION_FAILED);
}
if (result.data.failure === 1) {
throw new Error('Invalid token');
}
throw new Error('Unknown response from FCM server');
} catch (error) {
this.logger.error(
`Failed to Send Push Notification for ${notificationData.context}`,
error,
'/Not able to send Notification',
);
notificationLogs.status = false;
notificationLogs.error = error.toString();
await this.notificationServices.saveNotificationLogs(notificationLogs);
throw error;
}
}

async getAccessToken() {
const token = await admin.credential.cert({
projectId: this.configService.get('FIREBASE_PROJECT_ID'),
clientEmail: this.configService.get('FIREBASE_CLIENT_EMAIL'),
privateKey: this.configService.get('FIREBASE_PRIVATE_KEY').replace(/\\n/g, '\n'),
}).getAccessToken();
return token.access_token;
}
}
Loading

0 comments on commit 9b46160

Please sign in to comment.