Skip to content

[Mailer] message metadata and tags #35047

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
kbond opened this issue Dec 19, 2019 · 5 comments · Fixed by #35050
Closed

[Mailer] message metadata and tags #35047

kbond opened this issue Dec 19, 2019 · 5 comments · Fixed by #35050

Comments

@kbond
Copy link
Member

kbond commented Dec 19, 2019

Description
Transports like Postmark and Mailgun support message metadata and tags. The context of this issue will be Postmark.

#34766 implements tag support in Postmark by using a Tag header. This will work when using the Postmark API transport but not using the SMTP transport. For SMTP you need to add a custom header:

X-PM-Tag: password-reset

With the Postmark API, metadata is a key, value object added to the payload:

"Metadata": {
    "Color":"blue",
    "Client-Id":"12345"
}

With SMTP, it is a custom header for each value:

X-PM-Metadata-Color: blue
X-PM-Metadata-Client-Id: 12345

Example
Ideally, it would be nice to be able to do the following:

$email->setTag('password-reset');
$email->addMetadata('Color', 'blue');
$email->addMetadata('Client-Id, '12345');

Then the transports could convert to their specific tag/metadata format.

I can work on a PR for this if we can nail down how we want this to work.

@fabpot
Copy link
Member

fabpot commented Dec 19, 2019

I did not implement features that are not standards. If we want to implement some of these features, we should think of an abstraction for all/most transports. I don't want to recreate specific abstractions for each transport.

@kbond
Copy link
Member Author

kbond commented Dec 19, 2019

What about two new headers:

class TagHeader extends UnstructuredHeader
{
    public function __construct(string $value)
    {
        parent::__construct('X-Tag', $value);
    }
}
class MetadataHeader extends UnstructuredHeader
{
    private $key;

    public function __construct(string $name, string $value)
    {
        $this->key = $name;

        parent::__construct('X-Metadata-'.$name, $value);
    }
    
    public function getKey(): string
    {
        return $this->key;
    }
}

When creating an email, you can then do the following:

$email->getHeaders()->add(new TagHeader('password-reset'));
$email->getHeaders()->add(new MetadataHeader('Color', 'blue'));
$email->getHeaders()->add(new MetadataHeader('Client-ID', '12345'));

If a transport doesn't support metadata, the headers are just added to the message:

X-Tag: password-reset
X-Metadata-Color: blue
X-Metadata-Client-ID: 12345

@fabpot
Copy link
Member

fabpot commented Dec 19, 2019

Sounds like a good idea. Is the "tag" and "metadata" "concepts" shared among third-party providers?

@kbond
Copy link
Member Author

kbond commented Dec 19, 2019

@fabpot I replied here to move the conversation to the PR.

@fabpot
Copy link
Member

fabpot commented Jan 30, 2020

Closing to focus on the PR now.

@fabpot fabpot closed this as completed Jan 30, 2020
fabpot added a commit that referenced this issue Jan 30, 2020
This PR was merged into the 5.1-dev branch.

Discussion
----------

[Mailer] added tag/metadata support

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no
| Tickets       | Fix #35047
| License       | MIT
| Doc PR        | todo

This is an alternative to #34766 for adding tag and metadata support in a more generalized way.

Most transports allow for open/click tracking headers - maybe this should be handled in a similar way?

I added implementations for the Postmark (SMTP and API) and Mailgun (SMTP and API) transports. I can add others and tests/docs if this is acceptable.

### Example:

```php
use Symfony\Component\Mailer\Header\MetadataHeader;
use Symfony\Component\Mailer\Header\TagHeader;

$email->getHeaders()->add(new TagHeader('password-reset'));
$email->getHeaders()->add(new MetadataHeader('Color', 'blue'));
$email->getHeaders()->add(new MetadataHeader('Client-ID', '12345'));
```

The Postmark/Mailgun providers will parse these into their own headers/payload. For transports that don't support tags/metadata, these are just added as custom headers:

```
X-Tag: password-reset
X-Metadata-Color: blue
X-Metadata-Client-ID: 12345
```

Commits
-------

f2cdafc [Mailer] added tag/metadata support
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants