diff --git a/README.md b/README.md index 7be4064..8e885a7 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ class AccountApproved extends Notification } ``` -Or create a Twilio call: +Or create a Twilio call, using either an external TwiML url: ``` php use NotificationChannels\Twilio\TwilioChannel; @@ -153,6 +153,32 @@ class AccountApproved extends Notification } ``` +Or create a Twilio call, and send a TwiML response directly: + +``` php +use NotificationChannels\Twilio\TwilioChannel; +use NotificationChannels\Twilio\TwilioCallMessage; +use Illuminate\Notifications\Notification; +use Twilio\TwiML\VoiceResponse; + +class AccountApproved extends Notification +{ + public function via($notifiable) + { + return [TwilioChannel::class]; + } + + public function toTwilio($notifiable) + { + return (new TwilioCallMessage()) + ->twiml( + (new VoiceResponse()) + ->say('Hello world') + ); + } +} +``` + In order to let your Notification know which phone are you sending/calling to, the channel will look for the `phone_number` attribute of the Notifiable model. If you want to override this behaviour, add the `routeNotificationForTwilio` method to your Notifiable model. ```php @@ -174,6 +200,9 @@ public function routeNotificationForTwilio() - `from('')`: Accepts a phone to use as the notification sender. - `url('')`: Accepts an url for the call TwiML. +- `twiml(VoiceResponse)`: Accepts a \Twilio\TwiML\VoiceResponse containing the call TwiML. + +> You can use *either* url() *or* twiml() on a TwilioCallMessage object, not both. ## Changelog diff --git a/src/Exceptions/InvalidConfigException.php b/src/Exceptions/InvalidConfigException.php index b0fa6f9..4038801 100644 --- a/src/Exceptions/InvalidConfigException.php +++ b/src/Exceptions/InvalidConfigException.php @@ -10,4 +10,9 @@ public static function missingConfig(): self { return new self('Missing config. You must set either the username & password or SID and auth token'); } + + public static function multipleContentTypes(): self + { + return new self('Unable to use URL and TWIML call types simultaneously. You can use only one type'); + } } diff --git a/src/Twilio.php b/src/Twilio.php index 7c47881..dc17762 100644 --- a/src/Twilio.php +++ b/src/Twilio.php @@ -116,7 +116,7 @@ protected function sendSmsMessage(TwilioSmsMessage $message, ?string $to): Messa protected function makeCall(TwilioCallMessage $message, ?string $to): CallInstance { $params = [ - 'url' => trim($message->content), + $message->contentType => trim($message->content), ]; $this->fillOptionalParams($params, $message, [ diff --git a/src/TwilioCallMessage.php b/src/TwilioCallMessage.php index da4b160..0d21000 100755 --- a/src/TwilioCallMessage.php +++ b/src/TwilioCallMessage.php @@ -2,11 +2,22 @@ namespace NotificationChannels\Twilio; +use NotificationChannels\Twilio\Exceptions\InvalidConfigException; +use Twilio\TwiML\VoiceResponse; + class TwilioCallMessage extends TwilioMessage { public const STATUS_CANCELED = 'canceled'; public const STATUS_COMPLETED = 'completed'; + public const TYPE_URL = 'url'; + public const TYPE_TWIML = 'twiml'; + + /** + * @var int + */ + public $contentType = null; + /** * @var null|string */ @@ -35,11 +46,38 @@ class TwilioCallMessage extends TwilioMessage */ public function url(string $url): self { + $this->contentType(self::TYPE_URL); $this->content = $url; return $this; } + /** + * Set the message twiml. + * + * @param string $twiml + * @return $this + */ + public function twiml(VoiceResponse $response): self + { + $this->contentType(self::TYPE_TWIML); + $this->content = (string) $response; + + return $this; + } + + protected function contentType(string $contentType) + { + if ( + ! is_null($this->contentType) + && $contentType !== $this->contentType + ) { + InvalidConfigException::multipleContentTypes(); + } + + $this->contentType = $contentType; + } + /** * Set the message url request method. *