support list conference (#321)

* support list conference

* add test case

* fix conference action requires tag

* fix failing test case
This commit is contained in:
Hoan Luu Huu
2024-05-28 10:31:16 -04:00
committed by GitHub
parent 82c16380f5
commit dbbc894832
7 changed files with 71 additions and 10 deletions
+3 -1
View File
@@ -46,7 +46,8 @@ const {
addKey, addKey,
retrieveKey, retrieveKey,
deleteKey, deleteKey,
incrKey incrKey,
listConferences
} = require('./lib/helpers/realtimedb-helpers'); } = require('./lib/helpers/realtimedb-helpers');
const { const {
getTtsVoices, getTtsVoices,
@@ -88,6 +89,7 @@ app.locals = {
deleteCall, deleteCall,
listCalls, listCalls,
listSortedSets, listSortedSets,
listConferences,
purgeCalls, purgeCalls,
retrieveSet, retrieveSet,
addKey, addKey,
+3 -1
View File
@@ -13,6 +13,7 @@ const {
deleteKey, deleteKey,
incrKey, incrKey,
client: redisClient, client: redisClient,
listConferences
} = require('@jambonz/realtimedb-helpers')({}, logger); } = require('@jambonz/realtimedb-helpers')({}, logger);
module.exports = { module.exports = {
@@ -27,5 +28,6 @@ module.exports = {
retrieveKey, retrieveKey,
deleteKey, deleteKey,
redisClient, redisClient,
incrKey incrKey,
listConferences
}; };
+18 -2
View File
@@ -323,10 +323,10 @@ function validateUpdateCall(opts) {
throw new DbErrorBadRequest( throw new DbErrorBadRequest(
`conferenceParticipantAction invalid action property ${opts.conferenceParticipantAction.action}`); `conferenceParticipantAction invalid action property ${opts.conferenceParticipantAction.action}`);
} }
if ('tag' == opts.conferenceParticipantAction.action && !opts.tag) { if ('tag' == opts.conferenceParticipantAction.action && !opts.conferenceParticipantAction.tag) {
throw new DbErrorBadRequest('conferenceParticipantAction requires tag property when action is \'tag\''); throw new DbErrorBadRequest('conferenceParticipantAction requires tag property when action is \'tag\'');
} }
if ('coach' == opts.conferenceParticipantAction.action && !opts.tag) { if ('coach' == opts.conferenceParticipantAction.action && !opts.conferenceParticipantAction.tag) {
throw new DbErrorBadRequest('conferenceParticipantAction requires tag property when action is \'coach\''); throw new DbErrorBadRequest('conferenceParticipantAction requires tag property when action is \'coach\'');
} }
} }
@@ -1103,5 +1103,21 @@ router.get('/:sid/Queues', async(req, res) => {
} }
}); });
/**
* retrieve info for a list of conferences under an account
*/
router.get('/:sid/Conferences', async(req, res) => {
const {logger, listConferences} = req.app.locals;
try {
const accountSid = parseAccountSid(req);
await validateRequest(req, accountSid);
const conferences = await listConferences(accountSid);
logger.debug(`retrieved ${conferences.length} queues for account sid ${accountSid}`);
res.status(200).json(conferences.map((c) => c.split(':').pop()));
updateLastUsed(logger, accountSid, req).catch((err) => {});
} catch (err) {
sysError(logger, res, err);
}
});
module.exports = router; module.exports = router;
+28
View File
@@ -3882,6 +3882,34 @@ paths:
$ref: '#/components/schemas/GeneralError' $ref: '#/components/schemas/GeneralError'
/Accounts/{AccountSid}/Conferences:
get:
tags:
- Conferences
summary: list conferences
operationId: listConferences
parameters:
- name: AccountSid
in: path
required: true
schema:
type: string
responses:
200:
description: list of conferences for a specified account
content:
application/json:
schema:
type: array
items:
type: string
500:
description: system error
content:
application/json:
schema:
$ref: '#/components/schemas/GeneralError'
/Accounts/{AccountSid}/Calls: /Accounts/{AccountSid}/Calls:
post: post:
tags: tags:
+4 -4
View File
@@ -18,7 +18,7 @@
"@jambonz/db-helpers": "^0.9.3", "@jambonz/db-helpers": "^0.9.3",
"@jambonz/lamejs": "^1.2.2", "@jambonz/lamejs": "^1.2.2",
"@jambonz/mw-registrar": "^0.2.7", "@jambonz/mw-registrar": "^0.2.7",
"@jambonz/realtimedb-helpers": "^0.8.8", "@jambonz/realtimedb-helpers": "^0.8.9",
"@jambonz/speech-utils": "^0.1.0", "@jambonz/speech-utils": "^0.1.0",
"@jambonz/time-series": "^0.2.8", "@jambonz/time-series": "^0.2.8",
"@jambonz/verb-specifications": "^0.0.69", "@jambonz/verb-specifications": "^0.0.69",
@@ -2018,9 +2018,9 @@
} }
}, },
"node_modules/@jambonz/realtimedb-helpers": { "node_modules/@jambonz/realtimedb-helpers": {
"version": "0.8.8", "version": "0.8.9",
"resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.8.8.tgz", "resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.8.9.tgz",
"integrity": "sha512-bzVz2EqJ7Gma5ysOh8J8Z1amw7szCBS1RSCLWEhtwPgYt6yWRdjgXbH7wHJ1qbZYYEfetfn7jeEaee8BYnoQlg==", "integrity": "sha512-+kVH+dgL6ZIaPDxZM9pwHGGZSYRrAZPvIMqNYd4dLrpduKxpYmdEG3ShfmFgXBZOQJq/Ysz5a75vrYCjtyBkyQ==",
"dependencies": { "dependencies": {
"debug": "^4.3.4", "debug": "^4.3.4",
"ioredis": "^5.3.2" "ioredis": "^5.3.2"
+1 -1
View File
@@ -28,7 +28,7 @@
"@jambonz/db-helpers": "^0.9.3", "@jambonz/db-helpers": "^0.9.3",
"@jambonz/lamejs": "^1.2.2", "@jambonz/lamejs": "^1.2.2",
"@jambonz/mw-registrar": "^0.2.7", "@jambonz/mw-registrar": "^0.2.7",
"@jambonz/realtimedb-helpers": "^0.8.8", "@jambonz/realtimedb-helpers": "^0.8.9",
"@jambonz/speech-utils": "^0.1.0", "@jambonz/speech-utils": "^0.1.0",
"@jambonz/time-series": "^0.2.8", "@jambonz/time-series": "^0.2.8",
"@jambonz/verb-specifications": "^0.0.69", "@jambonz/verb-specifications": "^0.0.69",
+14 -1
View File
@@ -14,7 +14,7 @@ const {
createPhoneNumber, createPhoneNumber,
deleteObjectBySid} = require('./utils'); deleteObjectBySid} = require('./utils');
const logger = require('../lib/logger'); const logger = require('../lib/logger');
const { addToSortedSet } = require('@jambonz/realtimedb-helpers')({ const { addToSortedSet, createHash } = require('@jambonz/realtimedb-helpers')({
host: process.env.JAMBONES_REDIS_HOST, host: process.env.JAMBONES_REDIS_HOST,
port: process.env.JAMBONES_REDIS_PORT || 6379 port: process.env.JAMBONES_REDIS_PORT || 6379
}, logger); }, logger);
@@ -314,6 +314,19 @@ test('account tests', async(t) => {
}); });
t.ok(result.statusCode === 200 && result.body.length === 0, 'successfully queried account queue info with for an invalid account'); t.ok(result.statusCode === 200 && result.body.length === 0, 'successfully queried account queue info with for an invalid account');
// query conferences
await createHash(`conf:${sid}:conf1`, 'url1');
await createHash(`conf:${sid}:conf2`, 'url2');
await createHash(`conf:${sid}:conf3`, 'url3');
await createHash(`conf:${sid}:conf4`, 'url4');
result = await request.get(`/Accounts/${sid}/Conferences`, {
auth: authAdmin,
resolveWithFullResponse: true,
json: true,
});
t.ok(result.statusCode === 200 && result.body.length === 4, 'successfully queried account conferences info for an account');
/* delete account */ /* delete account */
result = await request.delete(`/Accounts/${sid}`, { result = await request.delete(`/Accounts/${sid}`, {
auth: authAdmin, auth: authAdmin,