Skip to content

Commit 71bca54

Browse files
author
Sachin Maheshwari
committed
initial bulk message developemnt.
1 parent c54be52 commit 71bca54

File tree

8 files changed

+228
-3
lines changed

8 files changed

+228
-3
lines changed

config/default.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ module.exports = {
5858
{
5959
id: 0, /** challengeid or projectid */
6060
name: '', /** challenge name */
61-
group: 'Challenge',
61+
group: 'challenge',
6262
title: 'Challenge specification is modified.',
6363
},
6464
},
@@ -75,7 +75,7 @@ module.exports = {
7575
{
7676
id: 0, /** challengeid or projectid */
7777
name: '', /** challenge name */
78-
group: 'Challenge',
78+
group: 'challenge',
7979
title: 'Challenge checkpoint review.',
8080
},
8181
},
@@ -92,7 +92,7 @@ module.exports = {
9292
{
9393
id: 0, /** challengeid or projectid */
9494
name: '', /** challenge name */
95-
group: 'Submission',
95+
group: 'submission',
9696
title: 'A new submission is uploaded.',
9797
},
9898
},
@@ -108,4 +108,5 @@ module.exports = {
108108
ENABLE_DEV_MODE: process.env.ENABLE_DEV_MODE ? Boolean(process.env.ENABLE_DEV_MODE) : true,
109109
DEV_MODE_EMAIL: process.env.DEV_MODE_EMAIL,
110110
DEFAULT_REPLY_EMAIL: process.env.DEFAULT_REPLY_EMAIL,
111+
ENABLE_HOOK_BULK_NOTIFICATION : process.env.ENABLE_HOOK_BULK_NOTIFICATION || false,
111112
};

src/hooks/hookBulkMessage.js

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/**
2+
* Hook to insert broadcast notification into database for a user.
3+
*/
4+
5+
'use strict'
6+
7+
const _ = require('lodash')
8+
//const Joi = require('joi')
9+
//const errors = require('../common/errors')
10+
const logger = require('../common/logger')
11+
const models = require('../models')
12+
const logPrefix = "BulkNotificationHook: "
13+
14+
models.BulkMessages.sync()
15+
models.BulkMessageUserRefs.sync()
16+
17+
/**
18+
* Main function
19+
* @param {Integer} userId
20+
*/
21+
function checkBulkMessageForUser(userId) {
22+
models.BulkMessages.count().then(function (tBulkMessages) {
23+
if (tBulkMessages > 0) {
24+
// the condition can help to optimize the execution
25+
models.BulkMessageUserRefs.count({
26+
where: {
27+
user_id: userId
28+
}
29+
}).then(function (tUserRefs) {
30+
if (tUserRefs < tBulkMessages) {
31+
logger.info(`${logPrefix} Need to sync broadcast message for current user ${userId}`)
32+
syncBulkMessageForUser(userId)
33+
}
34+
}).catch((e) => {
35+
logger.error(`${logPrefix} Failed to check total userRefs condition. Error: `, e)
36+
})
37+
}
38+
}).catch((e) => {
39+
logger.error(`${logPrefix} Failed to check total broadcast message condition. Error: `, e)
40+
})
41+
}
42+
43+
/**
44+
* Helper function
45+
* @param {Integer} userId
46+
*/
47+
function syncBulkMessageForUser(userId) {
48+
49+
/**
50+
* Check if all bulk mesaages processed for current user or not
51+
*/
52+
let q = "SELECT a.* FROM bulk_messages AS a " +
53+
" LEFT OUTER JOIN (SELECT id as refid, bulk_message_id " +
54+
" FROM bulk_message_user_refs AS bmur WHERE bmur.user_id=$1)" +
55+
" AS b ON a.id=b.bulk_message_id WHERE b.refid IS NULL"
56+
models.sequelize.query(q, { bind: [userId] })
57+
.then(function (res) {
58+
_.map(res[0], async (r) => {
59+
logger.info(`${logPrefix} need to process for bulk message id: `, r.id)
60+
// call function to check if current user in reciepent group
61+
// insert row in userRef table
62+
if (isBroadCastMessageForUser(userId, r)) {
63+
// current user in reciepent group
64+
createNotificationForUser(userId, r)
65+
} else {
66+
/**
67+
* Insert row in userRef with notification-id null value
68+
* It means - broadcast message in not for current user
69+
*/
70+
insertUserRefs(userId, r.id, null)
71+
}
72+
})
73+
}).catch((e) => {
74+
logger.error(`${logPrefix} Failed to check bulk message condition: `, err)
75+
})
76+
}
77+
78+
/**
79+
* Helper function
80+
* Check if current user in broadcast recipent group
81+
* @param {Integer} userId
82+
* @param {Object} bulkMessage
83+
*/
84+
function isBroadCastMessageForUser(userId, bulkMessage) {
85+
// TODO
86+
return true;
87+
}
88+
89+
/**
90+
* Helper function
91+
* @param {Integer} userId
92+
* @param {Integer} bulkMessageId
93+
* @param {Integer} notificationId
94+
*/
95+
function insertUserRefs(userId, bulkMessageId, notificationId) {
96+
models.BulkMessageUserRefs.create({
97+
bulk_message_id: bulkMessageId,
98+
user_id: userId,
99+
notification_id: notificationId,
100+
}).then((b) => {
101+
logger.info(`${logPrefix} Inserted userRef record ${b.id} for current user ${userId}`)
102+
}).catch((e) => {
103+
logger.error(`${logPrefix} Failed to insert userRef record for user: ${userId}, error: `, e)
104+
})
105+
}
106+
107+
/**
108+
* Helper function
109+
* @param {Integer} userId
110+
* @param {Object} bulkMessage
111+
*/
112+
function createNotificationForUser(userId, bulkMessage) {
113+
models.Notification.create({
114+
userId: userId,
115+
type: bulkMessage.type,
116+
contents: {
117+
id: bulkMessage.id, /** broadcast message id */
118+
name: bulkMessage.contents, /** broadcast message */
119+
group: 'broadcast',
120+
title: 'Broadcast Message',
121+
},
122+
read: false,
123+
seen: false,
124+
version: null,
125+
}).then((n) => {
126+
logger.info(`${logPrefix} Inserted notification record ${n.id} for current user ${userId}`)
127+
insertUserRefs(userId, bulkMessage.id, n.id)
128+
}).catch((err) => {
129+
logger.error(`${logPrefix} Error in inserting broadcast message `, err)
130+
})
131+
}
132+
133+
134+
// Exports
135+
module.exports = {
136+
checkBulkMessageForUser,
137+
};

src/hooks/index.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Copyright (C) 2020 TopCoder Inc., All Rights Reserved.
3+
*/
4+
5+
/**
6+
* Hook implementation
7+
*
8+
* @author TCSCODER
9+
* @version 1.0
10+
*/
11+
12+
const hookBulkMessage = require("./hookBulkMessage")
13+
14+
15+
module.exports = {
16+
hookBulkMessage,
17+
};

src/models/BulkMessageUserRefs.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* Copyright (C) 2020 TopCoder Inc., All Rights Reserved.
3+
*/
4+
5+
/**
6+
* The Bulk Message User Reference schema
7+
*
8+
* @author TCSCODER
9+
* @version 1.0
10+
*/
11+
12+
13+
module.exports = (sequelize, DataTypes) => sequelize.define('bulk_message_user_refs', {
14+
id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true },
15+
bulk_message_id: {
16+
type: DataTypes.BIGINT,
17+
allowNull: false,
18+
references: {
19+
model: 'bulk_messages',
20+
key: 'id'
21+
}
22+
},
23+
notification_id: {
24+
type: DataTypes.BIGINT,
25+
allowNull: true,
26+
references: {
27+
model: 'Notifications',
28+
key: 'id'
29+
}
30+
},
31+
user_id: { type: DataTypes.BIGINT, allowNull: false }
32+
}, {});
33+
34+
// sequelize will generate and manage createdAt, updatedAt fields

src/models/BulkMessages.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Copyright (C) 2020 TopCoder Inc., All Rights Reserved.
3+
*/
4+
5+
/**
6+
* The Bulk Message Store schema
7+
*
8+
* @author TCSCODER
9+
* @version 1.0
10+
*/
11+
12+
13+
module.exports = (sequelize, DataTypes) => sequelize.define('bulk_messages', {
14+
id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true },
15+
type: { type: DataTypes.STRING, allowNull: false },
16+
contents: { type: DataTypes.JSONB, allowNull: false },
17+
recipient_group: { type: DataTypes.STRING, allowNull: false }
18+
}, {});
19+
20+
// sequelize will generate and manage createdAt, updatedAt fields
21+

src/models/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,17 @@ const Notification = require('./Notification')(sequelize, DataTypes);
1616
const NotificationSetting = require('./NotificationSetting')(sequelize, DataTypes);
1717
const ServiceSettings = require('./ServiceSettings')(sequelize, DataTypes);
1818
const ScheduledEvents = require('./ScheduledEvents')(sequelize, DataTypes);
19+
const BulkMessages = require('./BulkMessages')(sequelize, DataTypes);
20+
const BulkMessageUserRefs = require('./BulkMessageUserRefs')(sequelize, DataTypes);
21+
1922

2023
module.exports = {
2124
Notification,
2225
NotificationSetting,
2326
ServiceSettings,
2427
ScheduledEvents,
28+
BulkMessages,
29+
BulkMessageUserRefs,
30+
sequelize,
2531
init: () => sequelize.sync(),
2632
};

src/services/NotificationService.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ const Joi = require('joi');
99
const errors = require('../common/errors');
1010
const logger = require('../common/logger');
1111
const models = require('../models');
12+
const config = require('config');
13+
const hooks = require('../hooks');
1214

1315
const DEFAULT_LIMIT = 10;
1416

@@ -202,6 +204,10 @@ function* listNotifications(query, userId) {
202204
break;
203205
}
204206

207+
if (config.ENABLE_HOOK_BULK_NOTIFICATION){
208+
hooks.hookBulkMessage.checkBulkMessageForUser(userId)
209+
}
210+
205211
if (_.keys(notificationSettings).length > 0) {
206212
// only filter out notifications types which were explicitly set to 'no' - so we return notification by default
207213
const notifications = _.keys(notificationSettings).filter((notificationType) =>

test/checkHooks.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const bulkhook = require("../src/hooks/hookBulkMessage")
2+
3+
bulkhook.checkBulkMessageForUser(123)

0 commit comments

Comments
 (0)