Implement basic GroupChat messages. Closes #4987
This commit is contained in:
parent
4a6b5e5e02
commit
8b9cc79c3d
19
bigbluebutton-html5/imports/api/group-chat-msg/index.js
Normal file
19
bigbluebutton-html5/imports/api/group-chat-msg/index.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
|
||||||
|
const GroupChat = new Mongo.Collection('group-chat-msg');
|
||||||
|
|
||||||
|
if (Meteor.isServer) {
|
||||||
|
GroupChat._ensureIndex({
|
||||||
|
meetingId: 1, chatId: 1, access: 1, users: 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GroupChat;
|
||||||
|
|
||||||
|
export const CHAT_ACCESS = {
|
||||||
|
PUBLIC: 'PUBLIC_ACCESS',
|
||||||
|
PRIVATE: 'PRIVATE_ACCESS',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CHAT_ACCESS_PUBLIC = CHAT_ACCESS.PUBLIC;
|
||||||
|
export const CHAT_ACCESS_PRIVATE = CHAT_ACCESS.PRIVATE;
|
@ -0,0 +1,6 @@
|
|||||||
|
import RedisPubSub from '/imports/startup/server/redis';
|
||||||
|
import handleGroupChatsMsgs from './handlers/groupChatsMsgs';
|
||||||
|
import handleGroupChatMsgBroadcast from './handlers/groupChatMsgBroadcast';
|
||||||
|
|
||||||
|
RedisPubSub.on('GetGroupChatMsgsRespMsg', handleGroupChatsMsgs);
|
||||||
|
RedisPubSub.on('GroupChatMessageBroadcastEvtMsg', handleGroupChatMsgBroadcast);
|
@ -0,0 +1,12 @@
|
|||||||
|
import { check } from 'meteor/check';
|
||||||
|
import addGroupChatMsg from '../modifiers/addGroupChatMsg';
|
||||||
|
|
||||||
|
export default function handleGroupChatMsgBroadcast({ body }, meetingId) {
|
||||||
|
const { chatId, msg } = body;
|
||||||
|
|
||||||
|
check(meetingId, String);
|
||||||
|
check(chatId, String);
|
||||||
|
check(msg, Object);
|
||||||
|
|
||||||
|
return addGroupChatMsg(meetingId, chatId, msg);
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
import { Match, check } from 'meteor/check';
|
||||||
|
import addGroupChatMsg from '../modifiers/addGroupChatMsg';
|
||||||
|
|
||||||
|
export default function handleGroupChatsMsgs({ body }, meetingId) {
|
||||||
|
const { chatId, msgs, msg } = body;
|
||||||
|
|
||||||
|
check(meetingId, String);
|
||||||
|
check(chatId, String);
|
||||||
|
check(msgs, Match.Maybe(Array));
|
||||||
|
check(msg, Match.Maybe(Array));
|
||||||
|
|
||||||
|
const msgsAdded = [];
|
||||||
|
|
||||||
|
(msgs || msg).forEach((m) => {
|
||||||
|
msgsAdded.push(addGroupChatMsg(meetingId, chatId, m));
|
||||||
|
});
|
||||||
|
|
||||||
|
return msgsAdded;
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
import './eventHandlers';
|
||||||
|
import './methods';
|
||||||
|
import './publishers';
|
@ -0,0 +1,7 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import mapToAcl from '/imports/startup/mapToAcl';
|
||||||
|
import sendGroupChatMsg from './methods/sendGroupChatMsg';
|
||||||
|
|
||||||
|
Meteor.methods(mapToAcl(['methods.sendGroupChatMsg'], {
|
||||||
|
sendGroupChatMsg,
|
||||||
|
}));
|
@ -0,0 +1,55 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import { check } from 'meteor/check';
|
||||||
|
import RedisPubSub from '/imports/startup/server/redis';
|
||||||
|
import RegexWebUrl from '/imports/utils/regex-weburl';
|
||||||
|
|
||||||
|
const HTML_SAFE_MAP = {
|
||||||
|
'<': '<',
|
||||||
|
'>': '>',
|
||||||
|
'"': '"',
|
||||||
|
"'": ''',
|
||||||
|
};
|
||||||
|
|
||||||
|
const parseMessage = (message) => {
|
||||||
|
let parsedMessage = message || '';
|
||||||
|
parsedMessage = parsedMessage.trim();
|
||||||
|
|
||||||
|
// Replace <br/> with \n\r
|
||||||
|
parsedMessage = parsedMessage.replace(/<br\s*[\\/]?>/gi, '\n\r');
|
||||||
|
|
||||||
|
// Sanitize. See: http://shebang.brandonmintern.com/foolproof-html-escaping-in-javascript/
|
||||||
|
parsedMessage = parsedMessage.replace(/[<>'"]/g, c => HTML_SAFE_MAP[c]);
|
||||||
|
|
||||||
|
// Replace flash links to flash valid ones
|
||||||
|
parsedMessage = parsedMessage.replace(RegexWebUrl, "<a href='event:$&'><u>$&</u></a>");
|
||||||
|
|
||||||
|
return parsedMessage;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function sendGroupChatMsg(credentials, chatId, message) {
|
||||||
|
const REDIS_CONFIG = Meteor.settings.private.redis;
|
||||||
|
const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
|
||||||
|
|
||||||
|
const { meetingId, requesterUserId, requesterToken } = credentials;
|
||||||
|
|
||||||
|
check(meetingId, String);
|
||||||
|
check(requesterUserId, String);
|
||||||
|
check(requesterToken, String);
|
||||||
|
check(message, Object);
|
||||||
|
|
||||||
|
const eventName = 'SendGroupChatMessageMsg';
|
||||||
|
|
||||||
|
const parsedMessage = parseMessage(message);
|
||||||
|
const payload = {
|
||||||
|
chatId,
|
||||||
|
// correlationId: `${Date.now()}`,
|
||||||
|
sender: {
|
||||||
|
id: requesterUserId,
|
||||||
|
name: '',
|
||||||
|
},
|
||||||
|
// color: '1',
|
||||||
|
message: parsedMessage,
|
||||||
|
};
|
||||||
|
|
||||||
|
return RedisPubSub.publishUserMessage(CHANNEL, eventName, meetingId, requesterUserId, payload);
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
import flat from 'flat';
|
||||||
|
import { Match, check } from 'meteor/check';
|
||||||
|
import Logger from '/imports/startup/server/logger';
|
||||||
|
import GroupChatMsg from '/imports/api/group-chat-msg';
|
||||||
|
import { BREAK_LINE } from '/imports/utils/lineEndings';
|
||||||
|
|
||||||
|
const parseMessage = (message) => {
|
||||||
|
let parsedMessage = message || '';
|
||||||
|
|
||||||
|
// Replace \r and \n to <br/>
|
||||||
|
parsedMessage = parsedMessage.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, `$1${BREAK_LINE}$2`);
|
||||||
|
|
||||||
|
// Replace flash links to html valid ones
|
||||||
|
parsedMessage = parsedMessage.split('<a href=\'event:').join('<a target="_blank" href=\'');
|
||||||
|
parsedMessage = parsedMessage.split('<a href="event:').join('<a target="_blank" href="');
|
||||||
|
|
||||||
|
return parsedMessage;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function addGroupChatMsg(meetingId, chatId, msg) {
|
||||||
|
check(meetingId, String);
|
||||||
|
check(chatId, String);
|
||||||
|
check(msg, {
|
||||||
|
id: String,
|
||||||
|
timestamp: Number,
|
||||||
|
sender: Object,
|
||||||
|
color: String,
|
||||||
|
message: String,
|
||||||
|
correlationId: Match.Maybe(String),
|
||||||
|
});
|
||||||
|
|
||||||
|
const msgDocument = {
|
||||||
|
...msg,
|
||||||
|
meetingId,
|
||||||
|
chatId,
|
||||||
|
message: parseMessage(msg.message),
|
||||||
|
sender: msg.sender.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const selector = {
|
||||||
|
meetingId,
|
||||||
|
chatId,
|
||||||
|
id: msg.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const modifier = {
|
||||||
|
$set: flat(msgDocument, { safe: true }),
|
||||||
|
};
|
||||||
|
|
||||||
|
const cb = (err, numChanged) => {
|
||||||
|
if (err) {
|
||||||
|
return Logger.error(`Adding group-chat-msg to collection: ${err}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { insertedId } = numChanged;
|
||||||
|
|
||||||
|
if (insertedId) {
|
||||||
|
return Logger.info(`Added group-chat-msg msgId=${msg.id} chatId=${chatId} meetingId=${meetingId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Logger.info(`Upserted group-chat-msg msgId=${msg.id} chatId=${chatId} meetingId=${meetingId}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
return GroupChatMsg.upsert(selector, modifier, cb);
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
import GroupChatMsg from '/imports/api/group-chat-msg';
|
||||||
|
import Logger from '/imports/startup/server/logger';
|
||||||
|
|
||||||
|
export default function clearGroupChatMsg(meetingId, chatId) {
|
||||||
|
if (meetingId) {
|
||||||
|
return GroupChatMsg.remove({ meetingId }, Logger.info(`Cleared GroupChat (${meetingId})`));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chatId) {
|
||||||
|
return GroupChatMsg.remove({ meetingId, chatId }, Logger.info(`Cleared GroupChat (${meetingId}, ${chatId})`));
|
||||||
|
}
|
||||||
|
|
||||||
|
return GroupChatMsg.remove({}, Logger.info('Cleared GroupChat (all)'));
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
import { check } from 'meteor/check';
|
||||||
|
import Logger from '/imports/startup/server/logger';
|
||||||
|
import GroupChatMsg from '/imports/api/group-chat-msg';
|
||||||
|
|
||||||
|
export default function removeGroupChat(meetingId, chatId) {
|
||||||
|
check(meetingId, String);
|
||||||
|
check(chatId, String);
|
||||||
|
|
||||||
|
const selector = {
|
||||||
|
chatId,
|
||||||
|
meetingId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const cb = (err, numChanged) => {
|
||||||
|
if (err) {
|
||||||
|
Logger.error(`Removing group-chat-msg from collection: ${err}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numChanged) {
|
||||||
|
// TODO: Clear group-chat-msg-messages
|
||||||
|
Logger.info(`Removed group-chat-msg id=${chatId} meeting=${meetingId}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return GroupChatMsg.remove(selector, cb);
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import { check } from 'meteor/check';
|
||||||
|
|
||||||
|
import Logger from '/imports/startup/server/logger';
|
||||||
|
import mapToAcl from '/imports/startup/mapToAcl';
|
||||||
|
|
||||||
|
import { GroupChat, CHAT_ACCESS_PUBLIC } from '/imports/api/group-chat-msg';
|
||||||
|
|
||||||
|
function groupChatMsg(credentials) {
|
||||||
|
const { meetingId, requesterUserId, requesterToken } = credentials;
|
||||||
|
|
||||||
|
check(meetingId, String);
|
||||||
|
check(requesterUserId, String);
|
||||||
|
check(requesterToken, String);
|
||||||
|
|
||||||
|
Logger.info(`Publishing group-chat-msg for ${meetingId} ${requesterUserId} ${requesterToken}`);
|
||||||
|
|
||||||
|
return GroupChat.find({
|
||||||
|
$or: [
|
||||||
|
{
|
||||||
|
access: CHAT_ACCESS_PUBLIC,
|
||||||
|
meetingId,
|
||||||
|
}, {
|
||||||
|
users: { $in: [requesterUserId] },
|
||||||
|
meetingId,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function publish(...args) {
|
||||||
|
const boundGroupChat = groupChatMsg.bind(this);
|
||||||
|
return mapToAcl('subscriptions.group-chat-msg', boundGroupChat)(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
Meteor.publish('group-chat-msg', publish);
|
19
bigbluebutton-html5/imports/api/group-chat/index.js
Normal file
19
bigbluebutton-html5/imports/api/group-chat/index.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
|
||||||
|
const GroupChat = new Mongo.Collection('group-chat');
|
||||||
|
|
||||||
|
if (Meteor.isServer) {
|
||||||
|
GroupChat._ensureIndex({
|
||||||
|
meetingId: 1, chatId: 1, access: 1, users: 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GroupChat;
|
||||||
|
|
||||||
|
export const CHAT_ACCESS = {
|
||||||
|
PUBLIC: 'PUBLIC_ACCESS',
|
||||||
|
PRIVATE: 'PRIVATE_ACCESS',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CHAT_ACCESS_PUBLIC = CHAT_ACCESS.PUBLIC;
|
||||||
|
export const CHAT_ACCESS_PRIVATE = CHAT_ACCESS.PRIVATE;
|
@ -0,0 +1,8 @@
|
|||||||
|
import RedisPubSub from '/imports/startup/server/redis';
|
||||||
|
import handleGroupChats from './handlers/groupChats';
|
||||||
|
import handleGroupChatCreated from './handlers/groupChatCreated';
|
||||||
|
import handleGroupChatDestroyed from './handlers/groupChatDestroyed';
|
||||||
|
|
||||||
|
RedisPubSub.on('GetGroupChatsRespMsg', handleGroupChats);
|
||||||
|
RedisPubSub.on('GroupChatCreatedEvtMsg', handleGroupChatCreated);
|
||||||
|
RedisPubSub.on('GroupChatDestroyedEvtMsg', handleGroupChatDestroyed);
|
@ -0,0 +1,9 @@
|
|||||||
|
import { check } from 'meteor/check';
|
||||||
|
import addGroupChat from '../modifiers/addGroupChat';
|
||||||
|
|
||||||
|
export default function handleGroupChatCreated({ body }, meetingId) {
|
||||||
|
check(meetingId, String);
|
||||||
|
check(body, Object);
|
||||||
|
|
||||||
|
return addGroupChat(meetingId, body);
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
import { check } from 'meteor/check';
|
||||||
|
import addGroupChat from '../modifiers/addGroupChat';
|
||||||
|
|
||||||
|
export default function handleGroupChatDestroyed({ body }, meetingId) {
|
||||||
|
check(meetingId, String);
|
||||||
|
check(body, Object);
|
||||||
|
|
||||||
|
return addGroupChat(meetingId, body);
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
import { check } from 'meteor/check';
|
||||||
|
import addGroupChat from '../modifiers/addGroupChat';
|
||||||
|
|
||||||
|
export default function handleGroupChats({ body }, meetingId) {
|
||||||
|
const { chats } = body;
|
||||||
|
|
||||||
|
check(meetingId, String);
|
||||||
|
check(chats, Array);
|
||||||
|
|
||||||
|
const chatsAdded = [];
|
||||||
|
|
||||||
|
chats.forEach((chat) => {
|
||||||
|
chatsAdded.push(addGroupChat(meetingId, chat));
|
||||||
|
});
|
||||||
|
|
||||||
|
return chatsAdded;
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
import '/imports/api/group-chat-msg/server';
|
||||||
|
import './eventHandlers';
|
||||||
|
import './methods';
|
||||||
|
import './publishers';
|
@ -0,0 +1,9 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import mapToAcl from '/imports/startup/mapToAcl';
|
||||||
|
import createGroupChat from './methods/createGroupChat';
|
||||||
|
import destroyGroupChat from './methods/destroyGroupChat';
|
||||||
|
|
||||||
|
Meteor.methods(mapToAcl(['methods.createGroupChat', 'methods.destroyGroupChat'], {
|
||||||
|
createGroupChat,
|
||||||
|
destroyGroupChat,
|
||||||
|
}));
|
@ -0,0 +1,31 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import { check } from 'meteor/check';
|
||||||
|
import RedisPubSub from '/imports/startup/server/redis';
|
||||||
|
|
||||||
|
export default function createGroupChat(credentials) {
|
||||||
|
const REDIS_CONFIG = Meteor.settings.private.redis;
|
||||||
|
const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
|
||||||
|
const { meetingId, requesterUserId, requesterToken } = credentials;
|
||||||
|
|
||||||
|
check(meetingId, String);
|
||||||
|
check(requesterUserId, String);
|
||||||
|
check(requesterToken, String);
|
||||||
|
|
||||||
|
const eventName = 'CreateGroupChatReqMsg';
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
// TODO: Implement this together with #4988
|
||||||
|
// correlationId: String,
|
||||||
|
// name: String,
|
||||||
|
// access: String,
|
||||||
|
// users: Vector[String],
|
||||||
|
// msg: Vector[{
|
||||||
|
// correlationId: String,
|
||||||
|
// sender: GroupChatUser,
|
||||||
|
// color: String,
|
||||||
|
// message: String
|
||||||
|
// }],
|
||||||
|
};
|
||||||
|
|
||||||
|
return RedisPubSub.publishUserMessage(CHANNEL, eventName, meetingId, requesterUserId, payload);
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import { check } from 'meteor/check';
|
||||||
|
import RedisPubSub from '/imports/startup/server/redis';
|
||||||
|
|
||||||
|
export default function createGroupChat(credentials) {
|
||||||
|
const REDIS_CONFIG = Meteor.settings.private.redis;
|
||||||
|
const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
|
||||||
|
const { meetingId, requesterUserId, requesterToken } = credentials;
|
||||||
|
|
||||||
|
check(meetingId, String);
|
||||||
|
check(requesterUserId, String);
|
||||||
|
check(requesterToken, String);
|
||||||
|
|
||||||
|
const eventName = 'DestroyGroupChatReqMsg';
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
// TODO: Implement this together with #4988
|
||||||
|
// chats: Array[String],
|
||||||
|
};
|
||||||
|
|
||||||
|
return RedisPubSub.publishUserMessage(CHANNEL, eventName, meetingId, requesterUserId, payload);
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
import flat from 'flat';
|
||||||
|
import { Match, check } from 'meteor/check';
|
||||||
|
import Logger from '/imports/startup/server/logger';
|
||||||
|
import GroupChat from '/imports/api/group-chat';
|
||||||
|
|
||||||
|
export default function addGroupChat(meetingId, chat) {
|
||||||
|
check(meetingId, String);
|
||||||
|
check(chat, {
|
||||||
|
id: Match.Maybe(String),
|
||||||
|
chatId: Match.Maybe(String),
|
||||||
|
correlationId: Match.Maybe(String),
|
||||||
|
name: String,
|
||||||
|
access: String,
|
||||||
|
createdBy: Object,
|
||||||
|
users: Array,
|
||||||
|
msg: Match.Maybe(Array),
|
||||||
|
});
|
||||||
|
|
||||||
|
const chatDocument = {
|
||||||
|
meetingId,
|
||||||
|
chatId: chat.chatId || chat.id,
|
||||||
|
name: chat.name,
|
||||||
|
access: chat.access,
|
||||||
|
users: chat.users.map(u => u.id),
|
||||||
|
createdBy: chat.createdBy.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const selector = {
|
||||||
|
chatId: chatDocument.chatId,
|
||||||
|
meetingId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const modifier = {
|
||||||
|
$set: flat(chatDocument, { safe: true }),
|
||||||
|
};
|
||||||
|
|
||||||
|
const cb = (err, numChanged) => {
|
||||||
|
if (err) {
|
||||||
|
return Logger.error(`Adding group-chat to collection: ${err}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { insertedId } = numChanged;
|
||||||
|
|
||||||
|
if (insertedId) {
|
||||||
|
return Logger.info(`Added group-chat name=${chat.name} meetingId=${meetingId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Logger.info(`Upserted group-chat name=${chat.name} meetingId=${meetingId}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
return GroupChat.upsert(selector, modifier, cb);
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
import GroupChat from '/imports/api/group-chat';
|
||||||
|
import Logger from '/imports/startup/server/logger';
|
||||||
|
import clearGroupChatMsg from 'imports/api/group-chat-msg/server/modifiers/clearGroupChatMsg';
|
||||||
|
|
||||||
|
export default function clearGroupChat(meetingId) {
|
||||||
|
if (meetingId) {
|
||||||
|
clearGroupChatMsg(meetingId);
|
||||||
|
return GroupChat.remove({ meetingId }, Logger.info(`Cleared GroupChat (${meetingId})`));
|
||||||
|
}
|
||||||
|
|
||||||
|
clearGroupChatMsg();
|
||||||
|
return GroupChat.remove({}, Logger.info('Cleared GroupChat (all)'));
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
import { check } from 'meteor/check';
|
||||||
|
import Logger from '/imports/startup/server/logger';
|
||||||
|
import GroupChat from '/imports/api/group-chat';
|
||||||
|
import clearGroupChatMsg from 'imports/api/group-chat-msg/server/modifiers/clearGroupChatMsg';
|
||||||
|
|
||||||
|
export default function removeGroupChat(meetingId, chatId) {
|
||||||
|
check(meetingId, String);
|
||||||
|
check(chatId, String);
|
||||||
|
|
||||||
|
const selector = {
|
||||||
|
chatId,
|
||||||
|
meetingId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const cb = (err, numChanged) => {
|
||||||
|
if (err) {
|
||||||
|
Logger.error(`Removing group-chat from collection: ${err}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numChanged) {
|
||||||
|
// TODO: Clear group-chat-messages
|
||||||
|
Logger.info(`Removed group-chat id=${chatId} meeting=${meetingId}`);
|
||||||
|
clearGroupChatMsg(meetingId, chatId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return GroupChat.remove(selector, cb);
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import { check } from 'meteor/check';
|
||||||
|
|
||||||
|
import Logger from '/imports/startup/server/logger';
|
||||||
|
import mapToAcl from '/imports/startup/mapToAcl';
|
||||||
|
|
||||||
|
import { GroupChat, CHAT_ACCESS_PUBLIC } from '/imports/api/group-chat';
|
||||||
|
|
||||||
|
function groupChat(credentials) {
|
||||||
|
const { meetingId, requesterUserId, requesterToken } = credentials;
|
||||||
|
|
||||||
|
check(meetingId, String);
|
||||||
|
check(requesterUserId, String);
|
||||||
|
check(requesterToken, String);
|
||||||
|
|
||||||
|
Logger.info(`Publishing group-chat for ${meetingId} ${requesterUserId} ${requesterToken}`);
|
||||||
|
|
||||||
|
return GroupChat.find({
|
||||||
|
$or: [
|
||||||
|
{
|
||||||
|
access: CHAT_ACCESS_PUBLIC,
|
||||||
|
meetingId,
|
||||||
|
}, {
|
||||||
|
users: { $in: [requesterUserId] },
|
||||||
|
meetingId,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function publish(...args) {
|
||||||
|
const boundGroupChat = groupChat.bind(this);
|
||||||
|
return mapToAcl('subscriptions.group-chat', boundGroupChat)(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
Meteor.publish('group-chat', publish);
|
@ -74,7 +74,9 @@
|
|||||||
"captions",
|
"captions",
|
||||||
"breakouts",
|
"breakouts",
|
||||||
"voiceUsers",
|
"voiceUsers",
|
||||||
"whiteboard-multi-user"
|
"whiteboard-multi-user",
|
||||||
|
"group-chat",
|
||||||
|
"group-chat-msg"
|
||||||
],
|
],
|
||||||
"methods": [
|
"methods": [
|
||||||
"listenOnlyToggle",
|
"listenOnlyToggle",
|
||||||
@ -82,7 +84,10 @@
|
|||||||
"setEmojiStatus",
|
"setEmojiStatus",
|
||||||
"toggleSelfVoice",
|
"toggleSelfVoice",
|
||||||
"publishVote",
|
"publishVote",
|
||||||
"sendChat"
|
"sendChat",
|
||||||
|
"createGroupChat",
|
||||||
|
"destroyGroupChat",
|
||||||
|
"sendGroupChatMsg"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"moderator": {
|
"moderator": {
|
||||||
|
@ -74,7 +74,9 @@
|
|||||||
"captions",
|
"captions",
|
||||||
"breakouts",
|
"breakouts",
|
||||||
"voiceUsers",
|
"voiceUsers",
|
||||||
"whiteboard-multi-user"
|
"whiteboard-multi-user",
|
||||||
|
"group-chat",
|
||||||
|
"group-chat-msg"
|
||||||
],
|
],
|
||||||
"methods": [
|
"methods": [
|
||||||
"listenOnlyToggle",
|
"listenOnlyToggle",
|
||||||
@ -82,7 +84,10 @@
|
|||||||
"setEmojiStatus",
|
"setEmojiStatus",
|
||||||
"toggleSelfVoice",
|
"toggleSelfVoice",
|
||||||
"publishVote",
|
"publishVote",
|
||||||
"sendChat"
|
"sendChat",
|
||||||
|
"createGroupChat",
|
||||||
|
"destroyGroupChat",
|
||||||
|
"sendGroupChatMsg"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"moderator": {
|
"moderator": {
|
||||||
@ -349,4 +354,4 @@
|
|||||||
"level": "warn"
|
"level": "warn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import '/imports/api/presentations/server';
|
|||||||
import '/imports/api/slides/server';
|
import '/imports/api/slides/server';
|
||||||
import '/imports/api/breakouts/server';
|
import '/imports/api/breakouts/server';
|
||||||
import '/imports/api/chat/server';
|
import '/imports/api/chat/server';
|
||||||
|
import '/imports/api/group-chat/server';
|
||||||
import '/imports/api/screenshare/server';
|
import '/imports/api/screenshare/server';
|
||||||
import '/imports/api/voice-users/server';
|
import '/imports/api/voice-users/server';
|
||||||
import '/imports/api/whiteboard-multi-user/server';
|
import '/imports/api/whiteboard-multi-user/server';
|
||||||
|
Loading…
Reference in New Issue
Block a user