Merge branch 'master' into 10dlc-api

This commit is contained in:
Narayana Shanubhogh 2021-12-02 11:29:12 +05:30 committed by GitHub
commit 744488e2d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 207 additions and 14 deletions

View file

@ -1,10 +0,0 @@
service_name: travis-ci
language: node_js
node_js:
# - "node" commenting this as we have to find out a solution for node12 & gulp3
- "lts/*"
- "8"
- "7"
- "6"
- "5"
- "4"

View file

@ -1,7 +1,13 @@
# Change Log
## [v4.24.0](https://github.com/plivo/plivo-node/tree/v4.24.0) (2021-12-02)
-- 10dlc Api support.
## [v4.25.0](https://github.com/plivo/plivo-node/tree/v4.25.0) (2021-12-02)
**Features - SMS: 10dlc Api support**
- Brand and Campaign API.
## [v4.24.0](https://github.com/plivo/plivo-node/tree/v4.24.0) (2021-11-30)
**Features - Voice: Multiparty calls**
- The [Add Multiparty Call API](https://www.plivo.com/docs/voice/api/multiparty-call/participants#add-a-participant) allows for greater functionality by accepting options like `start recording audio`, `stop recording audio`, and their HTTP methods.
- [Multiparty Calls](https://www.plivo.com/docs/voice/api/multiparty-call/) now has new APIs to `stop` and `play` audio.
## [v4.23.1](https://github.com/plivo/plivo-node/tree/v4.23.1) (2021-10-13)
**Bug Fix**

View file

@ -15,6 +15,7 @@ const clientKey = Symbol();
const action = 'MultiPartyCall/';
const idField = 'mpcUuid';
const secondaryAction = 'Participant/';
const secondaryMemberAction = 'Member/';
const secondaryIdField = 'participantUuid';
export class MPCError extends Error { }
@ -306,6 +307,29 @@ export class MultiPartyCall extends PlivoResource{
else {
params.exitSoundMethod = 'GET'
}
if(params.startRecordingAudio){
validUrl('startRecordingAudio', params.startRecordingAudio, false)
}
if(params.startRecordingAudioMethod){
validParam('startRecordingAudioMethod', params.startRecordingAudioMethod.toUpperCase(), [String], false, ['GET', 'POST'])
}
else {
params.startRecordingAudioMethod = 'GET'
}
if(params.stopRecordingAudio){
validUrl('stopRecordingAudio', params.stopRecordingAudio, false)
}
if(params.stopRecordingAudioMethod){
validParam('stopRecordingAudioMethod', params.stopRecordingAudioMethod.toUpperCase(), [String], false, ['GET', 'POST'])
}
else {
params.stopRecordingAudioMethod = 'GET'
}
if(params.to && (String(params.ringTimeout).split('<').length > params.to.split('<').length)){
throw new MPCError("RingTimeout:number of ring_timeout(s) should be same as number of destination(s)")
}
@ -449,6 +473,32 @@ export class MultiPartyCallParticipant extends PlivoSecondaryResource{
}
export class MultiPartyCallMember extends PlivoSecondaryResource{
constructor(client, data= {}) {
super(action, MultiPartyCall, idField, secondaryMemberAction, MultiPartyCallMember, secondaryIdField, client);
if (idField in data) {
this.id = data[idField];
}
if(secondaryIdField in data){
this.secondaryId = data[secondaryIdField];
}
extend(this, data);
this[clientKey] = client;
}
startPlayAudio(params){
params.isVoiceRequest = 'true';
return super.executeAction(this.id, this.secondaryId + '/Play', 'POST', params)
}
stopPlayAudio(){
return super.executeAction(this.id, this.secondaryId +'/Play', 'DELETE',{'isVoiceRequest' : 'true'})
}
}
export class MultiPartyCallInterface extends PlivoResourceInterface{
constructor(client, data = {}) {
super(action, MultiPartyCall, idField, client);
@ -737,4 +787,33 @@ export class MultiPartyCallInterface extends PlivoResourceInterface{
return new MultiPartyCallParticipant(this[clientKey], {id: mpcId[0] + mpcId[1], secondaryId: participantId}).getParticipant()
}
startPlayAudio(participantId, url, params = {}){
validParam('participantId', participantId, [String, Number], true)
validUrl('url', url, true)
if(params.uuid){
validParam('uuid', params.uuid, [String], false)
}
if(params.friendlyName){
validParam('friendlyName', params.friendlyName, [String], false)
}
let mpcId = this.makeMpcId(params.uuid, params.friendlyName)
delete params.uuid
delete params.friendlyName
params.url = url
return new MultiPartyCallMember(this[clientKey], {id: mpcId[0] + mpcId[1], secondaryId: participantId}).startPlayAudio(params)
}
stopPlayAudio(participantId, params = {}){
validParam('participantId', participantId, [String, Number], true)
if(params.uuid){
validParam('uuid', params.uuid, [String], false)
}
if(params.friendlyName){
validParam('friendlyName', params.friendlyName, [String], false)
}
let mpcId = this.makeMpcId(params.uuid, params.friendlyName)
delete params.uuid
delete params.friendlyName
return new MultiPartyCallMember(this[clientKey], {id: mpcId[0] + mpcId[1], secondaryId: participantId}).stopPlayAudio(params)
}
}

View file

@ -883,6 +883,60 @@ export function Request(config) {
});
}
else if (method === 'POST' && action === 'MultiPartyCall/name_TestMPC/Participant/10/Record/'){
resolve({
response: {},
body: {
"api_id": "036c80f3-3721-11ec-a678-0242ac110002",
"message": "MPC: TestMPC participant record started",
"recording_id": "24670db8-c723-4ba2-8521-f10ec41ddf8b",
"recording_url": "https://media-qa.voice.plivodev.com/v1/Account/MAXXXXXXXXXXXX/Recording/XXXXX-XXXX-XXXX-XXXXX.mp3"
}
});
}
else if (method === 'DELETE' && action === 'MultiPartyCall/name_TestMPC/Participant/10/Record/'){
resolve({
response: {},
body: {}
});
}
else if (method === 'POST' && action === 'MultiPartyCall/name_TestMPC/Participant/10/Record/Pause/'){
resolve({
response: {},
body: {}
});
}
else if (method === 'POST' && action === 'MultiPartyCall/name_TestMPC/Participant/10/Record/Resume/'){
resolve({
response: {},
body: {}
});
}
else if (method === 'POST' && action === 'MultiPartyCall/name_TestMPC/Member/10/Play/'){
resolve({
response: {},
body: {
"api_id": "c07db813-3721-11ec-8bcd-0242ac110008",
"message": "play queued into MPC",
"mpcMemberId": [
"1003"
],
"mpcName": "TestMPC"
}
});
}
else if (method === 'DELETE' && action === 'MultiPartyCall/name_TestMPC/Member/10/Play/'){
resolve({
response: {},
body: {}
});
}
// ============= Numbers ===================
else if (method == 'GET' && action == 'Number/+919999999990/') {
resolve({

View file

@ -473,6 +473,10 @@ Response.prototype = {
* @param {string} [attributes.recordingCallbackUrl]
* @param {string} [attributes.statusCallbackUrl]
* @param {string} [attributes.customerHoldMusicUrl]
* @param {string} [attributes.startRecordingAudio]
* @param {string} [attributes.stopRecordingAudio]
* @param {string} [attributes.startRecordingAudioMethod]
* @param {string} [attributes.stopRecordingAudioMethod]
*/
addMultiPartyCall: function (body, attributes){
const VALID_ROLE_VALUES = ['agent', 'supervisor', 'customer']
@ -664,6 +668,28 @@ Response.prototype = {
if(attributes.customerHoldMusicUrl && !plivoUtils.validUrl('customerHoldMusicUrl', attributes.customerHoldMusicUrl, false)){
throw new PlivoXMLError('Invalid attribute value ' + attributes.customerHoldMusicUrl + ' for customerHoldMusicUrl')
}
if(attributes.startRecordingAudio && !plivoUtils.validUrl('startRecordingAudio', attributes.startRecordingAudio, false)){
throw new PlivoXMLError('Invalid attribute value ' + attributes.startRecordingAudio + ' for startRecordingAudio')
}
if(attributes.stopRecordingAudio && !plivoUtils.validUrl('stopRecordingAudio', attributes.stopRecordingAudio, false)){
throw new PlivoXMLError('Invalid attribute value ' + attributes.stopRecordingAudio + ' for stopRecordingAudio')
}
if(attributes.startRecordingAudioMethod && VALID_METHOD_VALUES.indexOf(attributes.startRecordingAudioMethod.toUpperCase())===-1){
throw new PlivoXMLError('Invalid attribute value ' + attributes.startRecordingAudioMethod + ' for startRecordingAudioMethod')
}
else if (!attributes.startRecordingAudioMethod){
attributes.startRecordingAudioMethod = 'GET'
}
if(attributes.stopRecordingAudioMethod && VALID_METHOD_VALUES.indexOf(attributes.stopRecordingAudioMethod.toUpperCase())===-1){
throw new PlivoXMLError('Invalid attribute value ' + attributes.stopRecordingAudioMethod + ' for stopRecordingAudioMethod')
}
else if (!attributes.stopRecordingAudioMethod){
attributes.stopRecordingAudioMethod = 'GET'
}
return this.add(new MultiPartyCall(Response), body, attributes);
},
@ -984,6 +1010,7 @@ function MultiPartyCall(Response){
'statusCallbackEvents', 'statusCallbackUrl', 'statusCallbackMethod',
'stayAlone', 'coachMode', 'mute', 'hold', 'startMpcOnEnter', 'endMpcOnExit',
'enterSound', 'enterSoundMethod', 'exitSound', 'exitSoundMethod',
'onExitActionUrl', 'onExitActionMethod', 'relayDTMFInputs'];
'onExitActionUrl', 'onExitActionMethod', 'relayDTMFInputs',
'startRecordingAudio', 'startRecordingAudioMethod', 'stopRecordingAudio', 'stopRecordingAudioMethod'];
}
util.inherits(MultiPartyCall, Response);

View file

@ -92,4 +92,41 @@ describe('multiPartyCalls', function (){
assert.equal(response.resourceUri, '/v1/Account/MAMDJMMTEZOWY0ZMQWM2/MultiPartyCall/uuid_7503f05f-2d6e-4ab3-b9e6-3b0d81ae9087/Participant/2132/')
})
});
it('should start MPC Participant Recording', function (){
return client.multiPartyCalls.startParticipantRecording(10, {friendlyName: 'TestMPC'}).then(function (response){
assert(response.message, "MPC: TestMPC participant record started")
})
});
it('should stop MPC Participant Recording', function (){
return client.multiPartyCalls.stopParticipantRecording(10,{friendlyName: 'TestMPC'}).then(function (response){
assert(response instanceof PlivoGenericResponse)
})
});
it('should pause MPC Participant Recording', function (){
return client.multiPartyCalls.pauseParticipantRecording(10,{friendlyName: 'TestMPC'}).then(function (response){
assert(response instanceof PlivoGenericResponse)
})
});
it('should resume MPC Participant Recording', function (){
return client.multiPartyCalls.resumeParticipantRecording(10,{friendlyName: 'TestMPC'}).then(function (response){
assert(response instanceof PlivoGenericResponse)
})
});
it('should start MPC Play Audio Member', function (){
return client.multiPartyCalls.startPlayAudio(10,'https://s3.amazonaws.com/XXX/XXX.mp3',
{friendlyName: 'TestMPC'}).then(function (response){
assert(response.message, "play queued into MPC")
})
});
it('should stop MPC Play Audio Member', function (){
return client.multiPartyCalls.stopPlayAudio(10,{friendlyName: 'TestMPC'}).then(function (response){
assert(response instanceof PlivoGenericResponse)
})
});
})

View file

@ -35,7 +35,7 @@ describe('PlivoXML', function () {
maxDuration: 1000,
statusCallbackEvents: 'participant-speak-events, participant-digit-input-events, add-participant-api-events, participant-state-changes, mpc-state-changes'
});
assert.equal('<Response><MultiPartyCall role="Agent" maxDuration="1000" statusCallbackEvents="participant-speak-events, participant-digit-input-events, add-participant-api-events, participant-state-changes, mpc-state-changes" maxParticipants="10" waitMusicMethod="GET" agentHoldMusicMethod="GET" customerHoldMusicMethod="GET" record="false" recordFileFormat="mp3" recordingCallbackMethod="GET" statusCallbackMethod="POST" stayAlone="false" coachMode="true" mute="false" hold="false" startMpcOnEnter="true" endMpcOnExit="false" enterSound="beep:1" enterSoundMethod="GET" exitSound="beep:2" exitSoundMethod="GET" onExitActionMethod="POST" relayDTMFInputs="false">Nairobi</MultiPartyCall></Response>',mpcResponse.toXML());
assert.equal('<Response><MultiPartyCall role="Agent" maxDuration="1000" statusCallbackEvents="participant-speak-events, participant-digit-input-events, add-participant-api-events, participant-state-changes, mpc-state-changes" maxParticipants="10" waitMusicMethod="GET" agentHoldMusicMethod="GET" customerHoldMusicMethod="GET" record="false" recordFileFormat="mp3" recordingCallbackMethod="GET" statusCallbackMethod="POST" stayAlone="false" coachMode="true" mute="false" hold="false" startMpcOnEnter="true" endMpcOnExit="false" enterSound="beep:1" enterSoundMethod="GET" exitSound="beep:2" exitSoundMethod="GET" onExitActionMethod="POST" relayDTMFInputs="false" startRecordingAudioMethod="GET" stopRecordingAudioMethod="GET">Nairobi</MultiPartyCall></Response>',mpcResponse.toXML());
done();
});
});