Skip to content

Commit 76f41dd

Browse files
authored
Added ChatMessage schema & fixed api logic so it actually stores each chatMessage in the db (#1822)
* added ChatMessage schema & modified writeMessage function to write to mongodb * modified /getLatestmessage to get the latest message, need to test it out in postman now * updated writeMessage to be async for proper mongoDB chatMessage creation * getLatestMessage now works for specific chatRoom ids, gets the userid via querying the User database by username and then extracting the userId * uncommented out some token and apikey logic * fixed lint errors yay * reverted the package-lock.json file to the one from dev branch * removed all the random styling changes, kept only the logic changes * changed from expiresAt to expireAt and added TTL index for automatic expiration * made writing to mongoDb as a seperate function * removed the extracting username logic from writeMessage. * fixed lint errors * removed writeToMongo function, just added it inside the /send route * Fixed lint errors
1 parent b0086c1 commit 76f41dd

File tree

2 files changed

+65
-28
lines changed

2 files changed

+65
-28
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
const mongoose = require('mongoose');
2+
const Schema = mongoose.Schema;
3+
4+
const ChatMessageSchema = new Schema(
5+
{
6+
createdAt: {
7+
type: Date,
8+
default: Date.now(),
9+
},
10+
expiresAt: {
11+
type: Date,
12+
default: ()=> Date.now() + 24 * 3600 * 1000, // expires in 24 hours
13+
},
14+
chatroomId: {
15+
type: String,
16+
required: true,
17+
},
18+
userId: {
19+
type: Schema.Types.ObjectId,
20+
ref: 'User',
21+
required: true,
22+
},
23+
text: {
24+
type: String,
25+
required: true,
26+
}
27+
}
28+
);
29+
30+
ChatMessageSchema.index({chatroomId: 1, createdAt: -1}); // sort by whatever is created most currently
31+
ChatMessageSchema.index({expiresAt: 1}, {expireAfterSeconds: 0}); // TTL index for automatic expiration
32+
33+
module.exports = mongoose.model('ChatMessage', ChatMessageSchema);
34+
35+

api/main_endpoints/routes/Messages.js

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const logger = require('../../util/logger');
1313
const client = require('prom-client');
1414
const { decodeToken, decodeTokenFromBodyOrQuery } = require('../util/token-functions.js');
1515
const { MetricsHandler, register } = require('../../util/metrics.js');
16+
const ChatMessage = require('../models/ChatMessage.js');
1617

1718

1819
router.use(bodyParser.json());
@@ -23,7 +24,8 @@ const clients = {};
2324
const numberOfConnections = {};
2425
const lastMessageSent = {};
2526

26-
const writeMessage = ((roomId, message, username) => {
27+
28+
const writeMessage = (roomId, message, username) => {
2729

2830
const messageObj = {
2931
timestamp: Date.now(),
@@ -37,12 +39,13 @@ const writeMessage = ((roomId, message, username) => {
3739

3840
lastMessageSent[roomId] = JSON.stringify(messageObj);
3941

42+
4043
// increase the total messages sent counter
4144
MetricsHandler.totalMessagesSent.inc();
4245

4346
// increase the total amount of messages sent per chatroom counter
4447
MetricsHandler.totalChatMessagesPerChatRoom.labels(roomId).inc();
45-
});
48+
};
4649

4750
router.post('/send', async (req, res) => {
4851

@@ -65,6 +68,7 @@ router.post('/send', async (req, res) => {
6568
}
6669

6770
let nameToUse = null;
71+
let userId = null;
6872

6973
if (apiKey) {
7074
try {
@@ -73,20 +77,30 @@ router.post('/send', async (req, res) => {
7377
return res.sendStatus(UNAUTHORIZED);
7478
}
7579
nameToUse = result.firstName;
80+
userId = result._id;
81+
await writeToMongo(id, message, userId);
7682
} catch (error) {
7783
logger.error('Error in /send User.findOne: ', error);
7884
return res.sendStatus(SERVER_ERROR);
7985
}
86+
} else {
87+
const userObj = decodeToken(req);
88+
if (!userObj) {
89+
return res.sendStatus(UNAUTHORIZED);
90+
}
91+
nameToUse = userObj.firstName;
92+
userId = userObj._id;
8093
}
81-
82-
// Assume user passed a non null/undefined token
83-
const userObj = decodeToken(req);
84-
if (!userObj) {
85-
return res.sendStatus(UNAUTHORIZED);
86-
}
87-
nameToUse = userObj.firstName;
8894
try {
8995
writeMessage(id, `${message}`, `${nameToUse}:`);
96+
97+
ChatMessage.create({
98+
chatroomId: id,
99+
text: message,
100+
userId: userId
101+
}).catch(err => {
102+
logger.error('Error in /send ChatMessage.create: ', err);
103+
});
90104
return res.json({ status: 'Message sent' });
91105
} catch (error) {
92106
logger.error('Error in /send writeMessage: ', error);
@@ -103,33 +117,23 @@ router.get('/getLatestMessage', async (req, res) => {
103117
];
104118

105119
const missingValue = required.find(({value}) => !value);
106-
107120
if (missingValue){
108121
res.status(BAD_REQUEST).send(`You must specify a ${missingValue.title}`);
109122
return;
110123
}
111124

112125
try {
113-
User.findOne({ apiKey }, (error, result) => {
114-
if (error) {
115-
logger.error('/listen received an invalid API key: ', error);
116-
res.sendStatus(SERVER_ERROR);
117-
return;
118-
}
119-
120-
if (!result) { // return unauthorized if no api key found
121-
return res.sendStatus(UNAUTHORIZED);
122-
}
126+
const user = await User.findOne({apiKey});
127+
if(!user){
128+
return res.sendStatus(UNAUTHORIZED);
129+
}
123130

124-
if (!lastMessageSent[id]) {
125-
return res.status(OK).send('Room closed');
126-
}
131+
const messages = await ChatMessage.find({chatroomId: id}).sort({createdAt: -1}).limit(20).populate('userId');
127132

128-
return res.status(OK).send(lastMessageSent[id]);
133+
return res.status(OK).json(messages);
129134

130-
});
131135
} catch (error) {
132-
logger.error('Error in /get: ', error);
136+
logger.error('Error in /getLatestMessage: ', error);
133137
res.sendStatus(SERVER_ERROR);
134138
}
135139
});
@@ -144,7 +148,6 @@ router.get('/listen', async (req, res) => {
144148
];
145149

146150
const missingValue = required.find(({value}) => !value);
147-
148151
if (missingValue){
149152
res.status(BAD_REQUEST).send(`You must specify a ${missingValue.title}`);
150153
return;
@@ -174,7 +177,6 @@ router.get('/listen', async (req, res) => {
174177
}
175178

176179
const { _id } = result;
177-
178180
numberOfConnections[_id] = numberOfConnections[_id] ? numberOfConnections[_id] + 1 : 1;
179181

180182
const headers = {

0 commit comments

Comments
 (0)