Skip to content

[symfony/mailjet-mailer] Being able to customize payload when sending mail through mailjet+api #44100

@maximecolin

Description

@maximecolin

Description

Hi. I'm trying to send email through MailjetApiTransport using a MailJet template id (in order to ask MailJet to render the body with a template stored on MailJet instead of sending a text/html body).

With SMTP, we can set the X-MJ-TemplateID header to specify the template to use.

According to the MailJet documentation, using the API to send mail, we can't specify header which are already covered by a payload property. This is the case of X-MJ-TemplateID which allow to specify the template ID when you use SMTP. This is why I think the X-MJ-TemplateID header is forbidden here.

With the API we must instead use the payload property TemplateID. However it seems there is no way to add this to the payload generated by MailjetApiTransport.

Beside, there are a lot of other payload parameters that can't be set as header making impossible to use all MailJet features. While using MailjetSmtpTransport we can specify all header supported by MailJet, with MailjetApiTransport we can't specify the equivalent payload properties.

So, I would like to propose a way to set these payload parameters.

3 solutions come in my mind :

  1. What do you think about a subclass of Symfony\Component\Mime\Email containing these parameters as properties, MailjetApiMail for exemple. This object could be handle by the MailjetApiTransport which will add the properties to the payload if the email is an instance of MailjetApiMail.
  2. Alternatively, we can have a more generic ApiMail class with a payload setter. This solution could be more flexible as it does not require to backport MailJet API futur modification. Eventually, we could forbid payload parameters that are already generated from the Mail properties like From, To, etc.
  3. Finally, another way could be to make MailjetApiTransport::getPayload protected in order to allow us to extends MailjetApiTransport and add custom logic in getPayload.

Example

Solution 1, have a setter for each parameters:

$email = (new MailjetApiMail())
    ->to('foobar@example.com')
    ->from('barfoo@example.com')
    ->subject('Lorem ipsum')
    // mailjet specific properties that will feed the payload
    ->setTemplateID(23)
    ->setTemplateLanguage(true)
    ->setVariables([
        'var1' => 'value1',
        'var2' => 'value2',
    ])
;

Solution 2, we can have a more generic ApiMail class with a payload setter:

$email = (new ApiMail())
    ->to('foobar@example.com')
    ->from('barfoo@example.com')
    ->subject('Lorem ipsum')
    // will be merged with `MailjetApiTransport::getPayload` result
    ->payload([
        'TemplateID' => 23,
        'TemplateLanguage' => true,
        'Variables' => [
             'var1' => 'value1',
             'var2' => 'value2',
         ],
    ])
;

Solution 3, make getPayload method protected:

- private function getPayload(Email $email, Envelope $envelope): array
+ protected function getPayload(Email $email, Envelope $envelope): array

that allow us to extends the MailjetApiTransport::getPayload method

class CustomMailjetApiTransport
{
    protected function getPayload(Email $email, Envelope $envelope): array
    {
        $payload = parent::getPayload($email, $envelope);

        $payload['Messages'][0]['TemplateID'] = 23;

        return $payload;
    }
}

and then decorate the MailjetTransportFactory to return an instance of CustomMailjetApiTransport.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions