├── CHANGELOG.md ├── LICENSE ├── README.md ├── SendinblueTransport.php ├── SendinblueTransportFactory.php └── composer.json /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | CHANGELOG 2 | ========= 3 | 4 | 6.4 5 | --- 6 | 7 | * Deprecate the bridge (use Brevo instead) 8 | 9 | 6.2 10 | --- 11 | 12 | * Use `SmsMessage->from` when defined 13 | 14 | 5.3 15 | --- 16 | 17 | * The bridge is not marked as `@experimental` anymore 18 | 19 | 5.2.0 20 | ----- 21 | 22 | * Added the bridge 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019-present Fabien Potencier 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Sendinblue Notifier 2 | =================== 3 | 4 | Provides [Sendinblue](https://sendinblue.com) integration for Symfony Notifier. 5 | 6 | DSN example 7 | ----------- 8 | 9 | ``` 10 | SENDINBLUE_DSN=sendinblue://API_KEY@default?sender=SENDER 11 | ``` 12 | 13 | where: 14 | - `API_KEY` is your api key from your Sendinblue account 15 | - `SENDER` is your sender's phone number 16 | 17 | See more info at https://developers.sendinblue.com/reference#sendtransacsms 18 | 19 | Resources 20 | --------- 21 | 22 | * [Contributing](https://symfony.com/doc/current/contributing/index.html) 23 | * [Report issues](https://github.com/symfony/symfony/issues) and 24 | [send Pull Requests](https://github.com/symfony/symfony/pulls) 25 | in the [main Symfony repository](https://github.com/symfony/symfony) 26 | -------------------------------------------------------------------------------- /SendinblueTransport.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Notifier\Bridge\Sendinblue; 13 | 14 | use Symfony\Component\Notifier\Exception\TransportException; 15 | use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException; 16 | use Symfony\Component\Notifier\Message\MessageInterface; 17 | use Symfony\Component\Notifier\Message\SentMessage; 18 | use Symfony\Component\Notifier\Message\SmsMessage; 19 | use Symfony\Component\Notifier\Transport\AbstractTransport; 20 | use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; 21 | use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; 22 | use Symfony\Contracts\HttpClient\HttpClientInterface; 23 | 24 | /** 25 | * @author Pierre Tondereau 26 | * 27 | * @deprecated since Symfony 6.3, use BrevoTransport instead 28 | */ 29 | final class SendinblueTransport extends AbstractTransport 30 | { 31 | protected const HOST = 'api.brevo.com'; 32 | 33 | private string $apiKey; 34 | private string $sender; 35 | 36 | public function __construct(#[\SensitiveParameter] string $apiKey, string $sender, ?HttpClientInterface $client = null, ?EventDispatcherInterface $dispatcher = null) 37 | { 38 | $this->apiKey = $apiKey; 39 | $this->sender = $sender; 40 | 41 | parent::__construct($client, $dispatcher); 42 | } 43 | 44 | public function __toString(): string 45 | { 46 | return sprintf('sendinblue://%s?sender=%s', $this->getEndpoint(), $this->sender); 47 | } 48 | 49 | public function supports(MessageInterface $message): bool 50 | { 51 | return $message instanceof SmsMessage; 52 | } 53 | 54 | protected function doSend(MessageInterface $message): SentMessage 55 | { 56 | if (!$message instanceof SmsMessage) { 57 | throw new UnsupportedMessageTypeException(__CLASS__, SmsMessage::class, $message); 58 | } 59 | 60 | $response = $this->client->request('POST', 'https://'.$this->getEndpoint().'/v3/transactionalSMS/sms', [ 61 | 'json' => [ 62 | 'sender' => $message->getFrom() ?: $this->sender, 63 | 'recipient' => $message->getPhone(), 64 | 'content' => $message->getSubject(), 65 | ], 66 | 'headers' => [ 67 | 'api-key' => $this->apiKey, 68 | ], 69 | ]); 70 | 71 | try { 72 | $statusCode = $response->getStatusCode(); 73 | } catch (TransportExceptionInterface $e) { 74 | throw new TransportException('Could not reach the remote Sendinblue server.', $response, 0, $e); 75 | } 76 | 77 | if (201 !== $statusCode) { 78 | $error = $response->toArray(false); 79 | 80 | throw new TransportException('Unable to send the SMS: '.($error['message'] ?? $response->getContent(false)), $response); 81 | } 82 | 83 | $success = $response->toArray(false); 84 | 85 | $sentMessage = new SentMessage($message, (string) $this); 86 | $sentMessage->setMessageId($success['messageId']); 87 | 88 | return $sentMessage; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /SendinblueTransportFactory.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Notifier\Bridge\Sendinblue; 13 | 14 | use Symfony\Component\Notifier\Bridge\Brevo\BrevoTransport; 15 | use Symfony\Component\Notifier\Exception\UnsupportedSchemeException; 16 | use Symfony\Component\Notifier\Transport\AbstractTransportFactory; 17 | use Symfony\Component\Notifier\Transport\Dsn; 18 | 19 | /** 20 | * @author Pierre Tondereau 21 | * 22 | * @deprecated since Symfony 6.3, use BrevoTransportFactory instead 23 | */ 24 | final class SendinblueTransportFactory extends AbstractTransportFactory 25 | { 26 | public function create(Dsn $dsn): SendinblueTransport 27 | { 28 | trigger_deprecation('symfony/sendinblue-notifier', '6.3', 'The "%s" class is deprecated, use "%s" instead.', SendinblueTransport::class, BrevoTransport::class); 29 | 30 | $scheme = $dsn->getScheme(); 31 | 32 | if ('sendinblue' !== $scheme) { 33 | throw new UnsupportedSchemeException($dsn, 'sendinblue', $this->getSupportedSchemes()); 34 | } 35 | 36 | $apiKey = $this->getUser($dsn); 37 | $sender = $dsn->getRequiredOption('sender'); 38 | $host = 'default' === $dsn->getHost() ? null : $dsn->getHost(); 39 | $port = $dsn->getPort(); 40 | 41 | return (new SendinblueTransport($apiKey, $sender, $this->client, $this->dispatcher))->setHost($host)->setPort($port); 42 | } 43 | 44 | protected function getSupportedSchemes(): array 45 | { 46 | return ['sendinblue']; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symfony/sendinblue-notifier", 3 | "type": "symfony-notifier-bridge", 4 | "description": "Symfony Sendinblue Notifier Bridge", 5 | "keywords": ["sms", "sendinblue", "notifier"], 6 | "homepage": "https://symfony.com", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Pierre Tondereau", 11 | "email": "pierre.tondereau@protonmail.com" 12 | }, 13 | { 14 | "name": "Symfony Community", 15 | "homepage": "https://symfony.com/contributors" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=8.1", 20 | "symfony/deprecation-contracts": "^2.5|^3", 21 | "symfony/http-client": "^5.4|^6.0|^7.0", 22 | "symfony/notifier": "^6.2.7|^7.0" 23 | }, 24 | "autoload": { 25 | "psr-4": { "Symfony\\Component\\Notifier\\Bridge\\Sendinblue\\": "" }, 26 | "exclude-from-classmap": [ 27 | "/Tests/" 28 | ] 29 | }, 30 | "minimum-stability": "dev" 31 | } 32 | --------------------------------------------------------------------------------