Page MenuHomePhabricator

D19009.id45574.diff
No OneTemporary

D19009.id45574.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -3188,6 +3188,7 @@
'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 @@
'PhabricatorMailImplementationMailgunAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationPHPMailerAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter',
+ 'PhabricatorMailImplementationPostmarkAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationSendGridAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationTestAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailManagementListInboundWorkflow' => 'PhabricatorMailManagementWorkflow',
diff --git a/src/applications/metamta/adapter/PhabricatorMailImplementationAdapter.php b/src/applications/metamta/adapter/PhabricatorMailImplementationAdapter.php
--- a/src/applications/metamta/adapter/PhabricatorMailImplementationAdapter.php
+++ b/src/applications/metamta/adapter/PhabricatorMailImplementationAdapter.php
@@ -94,4 +94,13 @@
return;
}
+ protected function renderAddress($email, $name = null) {
+ if (strlen($name)) {
+ // TODO: This needs to be escaped correctly.
+ return "{$name} <{$email}>";
+ } else {
+ return $email;
+ }
+ }
+
}
diff --git a/src/applications/metamta/adapter/PhabricatorMailImplementationPostmarkAdapter.php b/src/applications/metamta/adapter/PhabricatorMailImplementationPostmarkAdapter.php
new file mode 100644
--- /dev/null
+++ b/src/applications/metamta/adapter/PhabricatorMailImplementationPostmarkAdapter.php
@@ -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;
+ }
+
+}
diff --git a/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php b/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php
--- a/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php
+++ b/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php
@@ -48,6 +48,11 @@
'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 @@
$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);
diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php
--- a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php
+++ b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php
@@ -319,6 +319,10 @@
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 @@
$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);
}
diff --git a/src/docs/user/configuration/configuring_outbound_email.diviner b/src/docs/user/configuration/configuring_outbound_email.diviner
--- a/src/docs/user/configuration/configuring_outbound_email.diviner
+++ b/src/docs/user/configuration/configuring_outbound_email.diviner
@@ -12,6 +12,7 @@
| 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 @@
- `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
==================

File Metadata

Mime Type
text/plain
Expires
Tue, Feb 25, 2:42 PM (2 h, 8 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7202222
Default Alt Text
D19009.id45574.diff (8 KB)

Event Timeline