mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-23 12:09:12 +01:00
Add a Postmark mail adapter so it can be configured as an outbound mailer
Summary: Depends on D19007. Ref T12677. Test Plan: Used `bin/mail send-test ... --mailer postmark` to deliver some mail via Postmark. Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T12677 Differential Revision: https://secure.phabricator.com/D19009
This commit is contained in:
parent
1f53aa27e4
commit
19b3fb8863
6 changed files with 165 additions and 0 deletions
|
@ -3188,6 +3188,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorMailImplementationMailgunAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationMailgunAdapter.php',
|
'PhabricatorMailImplementationMailgunAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationMailgunAdapter.php',
|
||||||
'PhabricatorMailImplementationPHPMailerAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPHPMailerAdapter.php',
|
'PhabricatorMailImplementationPHPMailerAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPHPMailerAdapter.php',
|
||||||
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPHPMailerLiteAdapter.php',
|
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPHPMailerLiteAdapter.php',
|
||||||
|
'PhabricatorMailImplementationPostmarkAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPostmarkAdapter.php',
|
||||||
'PhabricatorMailImplementationSendGridAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationSendGridAdapter.php',
|
'PhabricatorMailImplementationSendGridAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationSendGridAdapter.php',
|
||||||
'PhabricatorMailImplementationTestAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationTestAdapter.php',
|
'PhabricatorMailImplementationTestAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationTestAdapter.php',
|
||||||
'PhabricatorMailManagementListInboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementListInboundWorkflow.php',
|
'PhabricatorMailManagementListInboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementListInboundWorkflow.php',
|
||||||
|
@ -8691,6 +8692,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorMailImplementationMailgunAdapter' => 'PhabricatorMailImplementationAdapter',
|
'PhabricatorMailImplementationMailgunAdapter' => 'PhabricatorMailImplementationAdapter',
|
||||||
'PhabricatorMailImplementationPHPMailerAdapter' => 'PhabricatorMailImplementationAdapter',
|
'PhabricatorMailImplementationPHPMailerAdapter' => 'PhabricatorMailImplementationAdapter',
|
||||||
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter',
|
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter',
|
||||||
|
'PhabricatorMailImplementationPostmarkAdapter' => 'PhabricatorMailImplementationAdapter',
|
||||||
'PhabricatorMailImplementationSendGridAdapter' => 'PhabricatorMailImplementationAdapter',
|
'PhabricatorMailImplementationSendGridAdapter' => 'PhabricatorMailImplementationAdapter',
|
||||||
'PhabricatorMailImplementationTestAdapter' => 'PhabricatorMailImplementationAdapter',
|
'PhabricatorMailImplementationTestAdapter' => 'PhabricatorMailImplementationAdapter',
|
||||||
'PhabricatorMailManagementListInboundWorkflow' => 'PhabricatorMailManagementWorkflow',
|
'PhabricatorMailManagementListInboundWorkflow' => 'PhabricatorMailManagementWorkflow',
|
||||||
|
|
|
@ -94,4 +94,13 @@ abstract class PhabricatorMailImplementationAdapter extends Phobject {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function renderAddress($email, $name = null) {
|
||||||
|
if (strlen($name)) {
|
||||||
|
// TODO: This needs to be escaped correctly.
|
||||||
|
return "{$name} <{$email}>";
|
||||||
|
} else {
|
||||||
|
return $email;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorMailImplementationPostmarkAdapter
|
||||||
|
extends PhabricatorMailImplementationAdapter {
|
||||||
|
|
||||||
|
const ADAPTERTYPE = 'postmark';
|
||||||
|
|
||||||
|
private $parameters = array();
|
||||||
|
|
||||||
|
public function setFrom($email, $name = '') {
|
||||||
|
$this->parameters['From'] = $this->renderAddress($email, $name);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addReplyTo($email, $name = '') {
|
||||||
|
$this->parameters['ReplyTo'] = $this->renderAddress($email, $name);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addTos(array $emails) {
|
||||||
|
foreach ($emails as $email) {
|
||||||
|
$this->parameters['To'][] = $email;
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addCCs(array $emails) {
|
||||||
|
foreach ($emails as $email) {
|
||||||
|
$this->parameters['Cc'][] = $email;
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addAttachment($data, $filename, $mimetype) {
|
||||||
|
$this->parameters['Attachments'][] = array(
|
||||||
|
'Name' => $filename,
|
||||||
|
'ContentType' => $mimetype,
|
||||||
|
'Content' => base64_encode($data),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addHeader($header_name, $header_value) {
|
||||||
|
$this->parameters['Headers'][] = array(
|
||||||
|
'Name' => $header_name,
|
||||||
|
'Value' => $header_value,
|
||||||
|
);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setBody($body) {
|
||||||
|
$this->parameters['TextBody'] = $body;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setHTMLBody($html_body) {
|
||||||
|
$this->parameters['HtmlBody'] = $html_body;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setSubject($subject) {
|
||||||
|
$this->parameters['Subject'] = $subject;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supportsMessageIDHeader() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function validateOptions(array $options) {
|
||||||
|
PhutilTypeSpec::checkMap(
|
||||||
|
$options,
|
||||||
|
array(
|
||||||
|
'access-token' => 'string',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newDefaultOptions() {
|
||||||
|
return array(
|
||||||
|
'access-token' => null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newLegacyOptions() {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function send() {
|
||||||
|
$access_token = $this->getOption('access-token');
|
||||||
|
|
||||||
|
$parameters = $this->parameters;
|
||||||
|
$flatten = array(
|
||||||
|
'To',
|
||||||
|
'Cc',
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($flatten as $key) {
|
||||||
|
if (isset($parameters[$key])) {
|
||||||
|
$parameters[$key] = implode(', ', $parameters[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
id(new PhutilPostmarkFuture())
|
||||||
|
->setAccessToken($access_token)
|
||||||
|
->setMethod('email', $parameters)
|
||||||
|
->resolve();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -47,6 +47,11 @@ final class PhabricatorMailManagementSendTestWorkflow
|
||||||
'help' => pht('Attach a file.'),
|
'help' => pht('Attach a file.'),
|
||||||
'repeat' => true,
|
'repeat' => true,
|
||||||
),
|
),
|
||||||
|
array(
|
||||||
|
'name' => 'mailer',
|
||||||
|
'param' => 'key',
|
||||||
|
'help' => pht('Send with a specific configured mailer.'),
|
||||||
|
),
|
||||||
array(
|
array(
|
||||||
'name' => 'html',
|
'name' => 'html',
|
||||||
'help' => pht('Send as HTML mail.'),
|
'help' => pht('Send as HTML mail.'),
|
||||||
|
@ -161,6 +166,21 @@ final class PhabricatorMailManagementSendTestWorkflow
|
||||||
$mail->setFrom($from->getPHID());
|
$mail->setFrom($from->getPHID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$mailer_key = $args->getArg('mailer');
|
||||||
|
if ($mailer_key !== null) {
|
||||||
|
$mailers = PhabricatorMetaMTAMail::newMailers();
|
||||||
|
$mailers = mpull($mailers, null, 'getKey');
|
||||||
|
if (!isset($mailers[$mailer_key])) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht(
|
||||||
|
'Mailer key ("%s") is not configured. Available keys are: %s.',
|
||||||
|
$mailer_key,
|
||||||
|
implode(', ', array_keys($mailers))));
|
||||||
|
}
|
||||||
|
|
||||||
|
$mail->setTryMailers(array($mailer_key));
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($attach as $attachment) {
|
foreach ($attach as $attachment) {
|
||||||
$data = Filesystem::readFile($attachment);
|
$data = Filesystem::readFile($attachment);
|
||||||
$name = basename($attachment);
|
$name = basename($attachment);
|
||||||
|
|
|
@ -319,6 +319,10 @@ final class PhabricatorMetaMTAMail
|
||||||
return $this->getParam('mailer.key');
|
return $this->getParam('mailer.key');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setTryMailers(array $mailers) {
|
||||||
|
return $this->setParam('mailers.try', $mailers);
|
||||||
|
}
|
||||||
|
|
||||||
public function setHTMLBody($html) {
|
public function setHTMLBody($html) {
|
||||||
$this->setParam('html-body', $html);
|
$this->setParam('html-body', $html);
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -469,6 +473,12 @@ final class PhabricatorMetaMTAMail
|
||||||
|
|
||||||
$mailers = self::newMailers();
|
$mailers = self::newMailers();
|
||||||
|
|
||||||
|
$try_mailers = $this->getParam('mailers.try');
|
||||||
|
if ($try_mailers) {
|
||||||
|
$mailers = mpull($mailers, null, 'getKey');
|
||||||
|
$mailers = array_select_keys($mailers, $try_mailers);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->sendWithMailers($mailers);
|
return $this->sendWithMailers($mailers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ including a local mailer or various third-party services. Options include:
|
||||||
| Send Mail With | Setup | Cost | Inbound | Notes |
|
| Send Mail With | Setup | Cost | Inbound | Notes |
|
||||||
|---------|-------|------|---------|-------|
|
|---------|-------|------|---------|-------|
|
||||||
| Mailgun | Easy | Cheap | Yes | Recommended |
|
| Mailgun | Easy | Cheap | Yes | Recommended |
|
||||||
|
| Postmark | Easy | Cheap | Yes | Recommended |
|
||||||
| Amazon SES | Easy | Cheap | No | Recommended |
|
| Amazon SES | Easy | Cheap | No | Recommended |
|
||||||
| SendGrid | Medium | Cheap | Yes | Discouraged |
|
| SendGrid | Medium | Cheap | Yes | Discouraged |
|
||||||
| External SMTP | Medium | Varies | No | Gmail, etc. |
|
| External SMTP | Medium | Varies | No | Gmail, etc. |
|
||||||
|
@ -147,6 +148,17 @@ To use this mailer, set `type` to `mailgun`, then configure these `options`:
|
||||||
- `domain`: Required string. Your Mailgun domain.
|
- `domain`: Required string. Your Mailgun domain.
|
||||||
|
|
||||||
|
|
||||||
|
Mailer: Postmark
|
||||||
|
================
|
||||||
|
|
||||||
|
Postmark is a third-party email delivery serivice. You can learn more at
|
||||||
|
<https://www.postmarkapp.com/>.
|
||||||
|
|
||||||
|
To use this mailer, set `type` to `postmark`, then configure these `options`:
|
||||||
|
|
||||||
|
- `access-token`: Required string. Your Postmark access token.
|
||||||
|
|
||||||
|
|
||||||
Mailer: Amazon SES
|
Mailer: Amazon SES
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue