I have created an app using socket... I am able to manage the conversation between two persons using socket connection.
Here is the code for it
User model
const schema = new Mongoose.Schema({
firstName: { type: String, default: '', trim: true },
lastName: { type: String, default: '', trim: true }
})
Conversation model
const schema = new Mongoose.Schema({
name: { type: String, trim: true },
type: { type: String, required: true, enum: ['G', 'P'] },
members: [{ type: Schema.Types.ObjectId, ref: 'Users' }]
}, { timestamps: true })
Message Model
const schema = new Mongoose.Schema({
conversationId: { type: Schema.Types.ObjectId, ref: 'Conversations' },
body: { type: String, trim: true },
author: { type: Schema.Types.ObjectId, ref: 'Users' }
}, { timestamps: true })
Done with the chatting part with this socket connection
io.on('sendMessage', async(action2) => {
action2.author = socket.decoded.id
action2.markRead = markReadSocket
const createMessage = await Message.create(action2)
const messages = await Message.aggregate([
{ "$match": { "_id": mongoose.Types.ObjectId(createMessage._id) } },
{ "$lookup": {
"from": "users",
"let": { "author": "$author" },
"pipeline": [
{ "$match": { "$expr": { "$eq": [ "$_id", "$$author" ] }}},
{ "$project": { "firstName": 1, "lastName": 1, "avatar": 1 } }
],
"as": "author"
}},
{ "$unwind": "$author" },
{ "$project": {
"author": 1, "markRead": 1, "isDelivered": 1,
"body": 1, "conversationId": 1,
"isIncoming": { "$ne": [ "$author._id", mongoose.Types.ObjectId(socket.decoded.id) ] },
}}
])
io.emit(action2.conversationId, messages)
})
The above code is working fine for the one to one conversation and also for the group conversation.
Now what I want to achieve is to show delivered(two gray) and read(two blue) ticks just like the what app. Do I need to make separate collections for readBy
and deliveredTo
and need to save time
and userId
in it?
How can I do this with the nodejs
and socketio
? If someone has done this before then please post your code I will manage to understand it.
Any help would be appreciated!!!
Thanks in advance!!!
Client Side
Pseudocode
1. Register handler for 'newMessage' event, this will emit 'received' event
2. Function to emit 'markSeen' event, this will execute when the message is opened (chat window)
3. Register handler for 'delivered' event, this will display 'grey' ticks
4. Register handler for 'markedSeen' event, this will display 'blue' ticks
Functions
// Handler for 'newMessage' event
socket.on('newMessage', function(message) {
chatMessages[message.MESSAGE_ID] = message;
var options = {
messageID: message.MESSAGE_ID,
timetoken: moment().valueOf()
};
// Emit 'received' event
socket.emit('received', options);
});
// function to emit 'markSeen' event
function markSeen(message) {
var options = {
messageID: message.MESSAGE_ID
};
// Emit 'markSeen' event
socket.emit('markSeen', options);
}
// Handler for 'delivered' event
socket.on('delivered', function(message) {
chatMessages[MESSAGE_ID].delivered = true;
});
// Handler for 'markedSeen' event
socket.on('markedSeen', function(message) {
chatMessages[MESSAGE_ID].seen = true;
});
Server Side
Pseudocode
1. Register handler for 'received' event, this will emit 'delivered' event
2. Register handler for 'markSeen' event, this will emit 'markedSeen' event
Functions
// Handler for 'received' event
io.on('received', function(options) {
var options = {
timetoken: moment().valueOf(),
userID: options.message.SENDER_ID,
messageID: options.message.MESSAGE_ID
};
// Emit 'delivered' event
socket.emit('delivered', options);
});
// Handler for 'markSeen' event
io.on('markSeen', function(options) {
var options = {
timetoken: moment().valueOf(),
userID: options.message.SENDER_ID,
messageID: options.message.MESSAGE_ID
};
// Emit 'markedSeen' event
socket.emit('markedSeen', options);
});