mirror of
https://we.phorge.it/source/phorge.git
synced 2025-03-06 01:19:24 +01:00
Clean up numerous rough edges in Mail configuration
Summary: - Support file attachments in Mailgun, after D8831. - Fix `bin/mail send-test --attach ...` flag. - Make `bin/mail send-test` route mail through the daemons. - Remove the `workerTaskID` on MetaMTAMail, which is only used (needlessly) by `bin/mail resend` and creates a huge mess elsewhere. - Currently, when mail fails, the daemon exits with a very generic and useless message. Instead, make `sendNow()` throw when it fails, so the real reason is surfaced. This is OK now because mail is always sent via the daemons. - Now that Mailgun supports attachments, document it. - Update a bunch of mail docs. Test Plan: - Sent mail. - Sent mail with attachments. - Read documentation. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Differential Revision: https://secure.phabricator.com/D8832
This commit is contained in:
parent
c00733a292
commit
fcf5149b36
9 changed files with 172 additions and 130 deletions
|
@ -144,7 +144,7 @@ return array(
|
||||||
'rsrc/css/phui/phui-status.css' => '2f562399',
|
'rsrc/css/phui/phui-status.css' => '2f562399',
|
||||||
'rsrc/css/phui/phui-tag-view.css' => '295d81c4',
|
'rsrc/css/phui/phui-tag-view.css' => '295d81c4',
|
||||||
'rsrc/css/phui/phui-text.css' => '23e9b4b7',
|
'rsrc/css/phui/phui-text.css' => '23e9b4b7',
|
||||||
'rsrc/css/phui/phui-timeline-view.css' => '17905388',
|
'rsrc/css/phui/phui-timeline-view.css' => '18035042',
|
||||||
'rsrc/css/phui/phui-workboard-view.css' => '84f2c272',
|
'rsrc/css/phui/phui-workboard-view.css' => '84f2c272',
|
||||||
'rsrc/css/phui/phui-workpanel-view.css' => '97b69459',
|
'rsrc/css/phui/phui-workpanel-view.css' => '97b69459',
|
||||||
'rsrc/css/sprite-actions.css' => '969ad0e5',
|
'rsrc/css/sprite-actions.css' => '969ad0e5',
|
||||||
|
@ -767,7 +767,7 @@ return array(
|
||||||
'phui-status-list-view-css' => '2f562399',
|
'phui-status-list-view-css' => '2f562399',
|
||||||
'phui-tag-view-css' => '295d81c4',
|
'phui-tag-view-css' => '295d81c4',
|
||||||
'phui-text-css' => '23e9b4b7',
|
'phui-text-css' => '23e9b4b7',
|
||||||
'phui-timeline-view-css' => '17905388',
|
'phui-timeline-view-css' => '18035042',
|
||||||
'phui-workboard-view-css' => '84f2c272',
|
'phui-workboard-view-css' => '84f2c272',
|
||||||
'phui-workpanel-view-css' => '97b69459',
|
'phui-workpanel-view-css' => '97b69459',
|
||||||
'policy-css' => '957ea14c',
|
'policy-css' => '957ea14c',
|
||||||
|
|
|
@ -22,14 +22,11 @@ final class PhabricatorMetaMTAWorker
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$id = $message->getID();
|
try {
|
||||||
$message->sendNow();
|
$message->sendNow();
|
||||||
|
} catch (PhabricatorMetaMTAPermanentFailureException $ex) {
|
||||||
// task failed if the message is still queued
|
// If the mailer fails permanently, fail this task permanently.
|
||||||
// (instead of sent, void, or failed)
|
throw new PhabricatorWorkerPermanentFailureException($ex->getMessage());
|
||||||
if ($message->getStatus() == PhabricatorMetaMTAMail::STATUS_QUEUE) {
|
|
||||||
throw new Exception(
|
|
||||||
pht('Failed to send message.'));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ final class PhabricatorMailImplementationMailgunAdapter
|
||||||
extends PhabricatorMailImplementationAdapter {
|
extends PhabricatorMailImplementationAdapter {
|
||||||
|
|
||||||
private $params = array();
|
private $params = array();
|
||||||
|
private $attachments = array();
|
||||||
|
|
||||||
public function setFrom($email, $name = '') {
|
public function setFrom($email, $name = '') {
|
||||||
$this->params['from'] = $email;
|
$this->params['from'] = $email;
|
||||||
|
@ -37,9 +38,13 @@ final class PhabricatorMailImplementationMailgunAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addAttachment($data, $filename, $mimetype) {
|
public function addAttachment($data, $filename, $mimetype) {
|
||||||
// TODO: implement attachments. Requires changes in HTTPSFuture
|
$this->attachments[] = array(
|
||||||
throw new Exception(
|
'data' => $data,
|
||||||
"Mailgun adapter does not currently support attachments.");
|
'name' => $filename,
|
||||||
|
'type' => $mimetype,
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addHeader($header_name, $header_value) {
|
public function addHeader($header_name, $header_value) {
|
||||||
|
@ -71,7 +76,7 @@ final class PhabricatorMailImplementationMailgunAdapter
|
||||||
$domain = PhabricatorEnv::getEnvConfig('mailgun.domain');
|
$domain = PhabricatorEnv::getEnvConfig('mailgun.domain');
|
||||||
$params = array();
|
$params = array();
|
||||||
|
|
||||||
$params['to'] = idx($this->params, 'tos', array());
|
$params['to'] = implode(', ', idx($this->params, 'tos', array()));
|
||||||
$params['subject'] = idx($this->params, 'subject');
|
$params['subject'] = idx($this->params, 'subject');
|
||||||
|
|
||||||
if (idx($this->params, 'is-html')) {
|
if (idx($this->params, 'is-html')) {
|
||||||
|
@ -93,7 +98,7 @@ final class PhabricatorMailImplementationMailgunAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idx($this->params, 'ccs')) {
|
if (idx($this->params, 'ccs')) {
|
||||||
$params['cc'] = $this->params['ccs'];
|
$params['cc'] = implode(', ', $this->params['ccs']);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (idx($this->params, 'headers', array()) as $header) {
|
foreach (idx($this->params, 'headers', array()) as $header) {
|
||||||
|
@ -106,6 +111,14 @@ final class PhabricatorMailImplementationMailgunAdapter
|
||||||
$params);
|
$params);
|
||||||
$future->setMethod('POST');
|
$future->setMethod('POST');
|
||||||
|
|
||||||
|
foreach ($this->attachments as $attachment) {
|
||||||
|
$future->attachFileData(
|
||||||
|
'attachment',
|
||||||
|
$attachment['data'],
|
||||||
|
$attachment['name'],
|
||||||
|
$attachment['type']);
|
||||||
|
}
|
||||||
|
|
||||||
list($body) = $future->resolvex();
|
list($body) = $future->resolvex();
|
||||||
|
|
||||||
$response = json_decode($body, true);
|
$response = json_decode($body, true);
|
||||||
|
|
|
@ -44,15 +44,6 @@ final class PhabricatorMailManagementResendWorkflow
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($messages as $message) {
|
foreach ($messages as $message) {
|
||||||
if ($message->getStatus() == PhabricatorMetaMTAMail::STATUS_QUEUE) {
|
|
||||||
if ($message->getWorkerTaskID()) {
|
|
||||||
$console->writeOut(
|
|
||||||
"Message #%d is already queued with an assigned send task.\n",
|
|
||||||
$message->getID());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$message->setStatus(PhabricatorMetaMTAMail::STATUS_QUEUE);
|
$message->setStatus(PhabricatorMetaMTAMail::STATUS_QUEUE);
|
||||||
$message->save();
|
$message->save();
|
||||||
|
|
||||||
|
@ -60,9 +51,6 @@ final class PhabricatorMailManagementResendWorkflow
|
||||||
'PhabricatorMetaMTAWorker',
|
'PhabricatorMetaMTAWorker',
|
||||||
$message->getID());
|
$message->getID());
|
||||||
|
|
||||||
$message->setWorkerTaskID($mailer_task->getID());
|
|
||||||
$message->save();
|
|
||||||
|
|
||||||
$console->writeOut(
|
$console->writeOut(
|
||||||
"Queued message #%d for resend.\n",
|
"Queued message #%d for resend.\n",
|
||||||
$message->getID());
|
$message->getID());
|
||||||
|
|
|
@ -126,8 +126,16 @@ final class PhabricatorMailManagementSendTestWorkflow
|
||||||
$mail->setFrom($from->getPHID());
|
$mail->setFrom($from->getPHID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($attach as $attachment) {
|
||||||
|
$data = Filesystem::readFile($attachment);
|
||||||
|
$name = basename($attachment);
|
||||||
|
$mime = Filesystem::getMimeType($attachment);
|
||||||
|
$file = new PhabricatorMetaMTAAttachment($data, $name, $mime);
|
||||||
|
$mail->addAttachment($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
PhabricatorWorker::setRunAllTasksInProcess(true);
|
||||||
$mail->save();
|
$mail->save();
|
||||||
$mail->sendNow();
|
|
||||||
|
|
||||||
$console->writeErr(
|
$console->writeErr(
|
||||||
"%s\n\n phabricator/ $ ./bin/mail show-outbound --id %d\n\n",
|
"%s\n\n phabricator/ $ ./bin/mail show-outbound --id %d\n\n",
|
||||||
|
|
|
@ -231,15 +231,6 @@ final class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
|
||||||
return $this->getParam('is-error', false);
|
return $this->getParam('is-error', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getWorkerTaskID() {
|
|
||||||
return $this->getParam('worker-task');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setWorkerTaskID($id) {
|
|
||||||
$this->setParam('worker-task', $id);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getToPHIDs() {
|
public function getToPHIDs() {
|
||||||
return $this->getParam('to', array());
|
return $this->getParam('to', array());
|
||||||
}
|
}
|
||||||
|
@ -304,16 +295,13 @@ final class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
|
||||||
|
|
||||||
$this->openTransaction();
|
$this->openTransaction();
|
||||||
// Save to generate a task ID.
|
// Save to generate a task ID.
|
||||||
parent::save();
|
$result = parent::save();
|
||||||
|
|
||||||
// Queue a task to send this mail.
|
// Queue a task to send this mail.
|
||||||
$mailer_task = PhabricatorWorker::scheduleTask(
|
$mailer_task = PhabricatorWorker::scheduleTask(
|
||||||
'PhabricatorMetaMTAWorker',
|
'PhabricatorMetaMTAWorker',
|
||||||
$this->getID());
|
$this->getID());
|
||||||
|
|
||||||
// Save again to update the task ID.
|
|
||||||
$this->setWorkerTaskID($mailer_task->getID());
|
|
||||||
$result = parent::save();
|
|
||||||
$this->saveTransaction();
|
$this->saveTransaction();
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
|
@ -624,30 +612,41 @@ final class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
|
||||||
$mailer->addCCs($add_cc);
|
$mailer->addCCs($add_cc);
|
||||||
}
|
}
|
||||||
} catch (Exception $ex) {
|
} catch (Exception $ex) {
|
||||||
$this->setStatus(self::STATUS_FAIL);
|
$this
|
||||||
$this->setMessage($ex->getMessage());
|
->setStatus(self::STATUS_FAIL)
|
||||||
return $this->save();
|
->setMessage($ex->getMessage())
|
||||||
|
->save();
|
||||||
|
|
||||||
|
throw $ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$ok = $mailer->send();
|
$ok = $mailer->send();
|
||||||
$error = null;
|
if (!$ok) {
|
||||||
} catch (PhabricatorMetaMTAPermanentFailureException $ex) {
|
// TODO: At some point, we should clean this up and make all mailers
|
||||||
$this->setStatus(self::STATUS_FAIL);
|
// throw.
|
||||||
$this->setMessage($ex->getMessage());
|
throw new Exception(
|
||||||
return $this->save();
|
pht('Mail adapter encountered an unexpected, unspecified failure.'));
|
||||||
} catch (Exception $ex) {
|
}
|
||||||
$ok = false;
|
|
||||||
$error = $ex->getMessage()."\n".$ex->getTraceAsString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$ok) {
|
|
||||||
$this->setMessage($error);
|
|
||||||
} else {
|
|
||||||
$this->setStatus(self::STATUS_SENT);
|
$this->setStatus(self::STATUS_SENT);
|
||||||
}
|
$this->save();
|
||||||
|
|
||||||
return $this->save();
|
return $this;
|
||||||
|
} catch (PhabricatorMetaMTAPermanentFailureException $ex) {
|
||||||
|
$this
|
||||||
|
->setStatus(self::STATUS_FAIL)
|
||||||
|
->setMessage($ex->getMessage())
|
||||||
|
->save();
|
||||||
|
|
||||||
|
throw $ex;
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
$this
|
||||||
|
->setMessage($ex->getMessage()."\n".$ex->getTraceAsString())
|
||||||
|
->save();
|
||||||
|
|
||||||
|
throw $ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getReadableStatus($status_code) {
|
public static function getReadableStatus($status_code) {
|
||||||
|
|
|
@ -30,7 +30,11 @@ final class PhabricatorMetaMTAMailTestCase extends PhabricatorTestCase {
|
||||||
|
|
||||||
$mailer = new PhabricatorMailImplementationTestAdapter();
|
$mailer = new PhabricatorMailImplementationTestAdapter();
|
||||||
$mailer->setFailTemporarily(true);
|
$mailer->setFailTemporarily(true);
|
||||||
$mail->sendNow($force = true, $mailer);
|
try {
|
||||||
|
$mail->sendNow($force = true, $mailer);
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
// Ignore.
|
||||||
|
}
|
||||||
$this->assertEqual(
|
$this->assertEqual(
|
||||||
PhabricatorMetaMTAMail::STATUS_QUEUE,
|
PhabricatorMetaMTAMail::STATUS_QUEUE,
|
||||||
$mail->getStatus());
|
$mail->getStatus());
|
||||||
|
@ -42,7 +46,11 @@ final class PhabricatorMetaMTAMailTestCase extends PhabricatorTestCase {
|
||||||
|
|
||||||
$mailer = new PhabricatorMailImplementationTestAdapter();
|
$mailer = new PhabricatorMailImplementationTestAdapter();
|
||||||
$mailer->setFailPermanently(true);
|
$mailer->setFailPermanently(true);
|
||||||
$mail->sendNow($force = true, $mailer);
|
try {
|
||||||
|
$mail->sendNow($force = true, $mailer);
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
// Ignore.
|
||||||
|
}
|
||||||
$this->assertEqual(
|
$this->assertEqual(
|
||||||
PhabricatorMetaMTAMail::STATUS_FAIL,
|
PhabricatorMetaMTAMail::STATUS_FAIL,
|
||||||
$mail->getStatus());
|
$mail->getStatus());
|
||||||
|
|
|
@ -8,19 +8,24 @@ Maniphest tasks via email.
|
||||||
= Preamble =
|
= Preamble =
|
||||||
|
|
||||||
This can be extremely difficult to configure correctly. This is doubly true if
|
This can be extremely difficult to configure correctly. This is doubly true if
|
||||||
you use sendmail.
|
you use a local MTA.
|
||||||
|
|
||||||
There are basically a few approaches available:
|
There are a few approaches available:
|
||||||
|
|
||||||
- Use SendGrid (<http://sendgrid.com/>), which is very easy but is not free.
|
| Receive Mail With | Setup | Cost | Notes |
|
||||||
- Run your own MTA, which can be quite harrowing to configure but is free.
|
|--------|-------|------|-------|
|
||||||
- Tell the Phabricator devteam about another service you'd like support for,
|
| Mailgun | Easy | Cheap | Recommended |
|
||||||
this stuff is seriously terrible to configure on your own.
|
| SendGrid | Easy | Cheap | |
|
||||||
|
| Local MTA | Extremely Difficult | Free | Strongly discouraged! |
|
||||||
|
|
||||||
|
The remainder of this document walks through configuring Phabricator to
|
||||||
|
receive mail, and then configuring your chosen transport to deliver mail
|
||||||
|
to Phabricator.
|
||||||
|
|
||||||
= Configuring Phabricator =
|
= Configuring Phabricator =
|
||||||
|
|
||||||
By default, Phabricator uses a "noreply@phabricator.example.com" email address
|
By default, Phabricator uses a `noreply@phabricator.example.com` email address
|
||||||
as the 'From' (configurable with ##metamta.default-address##) and sets
|
as the 'From' (configurable with `metamta.default-address`) and sets
|
||||||
'Reply-To' to the user generating the email (e.g., by making a comment), if the
|
'Reply-To' to the user generating the email (e.g., by making a comment), if the
|
||||||
mail was generated by a user action. This means that users can reply (or
|
mail was generated by a user action. This means that users can reply (or
|
||||||
reply-all) to email to discuss changes, but the conversation won't be recorded
|
reply-all) to email to discuss changes, but the conversation won't be recorded
|
||||||
|
@ -36,24 +41,24 @@ over email, set these configuration keys:
|
||||||
Maniphest.
|
Maniphest.
|
||||||
|
|
||||||
Set these keys to some domain which you configure according to the instructions
|
Set these keys to some domain which you configure according to the instructions
|
||||||
below, e.g. "##phabricator.example.com##". You can set these both to the same
|
below, e.g. `phabricator.example.com`. You can set these both to the same
|
||||||
domain, and will generally want to. Once you set these keys, emails will use a
|
domain, and will generally want to. Once you set these keys, emails will use a
|
||||||
'Reply-To' like "##T123+273+af310f9220ad@example.com##", which -- when
|
'Reply-To' like `T123+273+af310f9220ad@example.com`, which -- when
|
||||||
configured correctly, according to the instructions below -- will parse incoming
|
configured correctly, according to the instructions below -- will parse incoming
|
||||||
email and allow users to interact with Maniphest tasks and Differential
|
email and allow users to interact with Maniphest tasks and Differential
|
||||||
revisions over email.
|
revisions over email.
|
||||||
|
|
||||||
If you don't want phabricator to take up an entire domain (or subdomain) you
|
If you don't want Phabricator to take up an entire domain (or subdomain) you
|
||||||
can configure a general prefix so you can use a single mailbox to receive mail
|
can configure a general prefix so you can use a single mailbox to receive mail
|
||||||
on. To make use of this set ##metamta.single-reply-handler-prefix## to the
|
on. To make use of this set `metamta.single-reply-handler-prefix` to the
|
||||||
prefix of your choice, and phabricator will prepend this to the 'Reply-To'
|
prefix of your choice, and Phabricator will prepend this to the 'Reply-To'
|
||||||
mail address. This works because everything up to the first (optional) '+'
|
mail address. This works because everything up to the first (optional) '+'
|
||||||
character in an email-address is considered the receiver, and everything
|
character in an email-address is considered the receiver, and everything
|
||||||
after is essentially "ignored".
|
after is essentially ignored.
|
||||||
|
|
||||||
You can also set up a task creation email address, like ##bugs@example.com##,
|
You can also set up a task creation email address, like `bugs@example.com`,
|
||||||
which will create a Maniphest task out of any email which is set to it. To do
|
which will create a Maniphest task out of any email which is set to it. To do
|
||||||
this, set ##metamta.maniphest.public-create-email## in your configuration. This
|
this, set `metamta.maniphest.public-create-email` in your configuration. This
|
||||||
has some mild security implications, see below.
|
has some mild security implications, see below.
|
||||||
|
|
||||||
= Security =
|
= Security =
|
||||||
|
@ -77,9 +82,9 @@ project and need to interact with users whose email accounts you have no control
|
||||||
over).
|
over).
|
||||||
|
|
||||||
If you leak a bunch of reply-to addresses by accident, you can change
|
If you leak a bunch of reply-to addresses by accident, you can change
|
||||||
##phabricator.mail-key## in your configuration to invalidate all the old hashes.
|
`phabricator.mail-key` in your configuration to invalidate all the old hashes.
|
||||||
|
|
||||||
You can also set ##metamta.public-replies##, which will change how Phabricator
|
You can also set `metamta.public-replies`, which will change how Phabricator
|
||||||
delivers email. Instead of sending each recipient a unique mail with a personal
|
delivers email. Instead of sending each recipient a unique mail with a personal
|
||||||
reply-to address, it will send a single email to everyone with a public reply-to
|
reply-to address, it will send a single email to everyone with a public reply-to
|
||||||
address. This decreases security because anyone who can spoof a "From" address
|
address. This decreases security because anyone who can spoof a "From" address
|
||||||
|
@ -88,7 +93,7 @@ practically, is a reasonable setting for many installs. The reply-to address
|
||||||
will still contain a hash unique to the object it represents, so users who have
|
will still contain a hash unique to the object it represents, so users who have
|
||||||
not received an email about an object can not blindly interact with it.
|
not received an email about an object can not blindly interact with it.
|
||||||
|
|
||||||
If you enable ##metamta.maniphest.public-create-email##, that address also uses
|
If you enable `metamta.maniphest.public-create-email`, that address also uses
|
||||||
the weaker "From" authentication mechanism.
|
the weaker "From" authentication mechanism.
|
||||||
|
|
||||||
NOTE: Phabricator does not currently attempt to verify "From" addresses because
|
NOTE: Phabricator does not currently attempt to verify "From" addresses because
|
||||||
|
@ -116,7 +121,18 @@ if your inbound email configuration is incorrect or even disabled.
|
||||||
|
|
||||||
Run `bin/mail help <command>` for detailed help on using these commands.
|
Run `bin/mail help <command>` for detailed help on using these commands.
|
||||||
|
|
||||||
= SendGrid =
|
= Mailgun Setup =
|
||||||
|
|
||||||
|
To use Mailgun, you need a Mailgun account. You can sign up at
|
||||||
|
<http://www.mailgun.com>. Provided you have such an account, configure it
|
||||||
|
like this:
|
||||||
|
|
||||||
|
- Configure a mail domain according to Mailgun's instructions.
|
||||||
|
- Add a Mailgun route with a `catch_all()` rule which takes the action
|
||||||
|
`forward("https://phabricator.example.com/mail/mailgun/")`. Replace the
|
||||||
|
example domain with your actual domain.
|
||||||
|
|
||||||
|
= SendGrid Setup =
|
||||||
|
|
||||||
To use SendGrid, you need a SendGrid account with access to the "Parse API" for
|
To use SendGrid, you need a SendGrid account with access to the "Parse API" for
|
||||||
inbound email. Provided you have such an account, configure it like this:
|
inbound email. Provided you have such an account, configure it like this:
|
||||||
|
@ -142,7 +158,7 @@ That's it! If everything is working properly you should be able to send email
|
||||||
to ##anything@phabricator.example.com## and it should appear in
|
to ##anything@phabricator.example.com## and it should appear in
|
||||||
`bin/mail list-inbound` within a few seconds.
|
`bin/mail list-inbound` within a few seconds.
|
||||||
|
|
||||||
= Installing Mailparse =
|
= Local MTA: Installing Mailparse =
|
||||||
|
|
||||||
If you're going to run your own MTA, you need to install the PECL mailparse
|
If you're going to run your own MTA, you need to install the PECL mailparse
|
||||||
extension. In theory, you can do that with:
|
extension. In theory, you can do that with:
|
||||||
|
@ -165,7 +181,7 @@ If you get a linker error like this:
|
||||||
mailparse.so. This is not the default if you have individual files in
|
mailparse.so. This is not the default if you have individual files in
|
||||||
##php.d/##.
|
##php.d/##.
|
||||||
|
|
||||||
= MTA: Configuring Sendmail =
|
= Local MTA: Configuring Sendmail =
|
||||||
|
|
||||||
Before you can configure Sendmail, you need to install Mailparse. See the
|
Before you can configure Sendmail, you need to install Mailparse. See the
|
||||||
section "Installing Mailparse" above.
|
section "Installing Mailparse" above.
|
||||||
|
@ -199,7 +215,7 @@ That will forward all mail to @yourdomain.com to the Phabricator processing
|
||||||
script. Run ##sudo /etc/mail/make## or similar and then restart sendmail with
|
script. Run ##sudo /etc/mail/make## or similar and then restart sendmail with
|
||||||
##sudo /etc/init.d/sendmail restart##.
|
##sudo /etc/init.d/sendmail restart##.
|
||||||
|
|
||||||
= MTA: Configuring Lamson =
|
= Local MTA: Configuring Lamson =
|
||||||
|
|
||||||
Before you can configure Lamson, you need to install Mailparse. See the section
|
Before you can configure Lamson, you need to install Mailparse. See the section
|
||||||
"Installing Mailparse" above.
|
"Installing Mailparse" above.
|
||||||
|
|
|
@ -5,53 +5,60 @@ Instructions for configuring Phabricator to send mail.
|
||||||
|
|
||||||
= Overview =
|
= Overview =
|
||||||
|
|
||||||
Phabricator can send outbound email via several different adapters:
|
Phabricator can send outbound email via several different providers, called
|
||||||
|
"Adapters".
|
||||||
|
|
||||||
- by running ##sendmail## on the local host with SMTP; or
|
| Send Mail With | Setup | Cost | Inbound | Notes |
|
||||||
- by running postfix on the local host with SMTP; or
|
|---------|-------|------|---------|-------|
|
||||||
- by using Amazon SES (Simple Email Service); or
|
| Mailgun | Easy | Cheap | Yes | Recommended |
|
||||||
- by using SendGrid's REST API; or
|
| Amazon SES | Easy | Cheap | No | Recommended |
|
||||||
- via a custom adapter you write; or
|
| SendGrid | Easy | Cheap | Yes | |
|
||||||
- by dropping email into a hole and not delivering it.
|
| External SMTP | Medium | Varies | No | Gmail, etc. |
|
||||||
|
| Local SMTP | Hard | Free | No | (Default) sendmail, postfix, etc |
|
||||||
|
| Custom | Hard | Free | No | Write an adapter for some other service. |
|
||||||
|
| Drop in a Hole | Easy | Free | No | Drops mail in a deep, dark hole. |
|
||||||
|
|
||||||
Of these, ##sendmail## is the default but requires some configuration. SES and
|
Of these options, sending mail via local SMTP is the default, but usually
|
||||||
SendGrid are easier, but cost money and have some limitations. Writing a custom
|
requires some configuration to get working. See below for details on how to
|
||||||
solution requires digging into the code. See below for details on how to set up
|
select and configure a delivery method.
|
||||||
each method.
|
|
||||||
|
|
||||||
Phabricator can also send outbound email in two ways:
|
Overall, Mailgun and SES are much easier to set up, and using one of them is
|
||||||
|
recommended. In particular, Mailgun will also let you set up inbound email
|
||||||
|
easily.
|
||||||
|
|
||||||
- immediately, when messages are generated (default); or
|
If you have some internal mail service you'd like to use you can also
|
||||||
- in the background, via a daemon.
|
write a custom adapter, but this requires digging into the code.
|
||||||
|
|
||||||
Sending mail in the background requires that you be running the Phabricator
|
Phabricator sends mail in the background, so the daemons need to be running for
|
||||||
daemons, but can greatly improve the performance of the application if your mail
|
it to be able to deliver mail. You should receive setup warnings if they are
|
||||||
handler is slow. For more information on using daemons, see
|
not. For more information on using daemons, see
|
||||||
@{article:Managing Daemons with phd}.
|
@{article:Managing Daemons with phd}.
|
||||||
|
|
||||||
= Basics =
|
= Basics =
|
||||||
|
|
||||||
Regardless of how outbound email is delivered, you should configure these keys
|
Regardless of how outbound email is delivered, you should configure these keys
|
||||||
in your configuration file:
|
in your configuration:
|
||||||
|
|
||||||
- **metamta.default-address** determines where mail is sent "From" by
|
- **metamta.default-address** determines where mail is sent "From" by
|
||||||
default. If your domain is ##example.org##, set this to something like
|
default. If your domain is `example.org`, set this to something like
|
||||||
"##noreply@example.org##".
|
`noreply@example.org`.
|
||||||
- **metamta.domain** should be set to your domain, e.g. "##example.org##".
|
- **metamta.domain** should be set to your domain, e.g. `example.org`.
|
||||||
- **metamta.can-send-as-user** should be left as ##false## in most cases,
|
- **metamta.can-send-as-user** should be left as ##false## in most cases,
|
||||||
but see the documentation in ##default.conf.php## for details.
|
but see the documentation for details.
|
||||||
|
|
||||||
= Configuring Mail Adapters =
|
= Configuring Mail Adapters =
|
||||||
|
|
||||||
To choose how mail will be sent, change the **metamta.mail-adapter** key in
|
To choose how mail will be sent, change the `metamta.mail-adapter` key in
|
||||||
your configuration. Possible values are:
|
your configuration. Possible values are listed in the UI:
|
||||||
|
|
||||||
|
- ##PhabricatorMailImplementationAmazonMailgunAdapter##: use Mailgun, see
|
||||||
|
"Adapter: Mailgun".
|
||||||
|
- ##PhabricatorMailImplementationAmazonSESAdapter##: use Amazon SES, see
|
||||||
|
"Adapter: Amazon SES".
|
||||||
- ##PhabricatorMailImplementationPHPMailerLiteAdapter##: default, uses
|
- ##PhabricatorMailImplementationPHPMailerLiteAdapter##: default, uses
|
||||||
"sendmail", see "Adapter: Sendmail".
|
"sendmail", see "Adapter: Sendmail".
|
||||||
- ##PhabricatorMailImplementationPHPMailerAdapter##: uses SMTP, see
|
- ##PhabricatorMailImplementationPHPMailerAdapter##: uses SMTP, see
|
||||||
"Adapter: SMTP".
|
"Adapter: SMTP".
|
||||||
- ##PhabricatorMailImplementationAmazonSESAdapter##: use Amazon SES, see
|
|
||||||
"Adapter: Amazon SES".
|
|
||||||
- ##PhabricatorMailImplementationSendGridAdapter##: use SendGrid, see
|
- ##PhabricatorMailImplementationSendGridAdapter##: use SendGrid, see
|
||||||
"Adapter: SendGrid".
|
"Adapter: SendGrid".
|
||||||
- ##Some Custom Class You Write##: use a custom adapter you write, see
|
- ##Some Custom Class You Write##: use a custom adapter you write, see
|
||||||
|
@ -64,8 +71,8 @@ your configuration. Possible values are:
|
||||||
= Adapter: Sendmail =
|
= Adapter: Sendmail =
|
||||||
|
|
||||||
This is the default, and selected by choosing
|
This is the default, and selected by choosing
|
||||||
##PhabricatorMailImplementationPHPMailerLiteAdapter## as the value for
|
`PhabricatorMailImplementationPHPMailerLiteAdapter` as the value for
|
||||||
**metamta.mail-adapter**. This requires a 'sendmail' binary to be installed on
|
**metamta.mail-adapter**. This requires a `sendmail` binary to be installed on
|
||||||
the system. Most MTAs (e.g., sendmail, qmail, postfix) should do this, but your
|
the system. Most MTAs (e.g., sendmail, qmail, postfix) should do this, but your
|
||||||
machine may not have one installed by default. For install instructions, consult
|
machine may not have one installed by default. For install instructions, consult
|
||||||
the documentation for your favorite MTA.
|
the documentation for your favorite MTA.
|
||||||
|
@ -74,25 +81,35 @@ Since you'll be sending the mail yourself, you are subject to things like SPF
|
||||||
rules, blackholes, and MTA configuration which are beyond the scope of this
|
rules, blackholes, and MTA configuration which are beyond the scope of this
|
||||||
document. If you can already send outbound email from the command line or know
|
document. If you can already send outbound email from the command line or know
|
||||||
how to configure it, this option is straightforward. If you have no idea how to
|
how to configure it, this option is straightforward. If you have no idea how to
|
||||||
do any of this, consider using Amazon SES.
|
do any of this, strongly consider using Mailgun or Amazon SES instead.
|
||||||
|
|
||||||
= Adapter: SMTP =
|
= Adapter: SMTP =
|
||||||
|
|
||||||
For most situations of using SMTP to send email, you could actually use
|
You can use this adapter to send mail via an external SMTP server, like Gmail.
|
||||||
'sendmail' or 'postfix' to do it. But some SMTP server requires authentication
|
To do this, set these configuration keys:
|
||||||
and the 'sendmail' mailer doesn't work. If you want to try with postfix, for
|
|
||||||
install instructions, consult the documentation for postfix as MTA and you
|
|
||||||
could configure to use SMTP then.
|
|
||||||
|
|
||||||
To configure Phabricator to use SMTP, set these configuration keys:
|
|
||||||
|
|
||||||
- **metamta.mail-adapter**: set to
|
- **metamta.mail-adapter**: set to
|
||||||
"PhabricatorMailImplementationPHPMailerAdapter".
|
`PhabricatorMailImplementationPHPMailerAdapter`.
|
||||||
- **phpmailer.mailer**: set to "smtp".
|
- **phpmailer.mailer**: set to `smtp`.
|
||||||
- **phpmailer.smtp-host**: set to hostname of your smtp server.
|
- **phpmailer.smtp-host**: set to hostname of your SMTP server.
|
||||||
- **phpmailer.smtp-port**: set to port of your smtp server.
|
- **phpmailer.smtp-port**: set to port of your SMTP server.
|
||||||
- **phpmailer.smtp-user**: set to your username used for authentication.
|
- **phpmailer.smtp-user**: set to your username used for authentication.
|
||||||
- **phpmailer.smtp-password**: set to your password used for authentication.
|
- **phpmailer.smtp-password**: set to your password used for authentication.
|
||||||
|
- **phpmailer.smtp-protocol**: set to `tls` or `ssl` if necessary. Use
|
||||||
|
`ssl` for Gmail.
|
||||||
|
|
||||||
|
= Adapter: Mailgun =
|
||||||
|
|
||||||
|
Mailgun is an email delivery service. You can learn more at
|
||||||
|
<http://www.mailgun.com>. Mailgun isn't free, but is very easy to configure
|
||||||
|
and works well.
|
||||||
|
|
||||||
|
To use Mailgun, sign up for an account, then set these configuration keys:
|
||||||
|
|
||||||
|
- **metamta.mail-adapter**: set to
|
||||||
|
`PhabricatorMailImplementationMailgunAdapter`.
|
||||||
|
- **mailgun.api-key**: set to your Mailgun API key.
|
||||||
|
- **mailgun.domain**: set to your Mailgun domain.
|
||||||
|
|
||||||
= Adapter: Amazon SES =
|
= Adapter: Amazon SES =
|
||||||
|
|
||||||
|
@ -113,10 +130,6 @@ NOTE: Amazon SES **requires you to verify your "From" address**. Configure which
|
||||||
then follow the Amazon SES verification process to verify it. You won't be able
|
then follow the Amazon SES verification process to verify it. You won't be able
|
||||||
to send email until you do this!
|
to send email until you do this!
|
||||||
|
|
||||||
NOTE: Amazon SES is slow to accept mail (often 1-2 seconds) and application
|
|
||||||
performance will improve greatly if you configure outbound email to send in
|
|
||||||
the background.
|
|
||||||
|
|
||||||
= Adapter: SendGrid =
|
= Adapter: SendGrid =
|
||||||
|
|
||||||
SendGrid is an email delivery service like Amazon SES. You can learn more at
|
SendGrid is an email delivery service like Amazon SES. You can learn more at
|
||||||
|
@ -140,9 +153,9 @@ information easily by visiting <http://sendgrid.com/developer>.
|
||||||
|
|
||||||
You can provide a custom adapter by writing a concrete subclass of
|
You can provide a custom adapter by writing a concrete subclass of
|
||||||
@{class:PhabricatorMailImplementationAdapter} and setting it as the
|
@{class:PhabricatorMailImplementationAdapter} and setting it as the
|
||||||
**metamta.mail-adapter**.
|
`metamta.mail-adapter`.
|
||||||
|
|
||||||
TODO: This needs to be better documented once extending Phabricator is better
|
TODO: This should be better documented once extending Phabricator is better
|
||||||
documented.
|
documented.
|
||||||
|
|
||||||
= Adapter: Disable Outbound Mail =
|
= Adapter: Disable Outbound Mail =
|
||||||
|
@ -150,7 +163,7 @@ documented.
|
||||||
You can use the @{class:PhabricatorMailImplementationTestAdapter} to completely
|
You can use the @{class:PhabricatorMailImplementationTestAdapter} to completely
|
||||||
disable outbound mail, if you don't want to send mail or don't want to configure
|
disable outbound mail, if you don't want to send mail or don't want to configure
|
||||||
it yet. Just set **metamta.mail-adapter** to
|
it yet. Just set **metamta.mail-adapter** to
|
||||||
"PhabricatorMailImplementationTestAdapter".
|
`PhabricatorMailImplementationTestAdapter`.
|
||||||
|
|
||||||
= Testing and Debugging Outbound Email =
|
= Testing and Debugging Outbound Email =
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue