Skip to content

Commit

Permalink
added DTMF mode with logic
Browse files Browse the repository at this point in the history
  • Loading branch information
SecondeJK committed Nov 25, 2024
1 parent f4d0994 commit 5fcfbdd
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 2 deletions.
42 changes: 41 additions & 1 deletion src/Voice/NCCO/Action/Input.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Vonage\Voice\NCCO\Action;

use phpDocumentor\Reflection\Types\This;
use RuntimeException;
use Vonage\Voice\Webhook;

Expand All @@ -14,6 +15,13 @@

class Input implements ActionInterface
{
public const ASYNCHRONOUS_MODE = 'asynchronous';
public const SYNCHRONOUS_MODE = 'synchronous';

public array $allowedModes = [
self::SYNCHRONOUS_MODE,
self::ASYNCHRONOUS_MODE,
];
protected ?int $dtmfTimeout = null;

protected ?int $dtmfMaxDigits = null;
Expand All @@ -26,6 +34,8 @@ class Input implements ActionInterface

protected ?string $speechLanguage = null;

protected ?string $mode = null;

/**
* @var ?array<string>
*/
Expand Down Expand Up @@ -70,6 +80,10 @@ public static function factory(array $data): Input
}
}

if (array_key_exists('mode', $data)) {
$action->setMode($data['mode']);
}

if (array_key_exists('speech', $data)) {
$speech = $data['speech'];
$action->setEnableSpeech(true);
Expand Down Expand Up @@ -136,7 +150,8 @@ public function toNCCOArray(): array
'action' => 'input',
];

if ($this->getEnableDtmf() === false && $this->getEnableSpeech() === false) {
if ($this->getEnableDtmf() === false && $this->getEnableSpeech() === false && $this->getMode() !==
self::ASYNCHRONOUS_MODE) {
throw new RuntimeException('Input NCCO action must have either speech or DTMF enabled');
}

Expand Down Expand Up @@ -198,6 +213,10 @@ public function toNCCOArray(): array
$data['eventMethod'] = $eventWebhook->getMethod();
}

if ($this->getMode()) {
$data['mode'] = $this->getMode();
}

return $data;
}

Expand Down Expand Up @@ -365,4 +384,25 @@ public function setEnableDtmf(bool $enableDtmf): Input

return $this;
}

public function getMode(): ?string
{
return $this->mode;
}

public function setMode(?string $mode): self
{
if ($this->getEnableDtmf()) {
if ($mode == self::ASYNCHRONOUS_MODE) {
throw new \InvalidArgumentException('Cannot have DTMF input when using Asynchronous mode.');
}
}

if (!in_array($mode, $this->allowedModes)) {
throw new \InvalidArgumentException('Mode not a valid string');
}

$this->mode = $mode;
return $this;
}
}
72 changes: 71 additions & 1 deletion test/Voice/NCCO/Action/InputTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,76 @@ public function testThrowsRuntimeExceptionIfNoInputDefined(): void
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('Input NCCO action must have either speech or DTMF enabled');

(new Input())->toNCCOArray();
$input = new Input();
$array = $input->toNCCOArray();
}

public function testCanCreateInputSyncNCCOCorrectly(): void
{
$data = [
'action' => 'input',
'eventUrl' => ['https://test.domain/events'],
'dtmf' => [
'maxDigits' => 4,
],
'mode' => 'synchronous'
];

$action = Input::factory($data);
$ncco = $action->toNCCOArray();

$this->assertSame($data['dtmf']['maxDigits'], $action->getDtmfMaxDigits());
$this->assertSame($data['dtmf']['maxDigits'], $ncco['dtmf']->maxDigits);
$this->assertSame($data['mode'], $ncco['mode']);
$this->assertSame('POST', $action->getEventWebhook()->getMethod());
$this->assertSame($data['mode'], $action->getMode());
}

public function testCanCreateInputAsyncNCCOCorrectly(): void
{
$data = [
'action' => 'input',
'eventUrl' => ['https://test.domain/events'],
'mode' => 'asynchronous'
];

$action = Input::factory($data);
$ncco = $action->toNCCOArray();

$this->assertSame($data['mode'], $ncco['mode']);
$this->assertSame('POST', $action->getEventWebhook()->getMethod());
$this->assertSame($data['mode'], $action->getMode());
}

public function testCannotCreateInputNCCOWithDtmfAndAsyncMode(): void
{
$this->expectException(\InvalidArgumentException::class);

$data = [
'action' => 'input',
'eventUrl' => ['https://test.domain/events'],
'dtmf' => [
'maxDigits' => 4,
],
'mode' => 'asynchronous'
];

$action = Input::factory($data);
}

public function testErrorsOnInvalidInput(): void
{
$this->expectException(\InvalidArgumentException::class);

$data = [
'action' => 'input',
'eventUrl' => ['https://test.domain/events'],
'dtmf' => [
'maxDigits' => 4,
],
'mode' => 'syncronus'
];

$action = Input::factory($data);
}
}

0 comments on commit 5fcfbdd

Please sign in to comment.