From 67fd1c5f6eb29dbc2289edc0ba7c6a9fb6890433 Mon Sep 17 00:00:00 2001 From: Koushik-Ayila Date: Wed, 27 Oct 2021 19:19:19 +0530 Subject: [PATCH 1/3] Added SDK changes for MPC Enhancements and missing MPC UTs --- .../MultiPartyCallInterface.php | 70 +++++++++++++++ src/Plivo/XML/MultiPartyCall.php | 21 ++++- ...allsStartParticipantRecordingResponse.json | 6 ++ ...multiPartyCallsStartPlayAudioResponse.json | 72 +++++++++++++++ tests/Resources/MultiPartyCallTest.php | 90 ++++++++++++++++++- 5 files changed, 257 insertions(+), 2 deletions(-) create mode 100644 tests/Mocks/multiPartyCallsStartParticipantRecordingResponse.json create mode 100644 tests/Mocks/multiPartyCallsStartPlayAudioResponse.json diff --git a/src/Plivo/Resources/MultiPartyCall/MultiPartyCallInterface.php b/src/Plivo/Resources/MultiPartyCall/MultiPartyCallInterface.php index 326936d7..dafdd881 100644 --- a/src/Plivo/Resources/MultiPartyCall/MultiPartyCallInterface.php +++ b/src/Plivo/Resources/MultiPartyCall/MultiPartyCallInterface.php @@ -353,6 +353,24 @@ public function addParticipant($role, array $optionalArgs = []){ else{ $optionalArgs['exit_sound_method'] = 'GET'; } + if(isset($optionalArgs['start_recording_audio'])){ + MPCUtils::validUrl('startRecordingAudio', $optionalArgs['start_recording_audio'], false); + } + if(isset($optionalArgs['start_recording_audio_method'])){ + MPCUtils::validParam('startRecordingAudioMethod', strtoupper($optionalArgs['start_recording_audio_method']), ['string'], false, ['GET', 'POST']); + } + else{ + $optionalArgs['start_recording_audio_method'] = 'GET'; + } + if(isset($optionalArgs['stop_recording_audio'])){ + MPCUtils::validUrl('stopRecordingAudio', $optionalArgs['stop_recording_audio'], false); + } + if(isset($optionalArgs['stop_recording_audio_method'])){ + MPCUtils::validParam('stopRecordingAudioMethod', strtoupper($optionalArgs['stop_recording_audio_method']), ['string'], false, ['GET', 'POST']); + } + else{ + $optionalArgs['stop_recording_audio_method'] = 'GET'; + } $mandatoryArgs = ['role' => $role]; $optionalArgs['isVoiceRequest'] = true; $response = $this->client->update( @@ -744,4 +762,56 @@ public function getParticipant($participantId, array $optionalArgs = []){ ); return $response->getContent(); } + + public function startPlayAudio($participantId, $url, array $optionalArgs = []){ + MPCUtils::validParam('participantId', $participantId, ['string', 'integer'], true); + MPCUtils::validUrl('url', $url, true); + if(isset($optionalArgs['uuid'])){ + MPCUtils::validParam('uuid', $optionalArgs['uuid'], ['string'],false); + } + if(isset($optionalArgs['friendly_name'])){ + MPCUtils::validParam('friendly_name', $optionalArgs['friendly_name'], ['string'],false); + } + if(!isset($optionalArgs['uuid'])){ + $optionalArgs['uuid'] = null; + } + if(!isset($optionalArgs['friendly_name'])){ + $optionalArgs['friendly_name'] = null; + } + $mpcId = self::mpcId($optionalArgs['uuid'], $optionalArgs['friendly_name']); + unset($optionalArgs['uuid']); + unset($optionalArgs['friendly_name']); + $mandatoryArgs = ['url' => $url]; + $optionalArgs['isVoiceRequest'] = true; + $response = $this->client->update( + $this->uri. $mpcId. '/Member/'. $participantId. '/Play/', + array_merge($mandatoryArgs, $optionalArgs) + ); + return $response->getContent(); + } + + public function stopPlayAudio($participantId, array $optionalArgs = []){ + MPCUtils::validParam('participantId', $participantId, ['string', 'integer'], true); + if(isset($optionalArgs['uuid'])){ + MPCUtils::validParam('uuid', $optionalArgs['uuid'], ['string'],false); + } + if(isset($optionalArgs['friendly_name'])){ + MPCUtils::validParam('friendly_name', $optionalArgs['friendly_name'], ['string'],false); + } + if(!isset($optionalArgs['uuid'])){ + $optionalArgs['uuid'] = null; + } + if(!isset($optionalArgs['friendly_name'])){ + $optionalArgs['friendly_name'] = null; + } + $mpcId = self::mpcId($optionalArgs['uuid'], $optionalArgs['friendly_name']); + unset($optionalArgs['uuid']); + unset($optionalArgs['friendly_name']); + $optionalArgs['isVoiceRequest'] = true; + $response = $this->client->delete( + $this->uri. $mpcId. '/Member/'. $participantId. '/Play/', + $optionalArgs + ); + return $response->getContent(); + } } \ No newline at end of file diff --git a/src/Plivo/XML/MultiPartyCall.php b/src/Plivo/XML/MultiPartyCall.php index fe11d89f..2432b89c 100644 --- a/src/Plivo/XML/MultiPartyCall.php +++ b/src/Plivo/XML/MultiPartyCall.php @@ -20,7 +20,8 @@ class MultiPartyCall extends Element { 'statusCallbackEvents', 'statusCallbackUrl', 'statusCallbackMethod', 'stayAlone', 'coachMode', 'mute', 'hold', 'startMpcOnEnter', 'endMpcOnExit', 'enterSound', 'enterSoundMethod', 'exitSound', 'exitSoundMethod', - 'onExitActionUrl', 'onExitActionMethod', 'relayDTMFInputs' + 'onExitActionUrl', 'onExitActionMethod', 'relayDTMFInputs', + 'startRecordingAudio', 'startRecordingAudioMethod', 'stopRecordingAudio', 'stopRecordingAudioMethod' ]; /** @@ -193,5 +194,23 @@ function __construct($body, $attributes = []) { if(isset($attributes['onExitActionUrl']) and !MPCUtils::validUrl('onExitActionUrl', $attributes['onExitActionUrl'], false)){ throw new PlivoXMLException('Invalid attribute value ' . $attributes['onExitActionUrl']. ' for onExitActionUrl'); } + if(isset($attributes['startRecordingAudio']) and !MPCUtils::validUrl('startRecordingAudio', $attributes['startRecordingAudio'], false)){ + throw new PlivoXMLException('Invalid attribute value ' . $attributes['startRecordingAudio']. ' for startRecordingAudio'); + } + if(isset($attributes['stopRecordingAudio']) and !MPCUtils::validUrl('stopRecordingAudio', $attributes['stopRecordingAudio'], false)){ + throw new PlivoXMLException('Invalid attribute value ' . $attributes['stopRecordingAudio']. ' for stopRecordingAudio'); + } + if(isset($attributes['startRecordingAudioMethod']) and !in_array(strtoupper($attributes['startRecordingAudioMethod']), $VALID_METHOD_VALUES, true)){ + throw new PlivoXMLException('Invalid attribute value ' . $attributes['startRecordingAudioMethod']. ' for startRecordingAudioMethod'); + } + elseif (!isset($attributes['startRecordingAudioMethod'])){ + $attributes['startRecordingAudioMethod'] = 'GET'; + } + if(isset($attributes['stopRecordingAudioMethod']) and !in_array(strtoupper($attributes['stopRecordingAudioMethod']), $VALID_METHOD_VALUES, true)){ + throw new PlivoXMLException('Invalid attribute value ' . $attributes['stopRecordingAudioMethod']. ' for stopRecordingAudioMethod'); + } + elseif (!isset($attributes['stopRecordingAudioMethod'])){ + $attributes['stopRecordingAudioMethod'] = 'GET'; + } } } \ No newline at end of file diff --git a/tests/Mocks/multiPartyCallsStartParticipantRecordingResponse.json b/tests/Mocks/multiPartyCallsStartParticipantRecordingResponse.json new file mode 100644 index 00000000..088197e4 --- /dev/null +++ b/tests/Mocks/multiPartyCallsStartParticipantRecordingResponse.json @@ -0,0 +1,6 @@ +{ + "api_id": "036c80f3-3721-11ec-a678-0242ac110002", + "message": "MPC: samplempc 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" +} \ No newline at end of file diff --git a/tests/Mocks/multiPartyCallsStartPlayAudioResponse.json b/tests/Mocks/multiPartyCallsStartPlayAudioResponse.json new file mode 100644 index 00000000..f306ad81 --- /dev/null +++ b/tests/Mocks/multiPartyCallsStartPlayAudioResponse.json @@ -0,0 +1,72 @@ +{ + "api_id": "c07db813-3721-11ec-8bcd-0242ac110008", + "message": "play queued into MPC", + "mpcMemberId": [ + "1003" + ], + "mpcName": "samplempc" +} + + +[role] => Agent +[call_uuid] => 1234-5678-4321-0987 +[call_status_callback_method] => POST +[confirm_key_sound_method] => GET +[dial_music] => Real +[ring_timeout] => 45 +[max_duration] => 14400 +[max_participants] => 10 +[wait_music_method] => GET +[agent_hold_music_method] => GET +[customer_hold_music_method] => GET +[recording_callback_method] => GET +[status_callback_method] => GET +[on_exit_action_method] => POST +[record] => +[record_file_format] => mp3 +[status_callback_events] => mpc-state-changes,participant-state-changes +[stay_alone] => +[coach_mode] => 1 +[mute] => +[hold] => +[start_mpc_on_enter] => 1 +[end_mpc_on_exit] => +[relay_dtmf_inputs] => +[enter_sound] => beep:1 +[enter_sound_method] => GET +[exit_sound] => beep:2 +[exit_sound_method] => GET +[start_recording_audio_method] => GET +[stop_recording_audio_method] => GET + +[role] => Agent +[call_uuid] => 1234-5678-4321-0987 +[call_status_callback_method] => POST +[confirm_key_sound_method] => GET +[dial_music] => Real +[ring_timeout] => 45 +[delay_dial] => 0 +[max_duration] => 14400 +[max_participants] => 10 +[wait_music_method] => GET +[agent_hold_music_method] => GET +[customer_hold_music_method] => GET +[recording_callback_method] => GET +[status_callback_method] => GET +[on_exit_action_method] => POST +[record] => +[record_file_format] => mp3 +[status_callback_events] => mpc-state-changes,participant-state-changes +[stay_alone] => +[coach_mode] => 1 +[mute] => +[hold] => +[start_mpc_on_enter] => 1 +[end_mpc_on_exit] => +[relay_dtmf_inputs] => +[enter_sound] => beep:1 +[enter_sound_method] => GET +[exit_sound] => beep:2 +[exit_sound_method] => GET +[start_recording_audio_method] => GET +[stop_recording_audio_method] => GET diff --git a/tests/Resources/MultiPartyCallTest.php b/tests/Resources/MultiPartyCallTest.php index eb043dee..79ff46c0 100644 --- a/tests/Resources/MultiPartyCallTest.php +++ b/tests/Resources/MultiPartyCallTest.php @@ -49,6 +49,7 @@ function testMPCAddParticipant(){ 'confirm_key_sound_method'=> 'GET', 'dial_music'=> 'Real', 'ring_timeout'=> 45, + 'delay_dial'=> 0, 'max_duration'=> 14400, 'max_participants'=> 10, 'wait_music_method'=> 'GET', @@ -71,6 +72,8 @@ function testMPCAddParticipant(){ 'enter_sound_method'=> 'GET', 'exit_sound'=> 'beep:2', 'exit_sound_method'=> 'GET', + 'start_recording_audio_method'=> 'GET', + 'stop_recording_audio_method'=> 'GET' ]); $body = file_get_contents(__DIR__ . '/../Mocks/multiPartyCallsAddParticipantResponse.json'); @@ -218,9 +221,94 @@ function testMPCGetParticipant(){ ); $body = file_get_contents(__DIR__ . '/../Mocks/multiPartyCallsGetParticipantResponse.json'); - $this->mock(new PlivoResponse($request,200)); + $this->mock(new PlivoResponse($request,200, $body)); $actual = $this->client->multiPartyCalls->getParticipant(10, ['uuid' => '12345678-90123456']); $this->assertRequest($request); self::assertNotNull($actual); } + + function testMPCStartParticipantRecording(){ + $request = new PlivoRequest( + 'POST', + 'Account/MAXXXXXXXXXXXXXXXXXX/MultiPartyCall/uuid_12345678-90123456/Participant/10/Record/', + ['file_format'=> 'wav', + 'status_callback_url'=> 'https://plivo.com/status', + 'status_callback_method'=> 'POST'] + ); + $body = file_get_contents(__DIR__ . '/../Mocks/multiPartyCallsStartParticipantRecordingResponse.json'); + + $this->mock(new PlivoResponse($request,200)); + $actual = $this->client->multiPartyCalls->startParticipantRecording(10, ['uuid' => '12345678-90123456', + 'file_format'=> 'wav', + 'status_callback_url'=> 'https://plivo.com/status', + 'status_callback_method'=> 'POST']); + $this->assertRequest($request); + self::assertNotNull($actual); + } + + function testMPCStopParticipantRecording(){ + $request = new PlivoRequest( + 'DELETE', + 'Account/MAXXXXXXXXXXXXXXXXXX/MultiPartyCall/uuid_12345678-90123456/Participant/10/Record/', + [] + ); + + $this->mock(new PlivoResponse($request,204)); + $actual = $this->client->multiPartyCalls->stopParticipantRecording(10, ['uuid' => '12345678-90123456']); + $this->assertRequest($request); + self::assertNotNull($actual); + } + + function testMPCPauseParticipantRecording(){ + $request = new PlivoRequest( + 'POST', + 'Account/MAXXXXXXXXXXXXXXXXXX/MultiPartyCall/uuid_12345678-90123456/Participant/10/Record/Pause/', + [] + ); + + $this->mock(new PlivoResponse($request,204)); + $actual = $this->client->multiPartyCalls->pauseParticipantRecording(10, ['uuid' => '12345678-90123456']); + $this->assertRequest($request); + self::assertNotNull($actual); + } + + function testMPCResumeParticipantRecording(){ + $request = new PlivoRequest( + 'POST', + 'Account/MAXXXXXXXXXXXXXXXXXX/MultiPartyCall/uuid_12345678-90123456/Participant/10/Record/Resume/', + [] + ); + + $this->mock(new PlivoResponse($request,204)); + $actual = $this->client->multiPartyCalls->resumeParticipantRecording(10, ['uuid' => '12345678-90123456']); + $this->assertRequest($request); + self::assertNotNull($actual); + } + + function testMPCStartPlayAudio(){ + $request = new PlivoRequest( + 'POST', + 'Account/MAXXXXXXXXXXXXXXXXXX/MultiPartyCall/uuid_12345678-90123456/Member/10/Play/', + ['url' => 'https://s3.amazonaws.com/XXX/XXX.mp3'] + ); + $body = file_get_contents(__DIR__ . '/../Mocks/multiPartyCallsStartPlayAudioResponse.json'); + + $this->mock(new PlivoResponse($request,202, $body)); + $actual = $this->client->multiPartyCalls->startPlayAudio(10, "https://s3.amazonaws.com/XXX/XXX.mp3", ['uuid' => '12345678-90123456']); + $this->assertRequest($request); + self::assertNotNull($actual); + } + + function testMPCStopPlayAudio(){ + $request = new PlivoRequest( + 'DELETE', + 'Account/MAXXXXXXXXXXXXXXXXXX/MultiPartyCall/uuid_12345678-90123456/Member/10/Play/', + [] + ); + + $this->mock(new PlivoResponse($request,204)); + $actual = $this->client->multiPartyCalls->stopPlayAudio(10, ['uuid' => '12345678-90123456']); + $this->assertRequest($request); + self::assertNotNull($actual); + } } \ No newline at end of file From c2434e0edaec4b8df17a30f44dd2a4de03fe1c93 Mon Sep 17 00:00:00 2001 From: Koushik-Ayila Date: Wed, 27 Oct 2021 19:21:09 +0530 Subject: [PATCH 2/3] Correct mock response --- ...multiPartyCallsStartPlayAudioResponse.json | 66 +------------------ 1 file changed, 1 insertion(+), 65 deletions(-) diff --git a/tests/Mocks/multiPartyCallsStartPlayAudioResponse.json b/tests/Mocks/multiPartyCallsStartPlayAudioResponse.json index f306ad81..f1dc9a68 100644 --- a/tests/Mocks/multiPartyCallsStartPlayAudioResponse.json +++ b/tests/Mocks/multiPartyCallsStartPlayAudioResponse.json @@ -5,68 +5,4 @@ "1003" ], "mpcName": "samplempc" -} - - -[role] => Agent -[call_uuid] => 1234-5678-4321-0987 -[call_status_callback_method] => POST -[confirm_key_sound_method] => GET -[dial_music] => Real -[ring_timeout] => 45 -[max_duration] => 14400 -[max_participants] => 10 -[wait_music_method] => GET -[agent_hold_music_method] => GET -[customer_hold_music_method] => GET -[recording_callback_method] => GET -[status_callback_method] => GET -[on_exit_action_method] => POST -[record] => -[record_file_format] => mp3 -[status_callback_events] => mpc-state-changes,participant-state-changes -[stay_alone] => -[coach_mode] => 1 -[mute] => -[hold] => -[start_mpc_on_enter] => 1 -[end_mpc_on_exit] => -[relay_dtmf_inputs] => -[enter_sound] => beep:1 -[enter_sound_method] => GET -[exit_sound] => beep:2 -[exit_sound_method] => GET -[start_recording_audio_method] => GET -[stop_recording_audio_method] => GET - -[role] => Agent -[call_uuid] => 1234-5678-4321-0987 -[call_status_callback_method] => POST -[confirm_key_sound_method] => GET -[dial_music] => Real -[ring_timeout] => 45 -[delay_dial] => 0 -[max_duration] => 14400 -[max_participants] => 10 -[wait_music_method] => GET -[agent_hold_music_method] => GET -[customer_hold_music_method] => GET -[recording_callback_method] => GET -[status_callback_method] => GET -[on_exit_action_method] => POST -[record] => -[record_file_format] => mp3 -[status_callback_events] => mpc-state-changes,participant-state-changes -[stay_alone] => -[coach_mode] => 1 -[mute] => -[hold] => -[start_mpc_on_enter] => 1 -[end_mpc_on_exit] => -[relay_dtmf_inputs] => -[enter_sound] => beep:1 -[enter_sound_method] => GET -[exit_sound] => beep:2 -[exit_sound_method] => GET -[start_recording_audio_method] => GET -[stop_recording_audio_method] => GET +} \ No newline at end of file From 100abd6de2c54bbaaefb13db9b5d28086ced4a29 Mon Sep 17 00:00:00 2001 From: Abinaya-plivo Date: Tue, 16 Nov 2021 17:18:24 +0530 Subject: [PATCH 3/3] remove code changes of start recording and stop recording announcements on MPC --- .../MultiPartyCallInterface.php | 18 ---------------- src/Plivo/XML/MultiPartyCall.php | 21 +------------------ tests/Resources/MultiPartyCallTest.php | 4 +--- 3 files changed, 2 insertions(+), 41 deletions(-) diff --git a/src/Plivo/Resources/MultiPartyCall/MultiPartyCallInterface.php b/src/Plivo/Resources/MultiPartyCall/MultiPartyCallInterface.php index dafdd881..ecd58e4f 100644 --- a/src/Plivo/Resources/MultiPartyCall/MultiPartyCallInterface.php +++ b/src/Plivo/Resources/MultiPartyCall/MultiPartyCallInterface.php @@ -353,24 +353,6 @@ public function addParticipant($role, array $optionalArgs = []){ else{ $optionalArgs['exit_sound_method'] = 'GET'; } - if(isset($optionalArgs['start_recording_audio'])){ - MPCUtils::validUrl('startRecordingAudio', $optionalArgs['start_recording_audio'], false); - } - if(isset($optionalArgs['start_recording_audio_method'])){ - MPCUtils::validParam('startRecordingAudioMethod', strtoupper($optionalArgs['start_recording_audio_method']), ['string'], false, ['GET', 'POST']); - } - else{ - $optionalArgs['start_recording_audio_method'] = 'GET'; - } - if(isset($optionalArgs['stop_recording_audio'])){ - MPCUtils::validUrl('stopRecordingAudio', $optionalArgs['stop_recording_audio'], false); - } - if(isset($optionalArgs['stop_recording_audio_method'])){ - MPCUtils::validParam('stopRecordingAudioMethod', strtoupper($optionalArgs['stop_recording_audio_method']), ['string'], false, ['GET', 'POST']); - } - else{ - $optionalArgs['stop_recording_audio_method'] = 'GET'; - } $mandatoryArgs = ['role' => $role]; $optionalArgs['isVoiceRequest'] = true; $response = $this->client->update( diff --git a/src/Plivo/XML/MultiPartyCall.php b/src/Plivo/XML/MultiPartyCall.php index 2432b89c..fe11d89f 100644 --- a/src/Plivo/XML/MultiPartyCall.php +++ b/src/Plivo/XML/MultiPartyCall.php @@ -20,8 +20,7 @@ class MultiPartyCall extends Element { 'statusCallbackEvents', 'statusCallbackUrl', 'statusCallbackMethod', 'stayAlone', 'coachMode', 'mute', 'hold', 'startMpcOnEnter', 'endMpcOnExit', 'enterSound', 'enterSoundMethod', 'exitSound', 'exitSoundMethod', - 'onExitActionUrl', 'onExitActionMethod', 'relayDTMFInputs', - 'startRecordingAudio', 'startRecordingAudioMethod', 'stopRecordingAudio', 'stopRecordingAudioMethod' + 'onExitActionUrl', 'onExitActionMethod', 'relayDTMFInputs' ]; /** @@ -194,23 +193,5 @@ function __construct($body, $attributes = []) { if(isset($attributes['onExitActionUrl']) and !MPCUtils::validUrl('onExitActionUrl', $attributes['onExitActionUrl'], false)){ throw new PlivoXMLException('Invalid attribute value ' . $attributes['onExitActionUrl']. ' for onExitActionUrl'); } - if(isset($attributes['startRecordingAudio']) and !MPCUtils::validUrl('startRecordingAudio', $attributes['startRecordingAudio'], false)){ - throw new PlivoXMLException('Invalid attribute value ' . $attributes['startRecordingAudio']. ' for startRecordingAudio'); - } - if(isset($attributes['stopRecordingAudio']) and !MPCUtils::validUrl('stopRecordingAudio', $attributes['stopRecordingAudio'], false)){ - throw new PlivoXMLException('Invalid attribute value ' . $attributes['stopRecordingAudio']. ' for stopRecordingAudio'); - } - if(isset($attributes['startRecordingAudioMethod']) and !in_array(strtoupper($attributes['startRecordingAudioMethod']), $VALID_METHOD_VALUES, true)){ - throw new PlivoXMLException('Invalid attribute value ' . $attributes['startRecordingAudioMethod']. ' for startRecordingAudioMethod'); - } - elseif (!isset($attributes['startRecordingAudioMethod'])){ - $attributes['startRecordingAudioMethod'] = 'GET'; - } - if(isset($attributes['stopRecordingAudioMethod']) and !in_array(strtoupper($attributes['stopRecordingAudioMethod']), $VALID_METHOD_VALUES, true)){ - throw new PlivoXMLException('Invalid attribute value ' . $attributes['stopRecordingAudioMethod']. ' for stopRecordingAudioMethod'); - } - elseif (!isset($attributes['stopRecordingAudioMethod'])){ - $attributes['stopRecordingAudioMethod'] = 'GET'; - } } } \ No newline at end of file diff --git a/tests/Resources/MultiPartyCallTest.php b/tests/Resources/MultiPartyCallTest.php index 79ff46c0..c0135bd4 100644 --- a/tests/Resources/MultiPartyCallTest.php +++ b/tests/Resources/MultiPartyCallTest.php @@ -71,9 +71,7 @@ function testMPCAddParticipant(){ 'enter_sound'=> 'beep:1', 'enter_sound_method'=> 'GET', 'exit_sound'=> 'beep:2', - 'exit_sound_method'=> 'GET', - 'start_recording_audio_method'=> 'GET', - 'stop_recording_audio_method'=> 'GET' + 'exit_sound_method'=> 'GET' ]); $body = file_get_contents(__DIR__ . '/../Mocks/multiPartyCallsAddParticipantResponse.json');