├── .github
├── CODEOWNERS
└── workflows
│ └── php.yml
├── renovate.json
├── .gitignore
├── config
└── mailersend-driver.php
├── .editorconfig
├── phpunit.xml.dist
├── tests
├── TestCase.php
└── MailerSendTransportTest.php
├── LICENSE.md
├── src
├── LaravelDriverServiceProvider.php
├── MailerSendTrait.php
└── MailerSendTransport.php
├── composer.json
└── README.md
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @mailersend/php-sdk-maintainers
2 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["github>mailerlite/renovate-config:base"]
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | composer.phar
2 | composer.lock
3 | vendor
4 | .idea
5 | .phpunit.result.cache
6 |
--------------------------------------------------------------------------------
/config/mailersend-driver.php:
--------------------------------------------------------------------------------
1 | env('MAILERSEND_API_KEY'),
5 | 'host' => env('MAILERSEND_API_HOST', 'api.mailersend.com'),
6 | 'protocol' => env('MAILERSEND_API_PROTO', 'https'),
7 | 'api_path' => env('MAILERSEND_API_PATH', 'v1'),
8 | ];
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | ; This file is for unifying the coding style for different editors and IDEs.
2 | ; More information at http://editorconfig.org
3 |
4 | root = true
5 |
6 | [*]
7 | charset = utf-8
8 | indent_size = 4
9 | indent_style = space
10 | end_of_line = lf
11 | insert_final_newline = true
12 | trim_trailing_whitespace = true
13 |
14 | [*.md]
15 | trim_trailing_whitespace = false
16 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 | tests
15 |
16 |
17 |
18 |
19 | src/
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/.github/workflows/php.yml:
--------------------------------------------------------------------------------
1 | name: PHP Composer
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 | branches: [ main ]
8 |
9 | jobs:
10 | run:
11 |
12 | runs-on: ubuntu-latest
13 | strategy:
14 | matrix:
15 | operating-system: [ubuntu-latest]
16 | php-versions: ['8.0', '8.1', '8.4']
17 | name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }}
18 |
19 | steps:
20 | - uses: actions/checkout@v5
21 |
22 | - name: Setup PHP
23 | uses: shivammathur/setup-php@v2
24 | with:
25 | php-version: ${{ matrix.php-versions }}
26 | extensions: mbstring, pdo, pdo_mysql, intl, zip
27 | coverage: none
28 | - name: Install dependencies
29 | run: composer install --prefer-dist --no-progress --no-suggest
30 |
31 | - name: Run test suite
32 | run: composer run-script test
33 |
--------------------------------------------------------------------------------
/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | getMessage());
25 | }
26 |
27 | $method = $reflection->getMethod($method);
28 | $method->setAccessible(true);
29 |
30 | return $method->invokeArgs($object, $parameters);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 MailerSend
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/src/LaravelDriverServiceProvider.php:
--------------------------------------------------------------------------------
1 | app->make(MailManager::class)->extend('mailersend', function (array $config) {
15 | $config = array_merge($this->app['config']->get('mailersend-driver', []), $config);
16 |
17 | $mailersend = new MailerSend([
18 | 'api_key' => Arr::get($config, 'api_key'),
19 | 'host' => Arr::get($config, 'host'),
20 | 'protocol' => Arr::get($config, 'protocol'),
21 | 'api_path' => Arr::get($config, 'api_path'),
22 | ]);
23 |
24 | return new MailerSendTransport($mailersend);
25 | });
26 |
27 | if ($this->app->runningInConsole()) {
28 | $this->publishes([
29 | __DIR__.'/../config/config.php' => config_path('laravel-driver.php'),
30 | ], 'config');
31 | }
32 | }
33 |
34 | public function register()
35 | {
36 | $this->mergeConfigFrom(__DIR__.'/../config/mailersend-driver.php', 'mailersend-driver');
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mailersend/laravel-driver",
3 | "description": "MailerSend Laravel Driver",
4 | "keywords": [
5 | "MailerSend",
6 | "mailersend",
7 | "email",
8 | "transactional",
9 | "laravel-driver"
10 | ],
11 | "homepage": "https://github.com/mailersend/mailersend-laravel-driver",
12 | "license": "MIT",
13 | "type": "library",
14 | "authors": [
15 | {
16 | "name": "Tautvydas Tijūnaitis",
17 | "email": "tautvydas@mailersend.com",
18 | "homepage": "https://mailersend.com",
19 | "role": "Developer"
20 | }
21 | ],
22 | "require": {
23 | "php": ">=8.0",
24 | "ext-json": "*",
25 | "illuminate/support": "^9.0 || ^10.0 || ^11.0 || ^12.0",
26 | "mailersend/mailersend": "^0.35.0",
27 | "nyholm/psr7": "^1.5",
28 | "php-http/guzzle7-adapter": "^1.0",
29 | "symfony/mailer": "^6.0 || ^7.0"
30 | },
31 | "require-dev": {
32 | "phpunit/phpunit": "^9.0 || ^10.5 || ^12.0",
33 | "orchestra/testbench": "^7.0 || ^9.0 || ^10.0"
34 | },
35 | "autoload": {
36 | "psr-4": {
37 | "MailerSend\\LaravelDriver\\": "src"
38 | }
39 | },
40 | "autoload-dev": {
41 | "psr-4": {
42 | "MailerSend\\LaravelDriver\\Tests\\": "tests"
43 | }
44 | },
45 | "scripts": {
46 | "test": "vendor/bin/phpunit"
47 | },
48 | "config": {
49 | "sort-packages": true,
50 | "allow-plugins": {
51 | "php-http/discovery": false
52 | }
53 | },
54 | "extra": {
55 | "laravel": {
56 | "providers": [
57 | "MailerSend\\LaravelDriver\\LaravelDriverServiceProvider"
58 | ],
59 | "aliases": {
60 | "LaravelDriver": "MailerSend\\LaravelDriver\\LaravelDriverFacade"
61 | }
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/MailerSendTrait.php:
--------------------------------------------------------------------------------
1 | driver() === 'mailersend') {
21 | $this->withSymfonyMessage(function (Email $message) use (
22 | $tags,
23 | $template_id,
24 | $personalization,
25 | $sendAt,
26 | $precedenceBulkHeader
27 | ) {
28 | $mailersendData = [];
29 |
30 | Arr::set($mailersendData, MailerSendTransport::MAILERSEND_DATA_TEMPLATE_ID, $template_id);
31 | Arr::set($mailersendData, MailerSendTransport::MAILERSEND_DATA_TAGS, $tags);
32 | Arr::set($mailersendData, MailerSendTransport::MAILERSEND_DATA_PERSONALIZATION, $personalization);
33 | Arr::set($mailersendData, MailerSendTransport::MAILERSEND_DATA_PRECENDECE_BULK_HEADER, $precedenceBulkHeader);
34 | Arr::set($mailersendData, MailerSendTransport::MAILERSEND_DATA_SEND_AT, $sendAt?->timestamp);
35 |
36 | $message->addPart(new DataPart(
37 | json_encode($mailersendData, JSON_THROW_ON_ERROR),
38 | MailerSendTransport::MAILERSEND_DATA_SUBTYPE.'.json',
39 | MailerSendTransport::MAILERSEND_DATA_TYPE.'/'.MailerSendTransport::MAILERSEND_DATA_SUBTYPE
40 | ));
41 | });
42 |
43 | if ($template_id !== null) {
44 | $this->html('');
45 | }
46 | }
47 |
48 | return $this;
49 | }
50 |
51 | protected function driver(): string
52 | {
53 | return function_exists('config') ? config('mail.default') : env('MAIL_MAILER');
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/tests/MailerSendTransportTest.php:
--------------------------------------------------------------------------------
1 | mailersend = new MailerSend([
26 | 'api_key' => 'key',
27 | 'host' => '',
28 | 'protocol' => '',
29 | 'api_path' => '',
30 | ]);
31 |
32 |
33 | $this->transport = new MailerSendTransport($this->mailersend);
34 | }
35 |
36 | public function test_basic_message_is_sent(): void
37 | {
38 | $response = [
39 | 'response' => $this->mock(ResponseInterface::class, function (MockInterface $mock) {
40 | $mock->expects('getHeaderLine')->withArgs(['X-Message-Id'])->andReturn('messageId');
41 |
42 | $stream = $this->mock(StreamInterface::class, function (MockInterface $mock) {
43 | $mock->expects('getContents')->withNoArgs()->andReturn('{"json":"value"}');
44 | });
45 |
46 | $mock->expects('getBody')->withNoArgs()->andReturn($stream);
47 | }),
48 | ];
49 |
50 | $emailParams = $this->partialMock(EmailParams::class, function (MockInterface $mock) {
51 | $mock->expects('setFrom')->withArgs(['test@mailersend.com'])->andReturnSelf();
52 | $mock->expects('setFromName')->withArgs(['John Doe'])->andReturnSelf();
53 | $mock->expects('setRecipients')->withAnyArgs()->andReturnSelf();
54 | $mock->expects('setSubject')->withArgs(['Subject'])->andReturnSelf();
55 | $mock->expects('setText')->withArgs(['Here is the text message'])->andReturnSelf();
56 | });
57 |
58 | /** @noinspection PhpFieldAssignmentTypeMismatchInspection */
59 | $this->mailersend->email = $this->mock(Email::class,
60 | function (MockInterface $mock) use ($emailParams, $response) {
61 | $mock->allows('send')->withArgs([$emailParams])->andReturn($response);
62 | });
63 |
64 | $message = (new \Symfony\Component\Mime\Email())
65 | ->subject('Subject')
66 | ->from('John Doe ')
67 | ->to('test-receive@mailersend.com')
68 | ->text('Here is the text message');
69 |
70 | $transport = new MailerSendTransport($this->mailersend);
71 | $sentMessage = $transport->send($message, Envelope::create($message));
72 |
73 | self::assertNotNull($sentMessage);
74 |
75 | $sentMessageString = $sentMessage->getMessage()->toString();
76 |
77 | self::assertStringContainsString('X-MailerSend-Message-Id: messageId', $sentMessageString);
78 | self::assertStringContainsString('X-MailerSend-Body: {"json":"value"}', $sentMessageString);
79 | }
80 |
81 | public function test_get_from(): void
82 | {
83 | $message = (new \Symfony\Component\Mime\Email())
84 | ->from('John Doe ');
85 |
86 | $getFrom = $this->callMethod($this->transport, 'getFrom', [$message]);
87 |
88 | self::assertEquals(['email' => 'test@mailersend.com', 'name' => 'John Doe'], $getFrom);
89 | }
90 |
91 | public function test_get_reply_to(): void
92 | {
93 | $message = (new \Symfony\Component\Mime\Email())
94 | ->replyTo('John Doe ');
95 |
96 | $getReplyTo = $this->callMethod($this->transport, 'getReplyTo', [$message]);
97 |
98 | self::assertEquals(['email' => 'test@mailersend.com', 'name' => 'John Doe'], $getReplyTo);
99 | }
100 |
101 | public function test_get_recipients(): void
102 | {
103 | $message = (new \Symfony\Component\Mime\Email())
104 | ->to('test-receive@mailersend.com');
105 |
106 | $getTo = $this->callMethod($this->transport, 'getRecipients', ['to', $message]);
107 |
108 | self::assertEquals('test-receive@mailersend.com', Arr::get(reset($getTo)->toArray(),
109 | 'email'));
110 | }
111 |
112 | public function test_get_attachments(): void
113 | {
114 | $attachment = new DataPart('data', 'filename', 'image/jpeg');
115 |
116 | if (method_exists(new \Symfony\Component\Mime\Email(), 'attachPart')) {
117 | $message = (new \Symfony\Component\Mime\Email())
118 | ->attachPart($attachment);
119 | } else {
120 | $message = (new \Symfony\Component\Mime\Email())
121 | ->addPart($attachment);
122 | }
123 |
124 | $getAttachments = $this->callMethod($this->transport, 'getAttachments', [$message]);
125 |
126 | $attachmentResult = reset($getAttachments)->toArray();
127 |
128 | self::assertEquals('data', Arr::get($attachmentResult,
129 | 'content'));
130 | self::assertEquals('filename', Arr::get($attachmentResult,
131 | 'filename'));
132 | self::assertEquals('attachment', Arr::get($attachmentResult,
133 | 'disposition'));
134 | }
135 |
136 | public function test_get_additional_data(): void
137 | {
138 | if (method_exists(new \Symfony\Component\Mime\Email(), 'attachPart')) {
139 | $message = (new \Symfony\Component\Mime\Email())
140 | ->attachPart(new DataPart(
141 | json_encode([
142 | 'template_id' => 'id'
143 | ], JSON_THROW_ON_ERROR),
144 | MailerSendTransport::MAILERSEND_DATA_SUBTYPE.'.json',
145 | MailerSendTransport::MAILERSEND_DATA_TYPE.'/'.MailerSendTransport::MAILERSEND_DATA_SUBTYPE
146 | ));
147 | } else {
148 | $message = (new \Symfony\Component\Mime\Email())
149 | ->addPart(new DataPart(
150 | json_encode([
151 | 'template_id' => 'id'
152 | ], JSON_THROW_ON_ERROR),
153 | MailerSendTransport::MAILERSEND_DATA_SUBTYPE.'.json',
154 | MailerSendTransport::MAILERSEND_DATA_TYPE.'/'.MailerSendTransport::MAILERSEND_DATA_SUBTYPE
155 | ));
156 | }
157 |
158 |
159 | $getAdditionalData = $this->callMethod($this->transport, 'getAdditionalData', [$message]);
160 |
161 | self::assertEquals('id', Arr::get($getAdditionalData,
162 | 'template_id'));
163 | self::assertEquals([], Arr::get($getAdditionalData,
164 | 'tags'));
165 | self::assertEquals([], Arr::get($getAdditionalData,
166 | 'personalization'));
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | MailerSend Laravel Driver
4 |
5 | [](./LICENSE.md)
6 |
7 | # Table of Contents
8 |
9 | * [Installation](#installation)
10 | * [Usage](#usage)
11 | * [Support and Feedback](#support-and-feedback)
12 | * [License](#license)
13 |
14 |
15 | # Installation
16 |
17 | ## Requirements
18 |
19 | - Laravel 9.0+
20 | - PHP 8.0+
21 | - Guzzle 7.0+
22 | - An API Key from [mailersend.com](https://www.mailersend.com)
23 |
24 | **For Laravel 7.x - 8.x support see [1.x branch](https://github.com/mailersend/mailersend-laravel-driver/tree/1.x)**
25 |
26 | ## Setup
27 |
28 | You can install the package via composer:
29 |
30 | ```bash
31 | composer require mailersend/laravel-driver
32 | ```
33 |
34 | After that, you need to set `MAILERSEND_API_KEY` in your `.env` file:
35 |
36 | ```dotenv
37 | MAILERSEND_API_KEY=
38 | ```
39 |
40 | Add MailerSend as a Laravel Mailer in `config/mail.php` in `mailers` array:
41 |
42 | ```php
43 | 'mailersend' => [
44 | 'transport' => 'mailersend',
45 | ],
46 | ```
47 |
48 | And set environment variable `MAIL_MAILER` in your `.env` file
49 |
50 | ```dotenv
51 | MAIL_MAILER=mailersend
52 | ```
53 |
54 | Also, double check that your `FROM` data is filled in `.env`:
55 |
56 | ```dotenv
57 | MAIL_FROM_ADDRESS=app@yourdomain.com
58 | MAIL_FROM_NAME="App Name"
59 | ```
60 |
61 |
62 | # Usage
63 |
64 | ### Old Syntax:
65 | This is an example using the build [mailable](https://laravel.com/docs/8.x/mail#writing-mailables) that you can use to send an email with.
66 |
67 | `app/Mail/TestEmail.php`
68 |
69 | ```php
70 | namespace App\Mail;
71 |
72 | use Illuminate\Bus\Queueable;
73 | use Illuminate\Mail\Mailable;
74 | use Illuminate\Queue\SerializesModels;
75 | use Illuminate\Support\Arr;
76 | use MailerSend\Helpers\Builder\Variable;
77 | use MailerSend\Helpers\Builder\Personalization;
78 | use MailerSend\LaravelDriver\MailerSendTrait;
79 |
80 | class TestEmail extends Mailable
81 | {
82 | use Queueable, SerializesModels, MailerSendTrait;
83 |
84 | public function build()
85 | {
86 | // Recipient for use with variables and/or personalization
87 | $to = Arr::get($this->to, '0.address');
88 |
89 | return $this
90 | ->view('emails.test_html')
91 | ->text('emails.test_text')
92 | ->attachFromStorageDisk('public', 'example.png')
93 | // Additional options for MailerSend API features
94 | ->mailersend(
95 | template_id: null,
96 | tags: ['tag'],
97 | personalization: [
98 | new Personalization($to, [
99 | 'var' => 'variable',
100 | 'number' => 123,
101 | 'object' => [
102 | 'key' => 'object-value'
103 | ],
104 | 'objectCollection' => [
105 | [
106 | 'name' => 'John'
107 | ],
108 | [
109 | 'name' => 'Patrick'
110 | ]
111 | ],
112 | ])
113 | ],
114 | precedenceBulkHeader: true,
115 | sendAt: new Carbon('2022-01-28 11:53:20'),
116 | );
117 | }
118 | }
119 | ```
120 |
121 | ### New Syntax:
122 | This is an example using the new [mailable](https://laravel.com/docs/9.x/mail#writing-mailables) syntax that you can use to send an email with.
123 |
124 | `app/Mail/TestEmail.php`
125 |
126 | ```php
127 | to, '0.address');
171 |
172 | // Additional options for MailerSend API features
173 | $this->mailersend(
174 | template_id: null,
175 | tags: ['tag'],
176 | personalization: [
177 | new Personalization($to, [
178 | 'var' => 'variable',
179 | 'number' => 123,
180 | 'object' => [
181 | 'key' => 'object-value'
182 | ],
183 | 'objectCollection' => [
184 | [
185 | 'name' => 'John'
186 | ],
187 | [
188 | 'name' => 'Patrick'
189 | ]
190 | ],
191 | ])
192 | ],
193 | precedenceBulkHeader: true,
194 | sendAt: new Carbon('2022-01-28 11:53:20'),
195 | );
196 |
197 | return new Content(
198 | view: 'emails.test_html',
199 | text: 'emails.test_text'
200 | );
201 | }
202 |
203 | /**
204 | * Get the attachments for the message.
205 | *
206 | * @return array
207 | */
208 | public function attachments(): array
209 | {
210 | return [
211 | Attachment::fromStorageDisk('public', 'example.png')
212 | ];
213 | }
214 | }
215 | ```
216 |
217 | We provide a `MailerSendTrait` trait that adds a `mailersend` method to the mailable and allows you to use additional options that are available through our API.
218 |
219 | After creating the mailable, you can send it using:
220 |
221 | ```php
222 | use App\Mail\TestEmail;
223 | use Illuminate\Support\Facades\Mail;
224 |
225 | Mail::to('recipient@domain.com')
226 | ->cc('cc@domain.com')
227 | ->bcc('bcc@domain.com')
228 | ->send(new TestEmail());
229 | ```
230 |
231 | Please refer to [Laravel Mail documenation](https://laravel.com/docs/9.x/mail) and [MailerSend API documentation](https://developers.mailersend.com) for more information.
232 |
233 |
234 | # Support and Feedback
235 |
236 | In case you find any bugs, submit an issue directly here in GitHub.
237 |
238 | If you have any troubles using our driver, feel free to contact our support by email [info@mailersend.com](mailto:info@mailersend.com)
239 |
240 | Official API documentation is at [https://developers.mailersend.com](https://developers.mailersend.com)
241 |
242 |
243 | # License
244 |
245 | [The MIT License (MIT)](LICENSE.md)
246 |
--------------------------------------------------------------------------------
/src/MailerSendTransport.php:
--------------------------------------------------------------------------------
1 | mailersend = $mailersend;
36 | }
37 |
38 | /**
39 | * @throws \Assert\AssertionFailedException
40 | * @throws \JsonException
41 | * @throws \Psr\Http\Client\ClientExceptionInterface
42 | * @throws TransportExceptionInterface
43 | * @throws \MailerSend\Exceptions\MailerSendAssertException
44 | */
45 | public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage
46 | {
47 | try{
48 | ['email' => $fromEmail, 'name' => $fromName] = $this->getFrom($message);
49 | ['email' => $replyToEmail, 'name' => $replyToName] = $this->getReplyTo($message);
50 |
51 | $text = $message->getTextBody();
52 | $html = $message->getHtmlBody();
53 |
54 | $to = $this->getRecipients('to', $message);
55 | $cc = $this->getRecipients('cc', $message);
56 | $bcc = $this->getRecipients('bcc', $message);
57 |
58 | $subject = $message->getSubject();
59 |
60 | $attachments = $this->getAttachments($message);
61 |
62 | [
63 | 'template_id' => $template_id,
64 | 'tags' => $tags,
65 | 'personalization' => $personalization,
66 | 'precedence_bulk_header' => $precedenceBulkHeader,
67 | 'send_at' => $sendAt,
68 | ] = $this->getAdditionalData($message);
69 |
70 | $emailParams = app(EmailParams::class)
71 | ->setFrom($fromEmail)
72 | ->setFromName($fromName)
73 | ->setReplyTo($replyToEmail)
74 | ->setReplyToName(strval($replyToName))
75 | ->setRecipients($to)
76 | ->setCc($cc)
77 | ->setBcc($bcc)
78 | ->setSubject($subject)
79 | ->setHtml($html)
80 | ->setText($text)
81 | ->setTemplateId($template_id)
82 | ->setPersonalization($personalization)
83 | ->setAttachments($attachments)
84 | ->setTags($tags)
85 | ->setPrecedenceBulkHeader($precedenceBulkHeader)
86 | ->setSendAt($sendAt);
87 |
88 | $listUnsubscribeHeader = $message->getHeaders()->get('List-Unsubscribe');
89 | $listUnsubscribe = $listUnsubscribeHeader ? $listUnsubscribeHeader->getBodyAsString() : null;
90 | if (!empty($listUnsubscribe)) {
91 | $emailParams->setListUnsubscribe($listUnsubscribe);
92 | }
93 |
94 | $response = $this->mailersend->email->send($emailParams);
95 |
96 | /** @var ResponseInterface $respInterface */
97 | $respInterface = $response['response'];
98 |
99 | if ($messageId = $respInterface->getHeaderLine('X-Message-Id')) {
100 | $message->getHeaders()?->addTextHeader('X-MailerSend-Message-Id', $messageId);
101 | }
102 |
103 | if ($body = $respInterface->getBody()->getContents()) {
104 | $message->getHeaders()?->addTextHeader('X-MailerSend-Body', $body);
105 | }
106 |
107 | return new SentMessage($message, $envelope);
108 | }catch (MailerSendHttpException $exception){
109 | throw new TransportException($exception->getMessage(), $exception->getCode());
110 | }
111 | }
112 |
113 | protected function getFrom(RawMessage $message): array
114 | {
115 | $from = $message->getFrom();
116 |
117 | if (count($from) > 0) {
118 | return ['name' => $from[0]->getName(), 'email' => $from[0]->getAddress()];
119 | }
120 |
121 | return ['email' => '', 'name' => ''];
122 | }
123 |
124 | protected function getReplyTo(RawMessage $message): array
125 | {
126 | $from = $message->getReplyTo();
127 |
128 | if (count($from) > 0) {
129 | return ['name' => $from[0]->getName(), 'email' => $from[0]->getAddress()];
130 | }
131 |
132 | return ['email' => '', 'name' => ''];
133 | }
134 |
135 | /**
136 | * @throws \MailerSend\Exceptions\MailerSendAssertException
137 | */
138 | protected function getRecipients(string $type, RawMessage $message): array
139 | {
140 | $recipients = [];
141 |
142 | if ($addresses = $message->{'get'.ucfirst($type)}()) {
143 | foreach ($addresses as $address) {
144 | $recipients[] = new Recipient($address->getAddress(), $address->getName());
145 | }
146 | }
147 |
148 | return $recipients;
149 | }
150 |
151 | protected function getAttachments(RawMessage $message): array
152 | {
153 | $attachments = [];
154 |
155 | foreach ($message->getAttachments() as $attachment) {
156 | /** @var DataPart $attachment */
157 |
158 | if ($attachment->getMediaSubtype() === self::MAILERSEND_DATA_SUBTYPE) {
159 | continue;
160 | }
161 |
162 | $attachments[] = new Attachment(
163 | $attachment->getBody(),
164 | $attachment->getPreparedHeaders()->get('content-disposition')?->getParameter('filename'),
165 | $attachment->getPreparedHeaders()->get('content-disposition')?->getBody(),
166 | $attachment->getPreparedHeaders()->get('content-id')?->getBodyAsString()
167 | );
168 | }
169 |
170 | return $attachments;
171 | }
172 |
173 | /**
174 | * @param RawMessage $message
175 | * @param array $payload
176 | * @throws \JsonException
177 | */
178 | protected function getAdditionalData(RawMessage $message): array
179 | {
180 | $defaultValues = [
181 | 'template_id' => null,
182 | 'personalization' => [],
183 | 'tags' => [],
184 | 'precedence_bulk_header' => null,
185 | 'send_at' => null,
186 | ];
187 |
188 | foreach ($message->getAttachments() as $attachment) {
189 | /** @var DataPart $attachment */
190 |
191 | if ($attachment->getMediaSubtype() !== self::MAILERSEND_DATA_SUBTYPE) {
192 | continue;
193 | }
194 |
195 | return array_merge($defaultValues,
196 | json_decode($attachment->getBody(), true, 512, JSON_THROW_ON_ERROR));
197 | }
198 |
199 | return $defaultValues;
200 | }
201 |
202 | public function __toString(): string
203 | {
204 | return 'mailersend';
205 | }
206 | }
207 |
--------------------------------------------------------------------------------