Skip to content

Commit 8bc0d8c

Browse files
committed
Merge branch 'new/livechat-voip' of github.com:RocketChat/Rocket.Chat into new/livechat-voip
2 parents f9d071b + f768d9d commit 8bc0d8c

File tree

26 files changed

+1034
-149
lines changed

26 files changed

+1034
-149
lines changed

app/api/server/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,7 @@ import './v1/instances';
4444
import './v1/banners';
4545
import './v1/email-inbox';
4646
import './v1/teams';
47+
import './v1/voip/asterisk-connector';
48+
import './v1/voip/server-config';
4749

4850
export { API, APIClass, defaultRateLimiterOptions } from './api';
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
2+
import { API } from '../../api';
3+
import { Commands } from '../../../../../server/services/voip/connector/asterisk/Commands';
4+
import { CommandHandler } from '../../../../../server/services/voip/connector/asterisk/CommandHandler';
5+
import { IVoipExtensionBase, IVoipExtensionConfig } from '../../../../../definition/IVoipExtension';
6+
7+
8+
const commandHandler = new CommandHandler();
9+
// Get the connector version and type
10+
API.v1.addRoute('connector.getversion', { authRequired: true }, {
11+
get() {
12+
return API.v1.success(commandHandler.getVersion());
13+
},
14+
});
15+
16+
// Get the extensions available on the call server
17+
API.v1.addRoute('connector.extension.list', { authRequired: true }, {
18+
get() {
19+
const list = Promise.await (
20+
commandHandler.executeCommand(Commands.extension_list, undefined)) as IVoipExtensionBase;
21+
this.logger.debug(`API = connector.extension.list JSON=${ JSON.stringify(list) }`);
22+
return API.v1.success({ extensions: list });
23+
},
24+
});
25+
26+
/* Get the details of a single extension.
27+
* Note : This API will either be called by the endpoint
28+
* or will be consumed internally.
29+
*/
30+
API.v1.addRoute('connector.extension.getDetails', { authRequired: true }, {
31+
get() {
32+
const endpointDetails = Promise.await (
33+
commandHandler.executeCommand(
34+
Commands.extension_info,
35+
this.requestParams())) as IVoipExtensionConfig;
36+
return API.v1.success({ ...endpointDetails });
37+
},
38+
});
39+
40+
/* Get the details for registration extension.
41+
*/
42+
API.v1.addRoute('connector.extension.getRegistrationInfo', { authRequired: true }, {
43+
get() {
44+
/**
45+
* REMOVE_THIS
46+
* Note : Once Murtaza's code reviews are done,
47+
* this hardcoding will be removed.
48+
*
49+
*/
50+
const serverConfig = {
51+
sipRegistrar: 'omni-asterisk.dev.rocket.chat',
52+
websocketUri: 'wss://omni-asterisk.dev.rocket.chat/ws',
53+
};
54+
/**
55+
* REMOVE_THIS
56+
*/
57+
const endpointDetails = Promise.await (commandHandler.executeCommand(
58+
Commands.extension_info,
59+
this.requestParams())) as IVoipExtensionConfig;
60+
61+
const extensionRegistrationInfo = {
62+
sipRegistrar: serverConfig.sipRegistrar,
63+
websocketUri: serverConfig.websocketUri,
64+
extension: endpointDetails.name,
65+
password: endpointDetails.password,
66+
};
67+
return API.v1.success({ ...extensionRegistrationInfo });
68+
},
69+
});
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { Match, check } from 'meteor/check';
2+
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
3+
4+
import { API } from '../../api';
5+
import { hasPermission } from '../../../../authorization/server';
6+
import { Voip } from '../../../../../server/sdk';
7+
import { ICallServerConfigData, IManagementConfigData, ServerType } from '../../../../../definition/IVoipServerConfig';
8+
9+
// management api(s)
10+
API.v1.addRoute('voipServerConfig.management', { authRequired: true }, {
11+
get() {
12+
if (!hasPermission(this.userId, 'manage-voip-contact-center-settings')) {
13+
return API.v1.unauthorized(TAPi18n._('error-insufficient-permission', { permission: 'manage-voip-contact-center-settings' }));
14+
}
15+
16+
const config = Promise.await(Voip.getServerConfigData(ServerType.MANAGEMENT));
17+
18+
if (!config) {
19+
return API.v1.notFound();
20+
}
21+
22+
return API.v1.success({ ...config });
23+
},
24+
// NOTE: you can use this POST endpoint for both create and update operation
25+
post() {
26+
check(this.bodyParams, Match.ObjectIncluding({
27+
host: String,
28+
port: Number,
29+
serverName: String,
30+
username: String,
31+
password: String,
32+
}));
33+
34+
if (!hasPermission(this.userId, 'manage-voip-contact-center-settings')) {
35+
return API.v1.unauthorized(TAPi18n._('error-insufficient-permission', { permission: 'manage-voip-contact-center-settings' }));
36+
}
37+
38+
const { host, port, serverName, username, password } = this.bodyParams;
39+
40+
Promise.await(Voip.addServerConfigData({
41+
type: ServerType.MANAGEMENT,
42+
host,
43+
name: serverName,
44+
active: true,
45+
configData: {
46+
port,
47+
username,
48+
password,
49+
} as IManagementConfigData,
50+
}));
51+
52+
return API.v1.success();
53+
},
54+
});
55+
56+
// call-server api(s)
57+
API.v1.addRoute('voipServerConfig.callServer', { authRequired: true }, {
58+
get() {
59+
if (!hasPermission(this.userId, 'manage-voip-call-settings')) {
60+
return API.v1.unauthorized(TAPi18n._('error-insufficient-permission', { permission: 'manage-voip-call-settings' }));
61+
}
62+
63+
const config = Promise.await(Voip.getServerConfigData(ServerType.CALL_SERVER));
64+
if (!config) {
65+
return API.v1.notFound();
66+
}
67+
68+
return API.v1.success({ ...config });
69+
},
70+
// NOTE: you can use this POST endpoint for both create and update operation
71+
post() {
72+
check(this.bodyParams, Match.ObjectIncluding({
73+
host: String,
74+
serverName: String,
75+
websocketPort: Number,
76+
websocketPath: String,
77+
}));
78+
79+
if (!hasPermission(this.userId, 'manage-voip-call-settings')) {
80+
return API.v1.unauthorized(TAPi18n._('error-insufficient-permission', { permission: 'manage-voip-call-settings' }));
81+
}
82+
83+
const { host, websocketPort, websocketPath, serverName } = this.bodyParams;
84+
85+
Promise.await(Voip.addServerConfigData({
86+
type: ServerType.CALL_SERVER,
87+
host,
88+
name: serverName,
89+
active: true,
90+
configData: {
91+
websocketPort,
92+
websocketPath,
93+
} as ICallServerConfigData,
94+
}));
95+
96+
return API.v1.success();
97+
},
98+
});

app/authorization/server/startup.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@ Meteor.startup(function() {
140140
{ _id: 'view-all-teams', roles: ['admin'] },
141141
{ _id: 'remove-closed-livechat-room', roles: ['livechat-manager', 'admin'] },
142142
{ _id: 'remove-livechat-department', roles: ['livechat-manager', 'admin'] },
143+
144+
// VOIP Permissions
145+
// allows to manage voip calls configuration
146+
{ _id: 'manage-voip-call-settings', roles: ['livechat-manager', 'admin'] },
147+
{ _id: 'manage-voip-contact-center-settings', roles: ['livechat-manager', 'admin'] },
148+
// allows to receive a voip call
149+
{ _id: 'inbound-voip-calls', roles: ['livechat-agent'] },
143150
];
144151

145152
for (const permission of permissions) {

0 commit comments

Comments
 (0)