UNPKG

yekonga-server

Version:
387 lines (305 loc) 13.3 kB
// @ts-nocheck const H = Yekonga.Helper; const path = global.serverLibrary.path; const Middleware = require('./middleware'); module.exports = (socketServer, options) => { var localOptions = { debug: true } new ChatConnection(socketServer, options); } class ChatConnection { static channel = '/chat'; constructor(socket, options) { options = options || {}; this._roomRooms = {} this._socket = socket.of(ChatConnection.channel); this.initializeSocket(); } initializeSocket() { this._socket .use(async function(socket, next) { if(typeof next == 'function') { next(); } }) .on('connection', (socket) => { // console.debug(socket); console.warn(`connected: /chat`); socket.on('open', async (data) => { var { chatGroupId, reference, type, localProfile, remoteProfile, } = data || {}; type = (H.isNotEmpty(type))? type: 'private'; var group = null; var localMemberId = null; var remoteMemberId = null; var localMember = await this.getGroupMember({ reference, ...localProfile }); var remoteMember = null; var where = { reference: reference, type: type, }; localMemberId = `${localMember.chatGroupMemberId}`; if(H.isNotEmpty(chatGroupId)) { where.chatGroupId = chatGroupId; } if(type == 'private') { if(remoteProfile && remoteProfile.userId) { remoteMember = await this.getGroupMember({ reference, ...remoteProfile }); } if(remoteMember) { remoteMemberId = `${remoteMember.chatGroupMemberId}`; } where.members = { all: [localMemberId, remoteMemberId] } } group = await Yekonga.Model.ChatGroup.findOne(where, true); if(!group) { var body = { reference: reference, type: type, members: [], } if(localMemberId) body.members.push(localMemberId); if(remoteMemberId) body.members.push(remoteMemberId); group = H.getFirst(await Yekonga.Model.ChatGroup.create(body, true)); } if(group) { var members = Array.isArray(group.members)? group.members: []; if(Array.isArray(members)) { members = members.map((e)=>`${e}`); } if(localMemberId && !members.includes(localMemberId)) { members.push(localMemberId); } if(remoteMemberId && !members.includes(remoteMemberId)) { members.push(remoteMemberId); } await Yekonga.Model.ChatGroup.update({ members: members }, { chatGroupId: group.chatGroupId }, true); } var messages = await this.getMessages(socket, group.chatGroupId); socket.emit('back-open', { ...group, roomId: group.chatGroupId, localProfile: localMember, messages, }); Yekonga.Cloud.runOnMessage('chat', 'open', data); }); socket.on('join', async (data) => { var { roomId, chatGroupMemberId } = data || {} socket.roomId = roomId; socket.chatGroupMemberId = chatGroupMemberId; socket.join(roomId, chatGroupMemberId); socket.broadcast.to(roomId).emit('receive-join', { roomId, chatGroupMemberId }); Yekonga.Cloud.runOnMessage('chat', 'join', data); }); socket.on('typing', (data) => { var { roomId, chatGroupMemberId, name, profileUrl } = data || { } socket.broadcast.to(roomId).emit("receive-typing", { roomId, chatGroupMemberId, name, profileUrl }); Yekonga.Cloud.runOnMessage('chat', 'typing', data); }); socket.on('message-media', async (data) => { var {roomId, chatMessageId, media, type } = data || {} var mediaData = null; if(Array.isArray(media) && media.length) { mediaData = []; for (let i = 0; i < media.length; i++) { var d = {}; var m = media[i]; d.fileName = m.fileName; d.fileType = m.fileType; d.fileSize = m.fileSize; d.url = m.base64; mediaData[i] = d; } } else if(media) { mediaData = [{ fileName: media.fileName, fileType: media.fileType, fileSize: media.fileSize, url: media.base64, }]; } if(mediaData) { var _message = H.getFirst(await Yekonga.Model.ChatMessage.update({ type: type? type: 'media', media: mediaData, }, { chatMessageId }, true)); if(_message) { var chatMessageId = _message.chatMessageId; var message = await this.getSingleMessage(socket, chatMessageId); socket.emit('back-message', { roomId, ...message, update: true }); socket.broadcast.to(roomId).emit("receive-message", { roomId, ...message, update: true }); } } Yekonga.Cloud.runOnMessage('chat', 'message-media', data); }); socket.on('message', async (data) => { var { roomId, chatMessageId, chatGroupMemberId, content, type, media } = data || {} // console.debug(media); // console.debug("================================"); if(Array.isArray(media) && media.length) { for (let i = 0; i < media.length; i++) { var d = {}; var m = media[i]; d.fileName = m.fileName; d.fileType = m.fileType; d.fileSize = m.fileSize; d.url = m.base64; media[i] = d; } } else { media = null; } var _message = H.getFirst(await Yekonga.Model.ChatMessage.create({ chatMessageId: chatMessageId? chatMessageId: H.getHexString(), chatGroupId: roomId, chatGroupMemberId: chatGroupMemberId, content: content, type: type? type: 'text', media: media, }, true)); if(_message) { var chatMessageId = _message.chatMessageId; var members = await Yekonga.Model.ChatGroupMember.find({ chatGroupId: roomId }, true); for (let i = 0; i < members.length; i++) { const e = members[i]; await Yekonga.Model.ChatMessageStatus.create({ chatMessageId: chatMessageId, chatGroupMemberId: e.chatGroupMemberId, }); } var message = await this.getSingleMessage(socket, chatMessageId); socket.emit('back-message', {roomId, ...message }); socket.broadcast.to(roomId).emit("receive-message", {roomId, ...message}); } Yekonga.Cloud.runOnMessage('chat', 'message', data); }); socket.on('received', (data) => { var { roomId, chatGroupMemberId, chatMessageId } = data || {} socket.broadcast.to(roomId).emit("receive-delivered", {roomId, chatGroupMemberId, chatMessageId}) Yekonga.Cloud.runOnMessage('chat', 'received', data); }); socket.on('opened', (data) => { var { roomId, chatGroupMemberId, chatMessageId } = data || {} socket.broadcast.to(roomId).emit("receive-opened", {roomId, chatGroupMemberId, chatMessageId}) Yekonga.Cloud.runOnMessage('chat', 'opened', data); }); socket.on('leave', (data) => { var { roomId, chatGroupMemberId, userReferenceId } = data || {} console.debug('leave',data); if(roomId) { socket.leave(roomId); socket.broadcast.to(roomId).emit('leave', {chatGroupMemberId, userReferenceId}) } Yekonga.Cloud.runOnMessage('chat', 'leave', data); }); socket.on('disconnect', () => { const roomId = socket.roomId? socket.roomId: null; const chatGroupMemberId = socket.chatGroupMemberId? socket.chatGroupMemberId: null; if(roomId) { socket.leave(roomId); socket.broadcast.to(roomId).emit('leave', {roomId, chatGroupMemberId}); } Yekonga.Cloud.runOnMessage('chat', 'disconnect', {roomId, chatGroupMemberId}); }) socket.on('error', function (e) { console.debug('socket.io error:' + e); Yekonga.Cloud.runOnMessage('chat', 'error', e); }); }); setInterval(() => { this._socket.emit('active', true); }, 5000); } queryFields = ` chatMessageId, chatGroupId, roomId: chatGroupId, chatGroupMemberId, content, media, mediaReference, type, timestamp, user: chatGroupMember(accessRole:"${Yekonga.Config.masterKey}") { chatGroupMemberId, userId, userReferenceId, name, profileUrl, isAdmin, isOwner, }, chatMessageStatuses { chatGroupMemberId, sent, received, opened, }, `; async getGroupMemberId({reference, userId, userReferenceId, name, profileUrl}) { var id = null; var member = await this.getGroupMember({reference, userId, userReferenceId, name, profileUrl}); if(member) { id = member.chatGroupMemberId; } return id; } async getGroupMember({reference, userId, userReferenceId, name, profileUrl}) { var member = await Yekonga.Model.ChatGroupMember.findOne({ reference, userId, userReferenceId }, true); if(!member) { member = H.getFirst(await Yekonga.Model.ChatGroupMember.create({ reference, userId, userReferenceId, name, profileUrl, }, true)); } return member; } async getMessages(req, id) { var headers = {} if(req.Yekonga && req.Yekonga.Client && req.Yekonga.Client.headers) { headers = req.Yekonga.Client.headers; } var queryBody = `query{list:chatMessages(where:{chatGroupId:{equalTo: "${id}"}},orderBy:{key:timestamp, value:ASC}) { ${this.queryFields} }}`; // console.debug(queryBody); var data = await Yekonga.Helper.getGraphql({query:queryBody}, headers, null, {}); if(data && data.list) { return data.list } return []; } async getSingleMessage(req, id) { var headers = {} if(req.Yekonga && req.Yekonga.Client && req.Yekonga.Client.headers) { headers = req.Yekonga.Client.headers; } var queryBody = `query{single:chatMessage(where:{chatMessageId:{equalTo: "${id}"}}) { ${this.queryFields} }}`; var data = await Yekonga.Helper.getGraphql({query:queryBody}, headers, 'single', {}); if(data && data.single) { return data.single } return null; } } async function createChatMessage() { } async function sendChatMessageStatus() { } // cancel pending order Yekonga.registerCronjob('processChatMessageStatus', 6000, async function(){ });