Skip to content

[Mailer] [Sendinblue] refacto sendinblue to brevo #50279

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2578,7 +2578,7 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co
MailerBridge\OhMySmtp\Transport\OhMySmtpTransportFactory::class => 'mailer.transport_factory.ohmysmtp',
MailerBridge\Postmark\Transport\PostmarkTransportFactory::class => 'mailer.transport_factory.postmark',
MailerBridge\Sendgrid\Transport\SendgridTransportFactory::class => 'mailer.transport_factory.sendgrid',
MailerBridge\Sendinblue\Transport\SendinblueTransportFactory::class => 'mailer.transport_factory.sendinblue',
MailerBridge\Brevo\Transport\BrevoTransportFactory::class => 'mailer.transport_factory.brevo',
MailerBridge\Amazon\Transport\SesTransportFactory::class => 'mailer.transport_factory.amazon',
];

Expand Down Expand Up @@ -2741,7 +2741,7 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $
NotifierBridge\RocketChat\RocketChatTransportFactory::class => 'notifier.transport_factory.rocket-chat',
NotifierBridge\Sendberry\SendberryTransportFactory::class => 'notifier.transport_factory.sendberry',
NotifierBridge\SimpleTextin\SimpleTextinTransportFactory::class => 'notifier.transport_factory.simple-textin',
NotifierBridge\Sendinblue\SendinblueTransportFactory::class => 'notifier.transport_factory.sendinblue',
NotifierBridge\Brevo\BrevoTransportFactory::class => 'notifier.transport_factory.brevo',
NotifierBridge\Sinch\SinchTransportFactory::class => 'notifier.transport_factory.sinch',
NotifierBridge\Slack\SlackTransportFactory::class => 'notifier.transport_factory.slack',
NotifierBridge\Sms77\Sms77TransportFactory::class => 'notifier.transport_factory.sms77',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
use Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpTransportFactory;
use Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkTransportFactory;
use Symfony\Component\Mailer\Bridge\Sendgrid\Transport\SendgridTransportFactory;
use Symfony\Component\Mailer\Bridge\Sendinblue\Transport\SendinblueTransportFactory;
use Symfony\Component\Mailer\Bridge\Brevo\Transport\BrevoTransportFactory;
use Symfony\Component\Mailer\Transport\AbstractTransportFactory;
use Symfony\Component\Mailer\Transport\NativeTransportFactory;
use Symfony\Component\Mailer\Transport\NullTransportFactory;
Expand Down Expand Up @@ -88,7 +88,7 @@
->parent('mailer.transport_factory.abstract')
->tag('mailer.transport_factory')

->set('mailer.transport_factory.sendinblue', SendinblueTransportFactory::class)
->set('mailer.transport_factory.brevo', BrevoTransportFactory::class)
->parent('mailer.transport_factory.abstract')
->tag('mailer.transport_factory')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
->parent('notifier.transport_factory.abstract')
->tag('texter.transport_factory')

->set('notifier.transport_factory.sendinblue', Bridge\Sendinblue\SendinblueTransportFactory::class)
->set('notifier.transport_factory.brevo', Bridge\Brevo\BrevoTransportFactory::class)
->parent('notifier.transport_factory.abstract')
->tag('texter.transport_factory')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ CHANGELOG
-----

* Added the bridge

6.3.0
----
* renamed from Sendinblue to Brevo
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
Sendinblue Bridge
Brevo Bridge - formerly Sendinblue
=================

Provides Sendinblue integration for Symfony Mailer.
Provides Brevo integration for Symfony Mailer.

Configuration example:

```env
# SMTP
MAILER_DSN=sendinblue+smtp://USERNAME:PASSWORD@default
MAILER_DSN=brevo+smtp://USERNAME:PASSWORD@default

# API
MAILER_DSN=sendinblue+api://KEY@default
MAILER_DSN=brevo+api://KEY@default
```

where:
- `KEY` is your Sendinblue API Key
- `KEY` is your Brevo API Key

With API, you can use custom headers.

Expand Down Expand Up @@ -44,7 +44,7 @@ This example allow you to set :
* sender.ip
* X-Mailin-Custom

For more informations, you can refer to [Sendinblue API documentation](https://developers.sendinblue.com/reference#sendtransacemail).
For more informations, you can refer to [Brevo API documentation](https://developers.brevo.com/reference/getting-started-1#sendtransacemail).

Resources
---------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
* file that was distributed with this source code.
*/

namespace Symfony\Component\Mailer\Bridge\Sendinblue\Tests\Transport;
namespace Symfony\Component\Mailer\Bridge\Brevo\Tests\Transport;

use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\HttpClient\Response\MockResponse;
use Symfony\Component\Mailer\Bridge\Sendinblue\Transport\SendinblueApiTransport;
use Symfony\Component\Mailer\Bridge\Brevo\Transport\BrevoApiTransport;
use Symfony\Component\Mailer\Envelope;
use Symfony\Component\Mailer\Exception\HttpTransportException;
use Symfony\Component\Mailer\Header\MetadataHeader;
Expand All @@ -24,31 +24,31 @@
use Symfony\Component\Mime\Part\DataPart;
use Symfony\Contracts\HttpClient\ResponseInterface;

class SendinblueApiTransportTest extends TestCase
class BrevoApiTransportTest extends TestCase
{
/**
* @dataProvider getTransportData
*/
public function testToString(SendinblueApiTransport $transport, string $expected)
public function testToString(BrevoApiTransport $transport, string $expected)
{
$this->assertSame($expected, (string) $transport);
}

public static function getTransportData()
{
yield [
new SendinblueApiTransport('ACCESS_KEY'),
'sendinblue+api://api.sendinblue.com',
new BrevoApiTransport('ACCESS_KEY'),
'brevo+api://api.brevo.com',
];

yield [
(new SendinblueApiTransport('ACCESS_KEY'))->setHost('example.com'),
'sendinblue+api://example.com',
(new BrevoApiTransport('ACCESS_KEY'))->setHost('example.com'),
'brevo+api://example.com',
];

yield [
(new SendinblueApiTransport('ACCESS_KEY'))->setHost('example.com')->setPort(99),
'sendinblue+api://example.com:99',
(new BrevoApiTransport('ACCESS_KEY'))->setHost('example.com')->setPort(99),
'brevo+api://example.com:99',
];
}

Expand All @@ -67,8 +67,8 @@ public function testCustomHeader()
;
$envelope = new Envelope(new Address('alice@system.com', 'Alice'), [new Address('bob@system.com', 'Bob')]);

$transport = new SendinblueApiTransport('ACCESS_KEY');
$method = new \ReflectionMethod(SendinblueApiTransport::class, 'getPayload');
$transport = new BrevoApiTransport('ACCESS_KEY');
$method = new \ReflectionMethod(BrevoApiTransport::class, 'getPayload');
$payload = $method->invoke($transport, $email, $envelope);

$this->assertArrayHasKey('X-Mailin-Custom', $payload['headers']);
Expand All @@ -89,7 +89,7 @@ public function testSendThrowsForErrorResponse()
{
$client = new MockHttpClient(function (string $method, string $url, array $options): ResponseInterface {
$this->assertSame('POST', $method);
$this->assertSame('https://api.sendinblue.com:8984/v3/smtp/email', $url);
$this->assertSame('https://api.brevo.com:8984/v3/smtp/email', $url);
$this->assertStringContainsString('Accept: */*', $options['headers'][2] ?? $options['request_headers'][1]);

return new MockResponse(json_encode(['message' => 'i\'m a teapot']), [
Expand All @@ -100,7 +100,7 @@ public function testSendThrowsForErrorResponse()
]);
});

$transport = new SendinblueApiTransport('ACCESS_KEY', $client);
$transport = new BrevoApiTransport('ACCESS_KEY', $client);
$transport->setPort(8984);

$mail = new Email();
Expand All @@ -119,15 +119,15 @@ public function testSend()
{
$client = new MockHttpClient(function (string $method, string $url, array $options): ResponseInterface {
$this->assertSame('POST', $method);
$this->assertSame('https://api.sendinblue.com:8984/v3/smtp/email', $url);
$this->assertSame('https://api.brevo.com:8984/v3/smtp/email', $url);
$this->assertStringContainsString('Accept: */*', $options['headers'][2] ?? $options['request_headers'][1]);

return new MockResponse(json_encode(['messageId' => 'foobar']), [
'http_code' => 201,
]);
});

$transport = new SendinblueApiTransport('ACCESS_KEY', $client);
$transport = new BrevoApiTransport('ACCESS_KEY', $client);
$transport->setPort(8984);

$mail = new Email();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Mailer\Bridge\Brevo\Tests\Transport;

use Psr\Log\NullLogger;
use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\Mailer\Bridge\Brevo\Transport\BrevoApiTransport;
use Symfony\Component\Mailer\Bridge\Brevo\Transport\BrevoSmtpTransport;
use Symfony\Component\Mailer\Bridge\Brevo\Transport\BrevoTransportFactory;
use Symfony\Component\Mailer\Test\TransportFactoryTestCase;
use Symfony\Component\Mailer\Transport\Dsn;
use Symfony\Component\Mailer\Transport\TransportFactoryInterface;

class BrevoTransportFactoryTest extends TransportFactoryTestCase
{
public function getFactory(): TransportFactoryInterface
{
return new BrevoTransportFactory(null, new MockHttpClient(), new NullLogger());
}

public static function supportsProvider(): iterable
{
yield [
new Dsn('brevo', 'default'),
true,
];

yield [
new Dsn('brevo+smtp', 'default'),
true,
];

yield [
new Dsn('brevo+smtp', 'example.com'),
true,
];

yield [
new Dsn('brevo+api', 'default'),
true,
];
}

public static function createProvider(): iterable
{
yield [
new Dsn('brevo', 'default', self::USER, self::PASSWORD),
new BrevoSmtpTransport(self::USER, self::PASSWORD, null, new NullLogger()),
];

yield [
new Dsn('brevo+smtp', 'default', self::USER, self::PASSWORD),
new BrevoSmtpTransport(self::USER, self::PASSWORD, null, new NullLogger()),
];

yield [
new Dsn('brevo+smtp', 'default', self::USER, self::PASSWORD, 465),
new BrevoSmtpTransport(self::USER, self::PASSWORD, null, new NullLogger()),
];

yield [
new Dsn('brevo+api', 'default', self::USER),
new BrevoApiTransport(self::USER, new MockHttpClient(), null, new NullLogger()),
];
}

public static function unsupportedSchemeProvider(): iterable
{
yield [
new Dsn('brevo+foo', 'default', self::USER, self::PASSWORD),
'The "brevo+foo" scheme is not supported; supported schemes for mailer "brevo" are: "brevo", "brevo+smtp", "brevo+api".',
];
}

public static function incompleteDsnProvider(): iterable
{
yield [new Dsn('brevo+smtp', 'default', self::USER)];

yield [new Dsn('brevo+smtp', 'default', null, self::PASSWORD)];

yield [new Dsn('brevo+api', 'default')];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/

namespace Symfony\Component\Mailer\Bridge\Sendinblue\Transport;
namespace Symfony\Component\Mailer\Bridge\Brevo\Transport;

use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Log\LoggerInterface;
Expand All @@ -30,7 +30,7 @@
/**
* @author Yann LUCAS
*/
final class SendinblueApiTransport extends AbstractApiTransport
final class BrevoApiTransport extends AbstractApiTransport
{
private string $key;

Expand All @@ -43,7 +43,7 @@ public function __construct(string $key, HttpClientInterface $client = null, Eve

public function __toString(): string
{
return sprintf('sendinblue+api://%s', $this->getEndpoint());
return sprintf('brevo+api://%s', $this->getEndpoint());
}

protected function doSendApi(SentMessage $sentMessage, Email $email, Envelope $envelope): ResponseInterface
Expand All @@ -61,7 +61,7 @@ protected function doSendApi(SentMessage $sentMessage, Email $email, Envelope $e
} catch (DecodingExceptionInterface) {
throw new HttpTransportException('Unable to send an email: '.$response->getContent(false).sprintf(' (code %d).', $statusCode), $response);
} catch (TransportExceptionInterface $e) {
throw new HttpTransportException('Could not reach the remote Sendinblue server.', $response, 0, $e);
throw new HttpTransportException('Could not reach the remote Brevo server.', $response, 0, $e);
}

if (201 !== $statusCode) {
Expand Down Expand Up @@ -180,6 +180,6 @@ private function stringifyAddress(Address $address): array

private function getEndpoint(): ?string
{
return ($this->host ?: 'api.sendinblue.com').($this->port ? ':'.$this->port : '');
return ($this->host ?: 'api.brevo.com').($this->port ? ':'.$this->port : '');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/

namespace Symfony\Component\Mailer\Bridge\Sendinblue\Transport;
namespace Symfony\Component\Mailer\Bridge\Brevo\Transport;

use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Log\LoggerInterface;
Expand All @@ -18,11 +18,11 @@
/**
* @author Yann LUCAS
*/
final class SendinblueSmtpTransport extends EsmtpTransport
final class BrevoSmtpTransport extends EsmtpTransport
{
public function __construct(string $username, #[\SensitiveParameter] string $password, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null)
{
parent::__construct('smtp-relay.sendinblue.com', 465, true, $dispatcher, $logger);
parent::__construct('smtp-relay.brevo.com', 465, true, $dispatcher, $logger);

$this->setUsername($username);
$this->setPassword($password);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/

namespace Symfony\Component\Mailer\Bridge\Sendinblue\Transport;
namespace Symfony\Component\Mailer\Bridge\Brevo\Transport;

use Symfony\Component\Mailer\Exception\UnsupportedSchemeException;
use Symfony\Component\Mailer\Transport\AbstractTransportFactory;
Expand All @@ -19,22 +19,22 @@
/**
* @author Yann LUCAS
*/
final class SendinblueTransportFactory extends AbstractTransportFactory
final class BrevoTransportFactory extends AbstractTransportFactory
{
public function create(Dsn $dsn): TransportInterface
{
if (!\in_array($dsn->getScheme(), $this->getSupportedSchemes(), true)) {
throw new UnsupportedSchemeException($dsn, 'sendinblue', $this->getSupportedSchemes());
throw new UnsupportedSchemeException($dsn, 'brevo', $this->getSupportedSchemes());
}

switch ($dsn->getScheme()) {
default:
case 'sendinblue':
case 'sendinblue+smtp':
$transport = SendinblueSmtpTransport::class;
case 'brevo':
case 'brevo+smtp':
$transport = BrevoSmtpTransport::class;
break;
case 'sendinblue+api':
return (new SendinblueApiTransport($this->getUser($dsn), $this->client, $this->dispatcher, $this->logger))
case 'brevo+api':
return (new BrevoApiTransport($this->getUser($dsn), $this->client, $this->dispatcher, $this->logger))
->setHost('default' === $dsn->getHost() ? null : $dsn->getHost())
->setPort($dsn->getPort())
;
Expand All @@ -45,6 +45,6 @@ public function create(Dsn $dsn): TransportInterface

protected function getSupportedSchemes(): array
{
return ['sendinblue', 'sendinblue+smtp', 'sendinblue+api'];
return ['brevo', 'brevo+smtp', 'brevo+api'];
}
}
Loading