1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 08:52:39 +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:
epriestley 2018-02-06 09:29:40 -08:00
parent 1f53aa27e4
commit 19b3fb8863
6 changed files with 165 additions and 0 deletions

View file

@ -3188,6 +3188,7 @@ phutil_register_library_map(array(
'PhabricatorMailImplementationMailgunAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationMailgunAdapter.php',
'PhabricatorMailImplementationPHPMailerAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPHPMailerAdapter.php',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPHPMailerLiteAdapter.php',
'PhabricatorMailImplementationPostmarkAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPostmarkAdapter.php',
'PhabricatorMailImplementationSendGridAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationSendGridAdapter.php',
'PhabricatorMailImplementationTestAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationTestAdapter.php',
'PhabricatorMailManagementListInboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementListInboundWorkflow.php',
@ -8691,6 +8692,7 @@ phutil_register_library_map(array(
'PhabricatorMailImplementationMailgunAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationPHPMailerAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationPostmarkAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationSendGridAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationTestAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailManagementListInboundWorkflow' => 'PhabricatorMailManagementWorkflow',

View file

@ -94,4 +94,13 @@ abstract class PhabricatorMailImplementationAdapter extends Phobject {
return;
}
protected function renderAddress($email, $name = null) {
if (strlen($name)) {
// TODO: This needs to be escaped correctly.
return "{$name} <{$email}>";
} else {
return $email;
}
}
}

View file

@ -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;
}
}

View file

@ -47,6 +47,11 @@ final class PhabricatorMailManagementSendTestWorkflow
'help' => pht('Attach a file.'),
'repeat' => true,
),
array(
'name' => 'mailer',
'param' => 'key',
'help' => pht('Send with a specific configured mailer.'),
),
array(
'name' => 'html',
'help' => pht('Send as HTML mail.'),
@ -161,6 +166,21 @@ final class PhabricatorMailManagementSendTestWorkflow
$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) {
$data = Filesystem::readFile($attachment);
$name = basename($attachment);

View file

@ -319,6 +319,10 @@ final class PhabricatorMetaMTAMail
return $this->getParam('mailer.key');
}
public function setTryMailers(array $mailers) {
return $this->setParam('mailers.try', $mailers);
}
public function setHTMLBody($html) {
$this->setParam('html-body', $html);
return $this;
@ -469,6 +473,12 @@ final class PhabricatorMetaMTAMail
$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);
}

View file

@ -12,6 +12,7 @@ including a local mailer or various third-party services. Options include:
| Send Mail With | Setup | Cost | Inbound | Notes |
|---------|-------|------|---------|-------|
| Mailgun | Easy | Cheap | Yes | Recommended |
| Postmark | Easy | Cheap | Yes | Recommended |
| Amazon SES | Easy | Cheap | No | Recommended |
| SendGrid | Medium | Cheap | Yes | Discouraged |
| 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.
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
==================