From 261cfeeb36ec8c97c68ce207f0ca2c872f83ff54 Mon Sep 17 00:00:00 2001 From: "mihail.krasilnikov" Date: Fri, 30 Oct 2020 22:40:10 +0200 Subject: [PATCH] Added telnyx notifier bridge --- .../FrameworkExtension.php | 2 + .../Resources/config/notifier_transports.php | 5 + .../Notifier/Bridge/Telnyx/.gitattributes | 4 + .../Notifier/Bridge/Telnyx/CHANGELOG.md | 7 + .../Component/Notifier/Bridge/Telnyx/LICENSE | 19 ++ .../Notifier/Bridge/Telnyx/README.md | 22 +++ .../Notifier/Bridge/Telnyx/TelnyxOptions.php | 109 +++++++++++ .../Bridge/Telnyx/TelnyxTransport.php | 104 +++++++++++ .../Bridge/Telnyx/TelnyxTransportFactory.php | 47 +++++ .../Tests/TelnyxTransportFactoryTest.php | 61 ++++++ .../Telnyx/Tests/TelnyxTransportTest.php | 176 ++++++++++++++++++ .../Notifier/Bridge/Telnyx/composer.json | 30 +++ .../Notifier/Bridge/Telnyx/phpunit.xml.dist | 31 +++ .../Exception/UnsupportedSchemeException.php | 4 + src/Symfony/Component/Notifier/Transport.php | 2 + 15 files changed, 623 insertions(+) create mode 100644 src/Symfony/Component/Notifier/Bridge/Telnyx/.gitattributes create mode 100644 src/Symfony/Component/Notifier/Bridge/Telnyx/CHANGELOG.md create mode 100644 src/Symfony/Component/Notifier/Bridge/Telnyx/LICENSE create mode 100644 src/Symfony/Component/Notifier/Bridge/Telnyx/README.md create mode 100644 src/Symfony/Component/Notifier/Bridge/Telnyx/TelnyxOptions.php create mode 100644 src/Symfony/Component/Notifier/Bridge/Telnyx/TelnyxTransport.php create mode 100644 src/Symfony/Component/Notifier/Bridge/Telnyx/TelnyxTransportFactory.php create mode 100644 src/Symfony/Component/Notifier/Bridge/Telnyx/Tests/TelnyxTransportFactoryTest.php create mode 100644 src/Symfony/Component/Notifier/Bridge/Telnyx/Tests/TelnyxTransportTest.php create mode 100644 src/Symfony/Component/Notifier/Bridge/Telnyx/composer.json create mode 100644 src/Symfony/Component/Notifier/Bridge/Telnyx/phpunit.xml.dist diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index f287c8b5f08bd..93128a4394ea9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -127,6 +127,7 @@ use Symfony\Component\Notifier\Bridge\Slack\SlackTransportFactory; use Symfony\Component\Notifier\Bridge\Smsapi\SmsapiTransportFactory; use Symfony\Component\Notifier\Bridge\Telegram\TelegramTransportFactory; +use Symfony\Component\Notifier\Bridge\Telnyx\TelnyxTransportFactory; use Symfony\Component\Notifier\Bridge\Twilio\TwilioTransportFactory; use Symfony\Component\Notifier\Bridge\Zulip\ZulipTransportFactory; use Symfony\Component\Notifier\Notifier; @@ -2249,6 +2250,7 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ OctopushTransportFactory::class => 'notifier.transport_factory.octopush', MercureTransportFactory::class => 'notifier.transport_factory.mercure', GitterTransportFactory::class => 'notifier.transport_factory.gitter', + TelnyxTransportFactory::class => 'notifier.transport_factory.telnyx', ]; foreach ($classToServices as $class => $service) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.php index 3d4fdcf101ea4..bdecdeb7d3fa8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.php @@ -34,6 +34,7 @@ use Symfony\Component\Notifier\Bridge\Slack\SlackTransportFactory; use Symfony\Component\Notifier\Bridge\Smsapi\SmsapiTransportFactory; use Symfony\Component\Notifier\Bridge\Telegram\TelegramTransportFactory; +use Symfony\Component\Notifier\Bridge\Telnyx\TelnyxTransportFactory; use Symfony\Component\Notifier\Bridge\Twilio\TwilioTransportFactory; use Symfony\Component\Notifier\Bridge\Zulip\ZulipTransportFactory; use Symfony\Component\Notifier\Transport\AbstractTransportFactory; @@ -145,6 +146,10 @@ ->parent('notifier.transport_factory.abstract') ->tag('chatter.transport_factory') + ->set('notifier.transport_factory.telnyx', TelnyxTransportFactory::class) + ->parent('notifier.transport_factory.abstract') + ->tag('texter.transport_factory') + ->set('notifier.transport_factory.null', NullTransportFactory::class) ->parent('notifier.transport_factory.abstract') ->tag('chatter.transport_factory') diff --git a/src/Symfony/Component/Notifier/Bridge/Telnyx/.gitattributes b/src/Symfony/Component/Notifier/Bridge/Telnyx/.gitattributes new file mode 100644 index 0000000000000..84c7add058fb5 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Telnyx/.gitattributes @@ -0,0 +1,4 @@ +/Tests export-ignore +/phpunit.xml.dist export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore diff --git a/src/Symfony/Component/Notifier/Bridge/Telnyx/CHANGELOG.md b/src/Symfony/Component/Notifier/Bridge/Telnyx/CHANGELOG.md new file mode 100644 index 0000000000000..1f2b652ac20ea --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Telnyx/CHANGELOG.md @@ -0,0 +1,7 @@ +CHANGELOG +========= + +5.3 +--- + + * Add the bridge diff --git a/src/Symfony/Component/Notifier/Bridge/Telnyx/LICENSE b/src/Symfony/Component/Notifier/Bridge/Telnyx/LICENSE new file mode 100644 index 0000000000000..efb17f98e7dd3 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Telnyx/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2021 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/Symfony/Component/Notifier/Bridge/Telnyx/README.md b/src/Symfony/Component/Notifier/Bridge/Telnyx/README.md new file mode 100644 index 0000000000000..bd5ac7f0c210b --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Telnyx/README.md @@ -0,0 +1,22 @@ +Telnyx Notifier +=============== + +Provides [Telnyx](https://telnyx.com) integration for Symfony Notifier. + +DSN example +----------- + +``` +TELNYX_DSN=telnyx://API_KEY@default?from=FROM +``` + +where: + - `API_KEY` is your telnyx api key + - `FROM` is your telnyx phone number + +--------- + + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/src/Symfony/Component/Notifier/Bridge/Telnyx/TelnyxOptions.php b/src/Symfony/Component/Notifier/Bridge/Telnyx/TelnyxOptions.php new file mode 100644 index 0000000000000..fad4ddfeafbf7 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Telnyx/TelnyxOptions.php @@ -0,0 +1,109 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Notifier\Bridge\Telnyx; + +use Symfony\Component\Notifier\Message\MessageOptionsInterface; + +/** + * @author Mihail Krasilnikov + * + * @see https://developers.telnyx.com/docs/api/v2/messaging/Messages#createMessage + */ +final class TelnyxOptions implements MessageOptionsInterface +{ + private $options; + + public function __construct(array $options = []) + { + $this->options = $options; + } + + public function toArray(): array + { + return $this->options; + } + + public function getRecipientId(): ?string + { + return $this->options['to'] ?? null; + } + + public function to(string $number): self + { + $this->options['to'] = $number; + + return $this; + } + + public function from(string $from): self + { + $this->options['from'] = $from; + + return $this; + } + + public function mediaUrls(array $mediaUrls): self + { + $this->options['media_urls'] = $mediaUrls; + + return $this; + } + + public function messagingProfileId(string $messagingProfileId): self + { + $this->options['messaging_profile_id'] = $messagingProfileId; + + return $this; + } + + public function subject(string $subject): self + { + $this->options['subject'] = $subject; + + return $this; + } + + public function text(string $text): self + { + $this->options['text'] = $text; + + return $this; + } + + public function type(string $type): self + { + $this->options['type'] = $type; + + return $this; + } + + public function useProfileWebhooks(bool $useProfileWebhooks): self + { + $this->options['use_profile_webhooks'] = $useProfileWebhooks; + + return $this; + } + + public function webhookFailoverUrl(string $webhookFailoverUrl): self + { + $this->options['webhook_failover_url'] = $webhookFailoverUrl; + + return $this; + } + + public function webhookUrll(string $webhookUrl): self + { + $this->options['webhook_url'] = $webhookUrl; + + return $this; + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/Telnyx/TelnyxTransport.php b/src/Symfony/Component/Notifier/Bridge/Telnyx/TelnyxTransport.php new file mode 100644 index 0000000000000..91dfb4f5363e9 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Telnyx/TelnyxTransport.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Notifier\Bridge\Telnyx; + +use Symfony\Component\Notifier\Exception\LogicException; +use Symfony\Component\Notifier\Exception\TransportException; +use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException; +use Symfony\Component\Notifier\Message\MessageInterface; +use Symfony\Component\Notifier\Message\SentMessage; +use Symfony\Component\Notifier\Message\SmsMessage; +use Symfony\Component\Notifier\Transport\AbstractTransport; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * @author Mihail Krasilnikov + */ +final class TelnyxTransport extends AbstractTransport +{ + protected const HOST = 'api.telnyx.com'; + + private $apiKey; + private $from; + + public function __construct(string $apiKey, string $from, HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null) + { + $this->apiKey = $apiKey; + $this->from = $from; + + parent::__construct($client, $dispatcher); + } + + public function __toString(): string + { + return sprintf('telnyx://%s?from=%s', $this->getEndpoint(), $this->from); + } + + public function supports(MessageInterface $message): bool + { + return $message instanceof SmsMessage; + } + + /** + * @see https://developers.telnyx.com/docs/api/v2/messaging/Messages + */ + protected function doSend(MessageInterface $message): SentMessage + { + if (!$message instanceof SmsMessage) { + throw new UnsupportedMessageTypeException(__CLASS__, SmsMessage::class, $message); + } + + if ($message->getOptions() && !$message->getOptions() instanceof TelnyxOptions) { + throw new LogicException(sprintf('The "%s" transport only supports instances of "%s" for options.', __CLASS__, TelnyxOptions::class)); + } + + $endpoint = sprintf('https://%s/v2/messages', $this->getEndpoint()); + + $response = $this->client->request('POST', $endpoint, [ + 'auth_bearer' => $this->apiKey, + 'json' => $this->preparePayload($message), + ]); + + if (200 !== $response->getStatusCode()) { + $error = $response->toArray(false); + + throw new TransportException(sprintf('Unable to send the SMS: "%s".', $error['errors'][0]['title']), $response); + } + + $success = $response->toArray(false); + + $sentMessage = new SentMessage($message, (string) $this); + $sentMessage->setMessageId($success['data']['id']); + + return $sentMessage; + } + + private function preparePayload(SmsMessage $message): array + { + $options = $message->getOptions() ? $message->getOptions()->toArray() : []; + + if (!isset($options['from'])) { + $options['from'] = $this->from; + } + + if (!isset($options['to'])) { + $options['to'] = $message->getPhone(); + } + + if (!isset($options['text'])) { + $options['text'] = $message->getSubject(); + } + + return $options; + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/Telnyx/TelnyxTransportFactory.php b/src/Symfony/Component/Notifier/Bridge/Telnyx/TelnyxTransportFactory.php new file mode 100644 index 0000000000000..73deb767024ad --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Telnyx/TelnyxTransportFactory.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Notifier\Bridge\Telnyx; + +use Symfony\Component\Notifier\Exception\UnsupportedSchemeException; +use Symfony\Component\Notifier\Transport\AbstractTransportFactory; +use Symfony\Component\Notifier\Transport\Dsn; +use Symfony\Component\Notifier\Transport\TransportInterface; + +/** + * @author Mihail Krasilnikov + */ +final class TelnyxTransportFactory extends AbstractTransportFactory +{ + /** + * @return TelnyxTransport + */ + public function create(Dsn $dsn): TransportInterface + { + $scheme = $dsn->getScheme(); + + if ('telnyx' !== $scheme) { + throw new UnsupportedSchemeException($dsn, 'telnyx', $this->getSupportedSchemes()); + } + + $apiKey = $this->getUser($dsn); + $from = $dsn->getRequiredOption('from'); + $host = 'default' === $dsn->getHost() ? null : $dsn->getHost(); + $port = $dsn->getPort(); + + return (new TelnyxTransport($apiKey, $from, $this->client, $this->dispatcher))->setHost($host)->setPort($port); + } + + protected function getSupportedSchemes(): array + { + return ['telnyx']; + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/Telnyx/Tests/TelnyxTransportFactoryTest.php b/src/Symfony/Component/Notifier/Bridge/Telnyx/Tests/TelnyxTransportFactoryTest.php new file mode 100644 index 0000000000000..3b730e10f11bc --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Telnyx/Tests/TelnyxTransportFactoryTest.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Notifier\Bridge\Telnyx\Tests; + +use Symfony\Component\Notifier\Bridge\Smsapi\SmsapiTransportFactory; +use Symfony\Component\Notifier\Bridge\Telnyx\TelnyxTransportFactory; +use Symfony\Component\Notifier\Tests\TransportFactoryTestCase; +use Symfony\Component\Notifier\Transport\TransportFactoryInterface; + +/** + * @author Mihail Krasilnikov + */ +final class TelnyxTransportFactoryTest extends TransportFactoryTestCase +{ + /** + * @return SmsapiTransportFactory + */ + public function createFactory(): TransportFactoryInterface + { + return new TelnyxTransportFactory(); + } + + public function createProvider(): iterable + { + yield [ + 'telnyx://default.host?from=37162626262', + 'telnyx://apikey@default.host?from=37162626262', + ]; + } + + public function supportsProvider(): iterable + { + yield [true, 'telnyx://apikey@default.host?from=37162626262']; + yield [false, 'another://apikey@default.host?from=37162626262']; + } + + public function incompleteDsnProvider(): iterable + { + yield 'missing api key' => ['telnyx://default.host?from=37162626262']; + } + + public function missingRequiredOptionProvider(): iterable + { + yield 'missing option: from' => ['telnyx://apikey@default.host']; + } + + public function unsupportedSchemeProvider(): iterable + { + yield ['another://apikey@default.host?from=37162626262']; + yield ['another://apikey@default.host']; // missing "from" option + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/Telnyx/Tests/TelnyxTransportTest.php b/src/Symfony/Component/Notifier/Bridge/Telnyx/Tests/TelnyxTransportTest.php new file mode 100644 index 0000000000000..1992c59550018 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Telnyx/Tests/TelnyxTransportTest.php @@ -0,0 +1,176 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Notifier\Bridge\Telnyx\Tests; + +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; +use Symfony\Component\Notifier\Bridge\Telnyx\TelnyxTransport; +use Symfony\Component\Notifier\Exception\LogicException; +use Symfony\Component\Notifier\Exception\TransportException; +use Symfony\Component\Notifier\Message\ChatMessage; +use Symfony\Component\Notifier\Message\SmsMessage; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Mihail Krasilnikov + */ +final class TelnyxTransportTest extends TestCase +{ + /** + * @var HttpClientInterface|MockObject + */ + private $client; + + public function testShouldSupportSmsMessageInstance() + { + $transport = $this->createTelnyxTransport(); + $smsMessage = new SmsMessage('37100101010101', 'Hello'); + $chatMessage = new ChatMessage('Hello'); + + $this->assertTrue($transport->supports($smsMessage)); + $this->assertFalse($transport->supports($chatMessage)); + } + + public function testShouldThrowExceptionWhenPassedNotSmsMessageInstance() + { + $transport = $this->createTelnyxTransport(); + $chatMessage = new ChatMessage('Hello'); + $this->expectException(LogicException::class); + + $transport->send($chatMessage); + } + + public function testShouldSuccessfullySendSmsMessage() + { + $transport = $this->createTelnyxTransport(); + $message = new SmsMessage('37100101010101', 'Hello'); + + $response = $this->createMock(ResponseInterface::class); + $response->expects($this->once()) + ->method('getStatusCode') + ->willReturn(200); + + $content = <<expects($this->once()) + ->method('toArray') + ->willReturn(json_decode($content, true)); + + $this->client + ->expects($this->once()) + ->method('request') + ->with('POST', 'https://test.host/v2/messages', [ + 'auth_bearer' => 'apikey', + 'json' => [ + 'to' => '37100101010101', + 'from' => '37100000000', + 'text' => 'Hello', + ], + ]) + ->willReturn($response); + + $sentMessage = $transport->send($message); + + $this->assertEquals('403w75a7-5c8a-4bbc-981f-symfony0f81d', $sentMessage->getMessageId()); + $this->assertEquals('telnyx://test.host?from=37100000000', $sentMessage->getTransport()); + } + + public function testShouldThrowTransportException() + { + $this->expectException(TransportException::class); + $this->expectExceptionMessage('Unable to send the SMS: "Invalid phone number"'); + + $transport = $this->createTelnyxTransport(); + $message = new SmsMessage('fake number', 'Hello'); + + $response = $this->createMock(ResponseInterface::class); + $response->expects($this->once()) + ->method('getStatusCode') + ->willReturn(404); + + $content = <<expects($this->once()) + ->method('toArray') + ->willReturn(json_decode($content, true)); + + $this->client + ->expects($this->once()) + ->method('request') + ->with('POST', 'https://test.host/v2/messages', [ + 'auth_bearer' => 'apikey', + 'json' => [ + 'to' => 'fake number', + 'from' => '37100000000', + 'text' => 'Hello', + ], + ]) + ->willReturn($response); + + $transport->send($message); + } + + private function createTelnyxTransport(): TelnyxTransport + { + $this->client = $this->createMock(HttpClientInterface::class); + + return (new TelnyxTransport('apikey', '37100000000', $this->client)) + ->setHost('test.host'); + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/Telnyx/composer.json b/src/Symfony/Component/Notifier/Bridge/Telnyx/composer.json new file mode 100644 index 0000000000000..10a33eb23b6c8 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Telnyx/composer.json @@ -0,0 +1,30 @@ +{ + "name": "symfony/telnyx-notifier", + "type": "symfony-bridge", + "description": "Symfony Telnyx Notifier Bridge", + "keywords": ["sms", "telnyx", "notifier"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Mihail Krasilnikov", + "email": "mihail.krasilnikov.j@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.2.5", + "symfony/http-client": "^4.4|^5.0", + "symfony/notifier": "^5.3" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\Notifier\\Bridge\\Telnyx\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev" +} diff --git a/src/Symfony/Component/Notifier/Bridge/Telnyx/phpunit.xml.dist b/src/Symfony/Component/Notifier/Bridge/Telnyx/phpunit.xml.dist new file mode 100644 index 0000000000000..f959ed7a2e194 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Telnyx/phpunit.xml.dist @@ -0,0 +1,31 @@ + + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + + diff --git a/src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php b/src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php index 574d419a9fb32..f57550879b1f4 100644 --- a/src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php +++ b/src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php @@ -108,6 +108,10 @@ class UnsupportedSchemeException extends LogicException 'class' => Bridge\Gitter\GitterTransportFactory::class, 'package' => 'symfony/gitter-notifier', ], + 'telnyx' => [ + 'class' => Bridge\Telnyx\TelnyxTransportFactory::class, + 'package' => 'symfony/telnyx-notifier', + ], ]; /** diff --git a/src/Symfony/Component/Notifier/Transport.php b/src/Symfony/Component/Notifier/Transport.php index fd3af9b05cc38..6aaa1592c0a37 100644 --- a/src/Symfony/Component/Notifier/Transport.php +++ b/src/Symfony/Component/Notifier/Transport.php @@ -31,6 +31,7 @@ use Symfony\Component\Notifier\Bridge\Slack\SlackTransportFactory; use Symfony\Component\Notifier\Bridge\Smsapi\SmsapiTransportFactory; use Symfony\Component\Notifier\Bridge\Telegram\TelegramTransportFactory; +use Symfony\Component\Notifier\Bridge\Telnyx\TelnyxTransportFactory; use Symfony\Component\Notifier\Bridge\Twilio\TwilioTransportFactory; use Symfony\Component\Notifier\Bridge\Zulip\ZulipTransportFactory; use Symfony\Component\Notifier\Exception\UnsupportedSchemeException; @@ -72,6 +73,7 @@ class Transport GatewayApiTransportFactory::class, OctopushTransportFactory::class, GitterTransportFactory::class, + TelnyxTransportFactory::class, ]; private $factories;