Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NEW] Apps engine Livechat #14626

Merged
merged 34 commits into from
Sep 21, 2019
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
dd57ae5
Add customFields to rooms converter in Apps Engine
d-gubert May 15, 2019
a844ae4
Refactor apps orchestrator initialization
d-gubert May 15, 2019
5198b7a
Merge remote-tracking branch 'origin/develop' into apps-engine-livechat
d-gubert May 21, 2019
b87f9de
Refactor imports of functions to work with the bridge
d-gubert May 24, 2019
33ac750
Add new options to the HTTP bridge
d-gubert May 24, 2019
c49e80f
Add new Livechat bridge for the engine
d-gubert May 24, 2019
ba3c6fb
Merge branch 'develop' into apps-engine-livechat
d-gubert May 24, 2019
1b3edee
Merge branch 'develop' into apps-engine-livechat
d-gubert May 27, 2019
4a8b8aa
Merge branch 'develop' into apps-engine-livechat
d-gubert May 28, 2019
64e32e6
Update converters to handle livechat data
d-gubert May 28, 2019
4547326
Merge branch 'develop' into apps-engine-livechat
d-gubert May 29, 2019
6228c2f
Improve room converter on the app engine
d-gubert May 29, 2019
bf79ec5
Merge branch 'develop' into apps-engine-livechat
d-gubert May 29, 2019
04a76e8
Merge branch 'develop' into apps-engine-livechat
d-gubert May 30, 2019
1d5e45b
Merge branch 'develop' into apps-engine-livechat
d-gubert May 31, 2019
ea08ead
Merge branch 'develop' into apps-engine-livechat
d-gubert May 31, 2019
abfed08
Merge branch 'develop' into apps-engine-livechat
d-gubert Jun 7, 2019
7452298
Merge branch 'develop' into apps-engine-livechat
d-gubert Jun 11, 2019
cad1dd2
Update livechat bridge and converters
d-gubert Jun 11, 2019
deface0
Add upload bridge and converter to apps engine
d-gubert Jun 11, 2019
144874e
Merge remote-tracking branch 'origin/develop' into apps-engine-livechat
d-gubert Jun 11, 2019
264e256
Merge branch 'develop' into apps-engine-livechat
d-gubert Jun 13, 2019
314ce20
Merge remote-tracking branch 'origin' into apps-engine-livechat
d-gubert Aug 29, 2019
224a304
Fix Apps calls in statistics collector
d-gubert Aug 29, 2019
9be3a85
Bump Apps-Engine version
d-gubert Aug 30, 2019
f1d305a
Merge branch 'develop' into apps-engine-livechat
d-gubert Sep 2, 2019
6bba091
Merge remote-tracking branch 'origin/develop' into apps-engine-livechat
d-gubert Sep 11, 2019
ca6691e
Access livechat room’s deparment data (#15407)
rodrigok Sep 20, 2019
b0c3e4e
Bump apps-engine version
d-gubert Sep 20, 2019
91ee620
Merge remote-tracking branch 'origin/develop' into apps-engine-livechat
d-gubert Sep 20, 2019
fb29392
Bump Apps-Engine version
d-gubert Sep 20, 2019
135bb8c
Merge branch 'develop' into apps-engine-livechat
d-gubert Sep 20, 2019
50d73d6
Merge branch 'apps-engine-livechat' of github.com:RocketChat/Rocket.C…
d-gubert Sep 20, 2019
a9b24a0
Merge branch 'develop' into apps-engine-livechat
d-gubert Sep 21, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/apps/server/bridges/bridges.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { AppRoomBridge } from './rooms';
import { AppInternalBridge } from './internal';
import { AppSettingBridge } from './settings';
import { AppUserBridge } from './users';
import { AppLivechatBridge } from './livechat';
import { AppUploadBridge } from './uploads';

export class RealAppBridges extends AppBridges {
constructor(orch) {
Expand All @@ -31,6 +33,8 @@ export class RealAppBridges extends AppBridges {
this._internalBridge = new AppInternalBridge(orch);
this._setsBridge = new AppSettingBridge(orch);
this._userBridge = new AppUserBridge(orch);
this._livechatBridge = new AppLivechatBridge(orch);
this._uploadBridge = new AppUploadBridge(orch);
}

getCommandBridge() {
Expand Down Expand Up @@ -84,4 +88,12 @@ export class RealAppBridges extends AppBridges {
getUserBridge() {
return this._userBridge;
}

getLivechatBridge() {
return this._livechatBridge;
}

getUploadBridge() {
return this._uploadBridge;
}
}
28 changes: 28 additions & 0 deletions app/apps/server/bridges/http.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
import { HTTP } from 'meteor/http';

/**
* Normalize the options object to a shape
* the HTTP.call method recognizes
*
* @param Object options Http options received from the engine
*
*/
function normalizeHttpOptions(options) {
const npmRequestOptions = {};

if (options.hasOwnProperty('strictSSL')) {
npmRequestOptions.strictSSL = options.strictSSL;
delete options.strictSSL;
}

if (options.hasOwnProperty('rejectUnauthorized')) {
npmRequestOptions.agentOptions = {
rejectUnauthorized: options.rejectUnauthorized,
};

delete options.rejectUnauthorized;
}

options.npmRequestOptions = npmRequestOptions;
}

export class AppHttpBridge {
constructor(orch) {
this.orch = orch;
Expand All @@ -10,6 +36,8 @@ export class AppHttpBridge {
info.request.content = JSON.stringify(info.request.data);
}

normalizeHttpOptions(info.request);

this.orch.debugLog(`The App ${ info.appId } is requesting from the outter webs:`, info);

try {
Expand Down
135 changes: 135 additions & 0 deletions app/apps/server/bridges/livechat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { Random } from 'meteor/random';

import { getRoom } from '../../../livechat/server/api/lib/livechat';
import { Livechat } from '../../../livechat/server/lib/Livechat';
import Rooms from '../../../models/server/models/Rooms';
import LivechatVisitors from '../../../models/server/models/LivechatVisitors';
import Users from '../../../models/server/models/Users';

export class AppLivechatBridge {
constructor(orch) {
this.orch = orch;
}

async createMessage(message, appId) {
this.orch.debugLog(`The App ${ appId } is creating a new message.`);

if (!message.token) {
d-gubert marked this conversation as resolved.
Show resolved Hide resolved
throw new Error('Invalid token for livechat message');
}

const data = {
guest: this.orch.getConverters().get('visitors').convertAppVisitor(message.visitor),
message: this.orch.getConverters().get('messages').convertAppMessage(message),
};

const msg = Livechat.sendMessage(data);

return msg._id;
}

async getMessageById(messageId, appId) {
this.orch.debugLog(`The App ${ appId } is getting the message: "${ messageId }"`);

return this.orch.getConverters().get('messages').convertById(messageId);
}

async updateMessage(message, appId) {
this.orch.debugLog(`The App ${ appId } is updating a message.`);

const data = {
guest: message.visitor,
message: this.orch.getConverters().get('messages').convertAppMessage(message),
};

Livechat.updateMessage(data);
}

async createRoom(visitor, agent, appId) {
this.orch.debugLog(`The App ${ appId } is creating a livechat room.`);

const agentUser = Users.findOneById(agent.id);
agentUser.agentId = agentUser._id;

return this.orch.getConverters().get('rooms').convertRoom(getRoom({
guest: this.orch.getConverters().get('visitors').convertAppVisitor(visitor),
agent: agentUser,
rid: Random.id(),
}).room);
}

async closeRoom(room, comment, appId) {
this.orch.debugLog(`The App ${ appId } is closing a livechat room.`);

return Livechat.closeRoom({
visitor: this.orch.getConverters().get('visitors').convertAppVisitor(room.visitor),
room: this.orch.getConverters().get('rooms').convertAppRoom(room),
comment,
});
}

async findRooms(visitor, departmentId, appId) {
this.orch.debugLog(`The App ${ appId } is looking for livechat visitors.`);

if (!visitor) {
return [];
}

let result;

if (departmentId) {
result = Rooms.findOpenByVisitorTokenAndDepartmentId(visitor.token, departmentId).fetch();
} else {
result = Rooms.findOpenByVisitorToken(visitor.token).fetch();
}

return result.map((room) => this.orch.getConverters().get('rooms').convertRoom(room));
}

async createVisitor(visitor, appId) {
this.orch.debugLog(`The App ${ appId } is creating a livechat visitor.`);

const registerData = {
department: visitor.department,
username: visitor.username,
name: visitor.name,
token: visitor.token,
};

if (visitor.visitorEmails && visitor.visitorEmails.length) {
registerData.email = visitor.visitorEmails[0].address;
}

if (visitor.phone && visitor.phone.length) {
registerData.phone = { number: visitor.phone[0].phoneNumber };
}

return Livechat.registerGuest(registerData);
}

async transferVisitor(visitor, transferData, appId) {
this.orch.debugLog(`The App ${ appId } is transfering a livechat.`);

if (!visitor) {
throw new Error('Invalid visitor, cannot transfer');
}

const {
targetAgent,
targetDepartment: departmentId,
currentRoom,
} = transferData;

return Livechat.transfer(
this.orch.getConverters().get('rooms').convertAppRoom(currentRoom),
this.orch.getConverters().get('visitors').convertAppVisitor(visitor),
{ userId: targetAgent.id, departmentId }
);
}

async findVisitors(query, appId) {
this.orch.debugLog(`The App ${ appId } is looking for livechat visitors.`);

return LivechatVisitors.find(query).fetch().map((visitor) => this.orch.getConverters().get('visitors').convertVisitor(visitor));
}
}
27 changes: 27 additions & 0 deletions app/apps/server/bridges/uploads.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { FileUpload } from '../../../file-upload/server';

export class AppUploadBridge {
constructor(orch) {
this.orch = orch;
}

async getById(id, appId) {
this.orch.debugLog(`The App ${ appId } is getting the upload: "${ id }"`);

return this.orch.getConverters().get('uploads').convertById(id);
}

getBuffer(upload, appId) {
this.orch.debugLog(`The App ${ appId } is getting the upload: "${ upload.id }"`);

return new Promise((resolve, reject) => {
FileUpload.getBuffer(upload, (error, result) => {
if (error) {
return reject(error);
}

resolve(result);
});
});
}
}
52 changes: 52 additions & 0 deletions app/apps/server/converters/departments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import LivechatDepartment from '../../../models/server/models/LivechatDepartment';
import { transformMappedData } from '../../lib/misc/transformMappedData';

export class AppDepartmentsConverter {
constructor(orch) {
this.orch = orch;
}

convertById(id) {
const department = LivechatDepartment.findOneById(id);

return this.convertDepartment(department);
}

convertDepartment(department) {
if (!department) {
return undefined;
}

const map = {
id: '_id',
name: 'name',
email: 'email',
updatedAt: '_updatedAt',
enabled: 'enabled',
numberOfAgents: 'numAgents',
showOnOfflineForm: 'showOnOfflineForm',
showOnRegistration: 'showOnRegistration',
};

return transformMappedData(department, map);
}

convertAppDepartment(department) {
if (!department) {
return undefined;
}

const newDepartment = {
_id: department.id,
name: department.name,
email: department.email,
_updatedAt: department.updatedAt,
enabled: department.enabled,
numAgents: department.numberOfAgents,
showOnOfflineForm: department.showOnOfflineForm,
showOnRegistration: department.showOnRegistration,
};

return Object.assign(newDepartment, department._unmappedProperties_);
}
}
2 changes: 2 additions & 0 deletions app/apps/server/converters/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ export class AppMessagesConverter {
emoji: 'emoji',
avatarUrl: 'avatar',
alias: 'alias',
file: 'file',
customFields: 'customFields',
groupable: 'groupable',
token: 'token',
room: (message) => {
const result = this.orch.getConverters().get('rooms').convertById(message.rid);
delete message.rid;
Expand Down
Loading