diff --git a/src/applications/config/check/PhabricatorMailSetupCheck.php b/src/applications/config/check/PhabricatorMailSetupCheck.php index ff789d4aee..2b8e4e12d5 100644 --- a/src/applications/config/check/PhabricatorMailSetupCheck.php +++ b/src/applications/config/check/PhabricatorMailSetupCheck.php @@ -1,87 +1,100 @@ newIssue('config.metamta.mail-adapter') ->setShortName(pht('Missing Sendmail')) ->setName(pht('No Sendmail Binary Found')) ->setMessage($message) ->addRelatedPhabricatorConfig('metamta.mail-adapter'); } break; case 'PhabricatorMailImplementationAmazonSESAdapter': if (PhabricatorEnv::getEnvConfig('metamta.can-send-as-user')) { $message = pht( 'Amazon SES does not support sending email as users. Disable '. 'send as user, or choose a different mail adapter.'); $this->newIssue('config.can-send-as-user') ->setName(pht("SES Can't Send As User")) ->setMessage($message) ->addRelatedPhabricatorConfig('metamta.mail-adapter') ->addPhabricatorConfig('metamta.can-send-as-user'); } if (!PhabricatorEnv::getEnvConfig('amazon-ses.access-key')) { $message = pht( 'Amazon SES is selected as the mail adapter, but no SES access '. 'key is configured. Provide an SES access key, or choose a '. 'different mail adapter.'); $this->newIssue('config.amazon-ses.access-key') ->setName(pht('Amazon SES Access Key Not Set')) ->setMessage($message) ->addRelatedPhabricatorConfig('metamta.mail-adapter') ->addPhabricatorConfig('amazon-ses.access-key'); } if (!PhabricatorEnv::getEnvConfig('amazon-ses.secret-key')) { $message = pht( 'Amazon SES is selected as the mail adapter, but no SES secret '. 'key is configured. Provide an SES secret key, or choose a '. 'different mail adapter.'); $this->newIssue('config.amazon-ses.secret-key') ->setName(pht('Amazon SES Secret Key Not Set')) ->setMessage($message) ->addRelatedPhabricatorConfig('metamta.mail-adapter') ->addPhabricatorConfig('amazon-ses.secret-key'); } + if (!PhabricatorEnv::getEnvConfig('amazon-ses.endpoint')) { + $message = pht( + 'Amazon SES is selected as the mail adapter, but no SES endpoint '. + 'is configured. Provide an SES endpoint or choose a different '. + 'mail adapter.'); + + $this->newIssue('config.amazon-ses.endpoint') + ->setName(pht('Amazon SES Endpoint Not Set')) + ->setMessage($message) + ->addRelatedPhabricatorConfig('metamta.mail-adapter') + ->addPhabricatorConfig('amazon-ses.endpoint'); + } + $address_key = 'metamta.default-address'; $options = PhabricatorApplicationConfigOptions::loadAllOptions(); $default = $options[$address_key]->getDefault(); $value = PhabricatorEnv::getEnvConfig($address_key); if ($default === $value) { $message = pht( 'Amazon SES requires verification of the "From" address, but '. 'you have not configured a "From" address. Configure and verify '. 'a "From" address, or choose a different mail adapter.'); $this->newIssue('config.metamta.default-address') ->setName(pht('No SES From Address Configured')) ->setMessage($message) ->addRelatedPhabricatorConfig('metamta.mail-adapter') ->addPhabricatorConfig('metamta.default-address'); } break; } } } diff --git a/src/applications/config/option/PhabricatorAWSConfigOptions.php b/src/applications/config/option/PhabricatorAWSConfigOptions.php index faed807ae3..6647930859 100644 --- a/src/applications/config/option/PhabricatorAWSConfigOptions.php +++ b/src/applications/config/option/PhabricatorAWSConfigOptions.php @@ -1,66 +1,78 @@ newOption('amazon-ses.access-key', 'string', null) ->setLocked(true) ->setDescription(pht('Access key for Amazon SES.')), $this->newOption('amazon-ses.secret-key', 'string', null) ->setHidden(true) ->setDescription(pht('Secret key for Amazon SES.')), + $this->newOption('amazon-ses.endpoint', 'string', null) + ->setLocked(true) + ->setDescription( + pht( + 'SES endpoint domain name. You can find a list of available '. + 'regions and endpoints in the AWS documentation.')) + ->addExample( + 'email.us-east-1.amazonaws.com', + pht('US East (N. Virginia, Older default endpoint)')) + ->addExample( + 'email.us-west-2.amazonaws.com', + pht('US West (Oregon)')), $this->newOption('amazon-s3.access-key', 'string', null) ->setLocked(true) ->setDescription(pht('Access key for Amazon S3.')), $this->newOption('amazon-s3.secret-key', 'string', null) ->setHidden(true) ->setDescription(pht('Secret key for Amazon S3.')), $this->newOption('amazon-s3.region', 'string', null) ->setLocked(true) ->setDescription( pht( 'Amazon S3 region where your S3 bucket is located. When you '. 'specify a region, you should also specify a corresponding '. 'endpoint with `amazon-s3.endpoint`. You can find a list of '. 'available regions and endpoints in the AWS documentation.')) ->addExample('us-west-1', pht('USWest Region')), $this->newOption('amazon-s3.endpoint', 'string', null) ->setLocked(true) ->setDescription( pht( 'Explicit S3 endpoint to use. This should be the endpoint '. 'which corresponds to the region you have selected in '. '`amazon-s3.region`. Phabricator can not determine the correct '. 'endpoint automatically because some endpoint locations are '. 'irregular.')) ->addExample( 's3-us-west-1.amazonaws.com', pht('Use specific endpoint')), $this->newOption('amazon-ec2.access-key', 'string', null) ->setLocked(true) ->setDescription(pht('Access key for Amazon EC2.')), $this->newOption('amazon-ec2.secret-key', 'string', null) ->setHidden(true) ->setDescription(pht('Secret key for Amazon EC2.')), ); } } diff --git a/src/applications/metamta/adapter/PhabricatorMailImplementationAmazonSESAdapter.php b/src/applications/metamta/adapter/PhabricatorMailImplementationAmazonSESAdapter.php index 59c7b08933..5b03cd86ac 100644 --- a/src/applications/metamta/adapter/PhabricatorMailImplementationAmazonSESAdapter.php +++ b/src/applications/metamta/adapter/PhabricatorMailImplementationAmazonSESAdapter.php @@ -1,36 +1,37 @@ mailer->Mailer = 'amazon-ses'; $this->mailer->customMailer = $this; } public function supportsMessageIDHeader() { // Amazon SES will ignore any Message-ID we provide. return false; } /** * @phutil-external-symbol class SimpleEmailService */ public function executeSend($body) { $key = PhabricatorEnv::getEnvConfig('amazon-ses.access-key'); $secret = PhabricatorEnv::getEnvConfig('amazon-ses.secret-key'); + $endpoint = PhabricatorEnv::getEnvConfig('amazon-ses.endpoint'); $root = phutil_get_library_root('phabricator'); $root = dirname($root); require_once $root.'/externals/amazon-ses/ses.php'; - $service = new SimpleEmailService($key, $secret); + $service = new SimpleEmailService($key, $secret, $endpoint); $service->enableUseExceptions(true); return $service->sendRawEmail($body); } } diff --git a/src/docs/user/configuration/configuring_outbound_email.diviner b/src/docs/user/configuration/configuring_outbound_email.diviner index 55c51837c7..2a95f49bc3 100644 --- a/src/docs/user/configuration/configuring_outbound_email.diviner +++ b/src/docs/user/configuration/configuring_outbound_email.diviner @@ -1,200 +1,201 @@ @title Configuring Outbound Email @group config Instructions for configuring Phabricator to send mail. = Overview = Phabricator can send outbound email via several different providers, called "Adapters". | Send Mail With | Setup | Cost | Inbound | Notes | |---------|-------|------|---------|-------| | Mailgun | Easy | Cheap | Yes | Recommended | | Amazon SES | Easy | Cheap | No | Recommended | | SendGrid | Medium | Cheap | Yes | Discouraged (See Note) | | 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 options, sending mail via local SMTP is the default, but usually requires some configuration to get working. See below for details on how to select and configure a delivery method. 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. If you have some internal mail service you'd like to use you can also write a custom adapter, but this requires digging into the code. Phabricator sends mail in the background, so the daemons need to be running for it to be able to deliver mail. You should receive setup warnings if they are not. For more information on using daemons, see @{article:Managing Daemons with phd}. **Note on SendGrid**: Users have experienced a number of odd issues with SendGrid, compared to fewer issues with other mailers. We discourage SendGrid unless you're already using it. If you send to SendGrid via SMTP, you may need to adjust `phpmailer.smtp-encoding`. = Basics = Regardless of how outbound email is delivered, you should configure these keys in your configuration: - **metamta.default-address** determines where mail is sent "From" by default. If your domain is `example.org`, set this to something like `noreply@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, but see the documentation for details. = Configuring Mail Adapters = To choose how mail will be sent, change the `metamta.mail-adapter` key in 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 "sendmail", see "Adapter: Sendmail". - `PhabricatorMailImplementationPHPMailerAdapter`: uses SMTP, see "Adapter: SMTP". - `PhabricatorMailImplementationSendGridAdapter`: use SendGrid, see "Adapter: SendGrid". - `Some Custom Class You Write`: use a custom adapter you write, see "Adapter: Custom". - `PhabricatorMailImplementationTestAdapter`: this will **completely disable** outbound mail. You can use this if you don't want to send outbound mail, or want to skip this step for now and configure it later. = Adapter: Sendmail = This is the default, and selected by choosing `PhabricatorMailImplementationPHPMailerLiteAdapter` as the value for **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 machine may not have one installed by default. For install instructions, consult the documentation for your favorite MTA. 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 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 do any of this, strongly consider using Mailgun or Amazon SES instead. If you experience issues with mail getting mangled (for example, arriving with too many or too few newlines) you may try adjusting `phpmailer.smtp-encoding`. = Adapter: SMTP = You can use this adapter to send mail via an external SMTP server, like Gmail. To do this, set these configuration keys: - **metamta.mail-adapter**: set to `PhabricatorMailImplementationPHPMailerAdapter`. - **phpmailer.mailer**: set to `smtp`. - **phpmailer.smtp-host**: set to hostname 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-password**: set to your password used for authentication. - **phpmailer.smtp-protocol**: set to `tls` or `ssl` if necessary. Use `ssl` for Gmail. - **phpmailer.smtp-encoding**: Normally safe to leave as the default, but adjusting it may help resolve mail mangling issues (for example, mail arriving with too many or too few newlines). = Adapter: Mailgun = Mailgun is an email delivery service. You can learn more at . 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 = Amazon SES is Amazon's cloud email service. It is not free, but is easier to configure than sendmail and can simplify outbound email configuration. To use Amazon SES, you need to sign up for an account with Amazon at . To configure Phabricator to use Amazon SES, set these configuration keys: - **metamta.mail-adapter**: set to "PhabricatorMailImplementationAmazonSESAdapter". - **amazon-ses.access-key**: set to your Amazon SES access key. - **amazon-ses.secret-key**: set to your Amazon SES secret key. + - **amazon-ses.endpoint**: Set to your Amazon SES endpoint. NOTE: Amazon SES **requires you to verify your "From" address**. Configure which "From" address to use by setting "`metamta.default-address`" in your config, then follow the Amazon SES verification process to verify it. You won't be able to send email until you do this! = Adapter: SendGrid = SendGrid is an email delivery service like Amazon SES. You can learn more at . It is easy to configure, but not free. You can configure SendGrid in two ways: you can send via SMTP or via the REST API. To use SMTP, just configure `sendmail` and leave Phabricator's setup with defaults. To use the REST API, follow the instructions in this section. To configure Phabricator to use SendGrid, set these configuration keys: - **metamta.mail-adapter**: set to "PhabricatorMailImplementationSendGridAdapter". - **sendgrid.api-user**: set to your SendGrid login name. - **sendgrid.api-key**: set to your SendGrid password. If you're logged into your SendGrid account, you may be able to find this information easily by visiting . = Adapter: Custom = You can provide a custom adapter by writing a concrete subclass of @{class:PhabricatorMailImplementationAdapter} and setting it as the `metamta.mail-adapter`. TODO: This should be better documented once extending Phabricator is better documented. = Adapter: Disable Outbound Mail = 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 it yet. Just set **metamta.mail-adapter** to `PhabricatorMailImplementationTestAdapter`. = Testing and Debugging Outbound Email = You can use the `bin/mail` utility to test, debug, and examine outbound mail. In particular: phabricator/ $ ./bin/mail list-outbound # List outbound mail. phabricator/ $ ./bin/mail show-outbound # Show details about messages. phabricator/ $ ./bin/mail send-test # Send test messages. Run `bin/mail help ` for more help on using these commands. You can monitor daemons using the Daemon Console (`/daemon/`, or click **Daemon Console** from the homepage). = Next Steps = Continue by: - @{article:Configuring Inbound Email} so users can reply to email they receive about revisions and tasks to interact with them; or - learning about daemons with @{article:Managing Daemons with phd}; or - returning to the @{article:Configuration Guide}.