diff --git a/src/applications/metamta/constants/MetaMTAReceivedMailStatus.php b/src/applications/metamta/constants/MetaMTAReceivedMailStatus.php index ff01becec1..34bbe1826d 100644 --- a/src/applications/metamta/constants/MetaMTAReceivedMailStatus.php +++ b/src/applications/metamta/constants/MetaMTAReceivedMailStatus.php @@ -15,6 +15,8 @@ final class MetaMTAReceivedMailStatus const STATUS_NO_SUCH_OBJECT = 'err:not-found'; const STATUS_HASH_MISMATCH = 'err:bad-hash'; const STATUS_UNHANDLED_EXCEPTION = 'err:exception'; + const STATUS_EMPTY = 'err:empty'; + const STATUS_EMPTY_IGNORED = 'err:empty-ignored'; public static function getHumanReadableName($status) { $map = array( @@ -30,6 +32,8 @@ final class MetaMTAReceivedMailStatus self::STATUS_NO_SUCH_OBJECT => pht('No Such Object'), self::STATUS_HASH_MISMATCH => pht('Bad Address'), self::STATUS_UNHANDLED_EXCEPTION => pht('Unhandled Exception'), + self::STATUS_EMPTY => pht('Empty Mail'), + self::STATUS_EMPTY_IGNORED => pht('Ignored Empty Mail'), ); return idx($map, $status, pht('Processing Exception')); diff --git a/src/applications/metamta/replyhandler/PhabricatorMailReplyHandler.php b/src/applications/metamta/replyhandler/PhabricatorMailReplyHandler.php index 82adabbf05..eaa890ae37 100644 --- a/src/applications/metamta/replyhandler/PhabricatorMailReplyHandler.php +++ b/src/applications/metamta/replyhandler/PhabricatorMailReplyHandler.php @@ -46,81 +46,38 @@ abstract class PhabricatorMailReplyHandler { PhabricatorMetaMTAReceivedMail $mail); public function processEmail(PhabricatorMetaMTAReceivedMail $mail) { - $error = $this->sanityCheckEmail($mail); - - if ($error) { - if ($this->shouldSendErrorEmail($mail)) { - $this->sendErrorEmail($error, $mail); - } - return null; - } + $this->dropEmptyMail($mail); return $this->receiveEmail($mail); } - private function sanityCheckEmail(PhabricatorMetaMTAReceivedMail $mail) { - $body = $mail->getCleanTextBody(); + private function dropEmptyMail(PhabricatorMetaMTAReceivedMail $mail) { + $body = $mail->getCleanTextBody(); $attachments = $mail->getAttachments(); - if (empty($body) && empty($attachments)) { - return 'Empty email body. Email should begin with an !action and / or '. - 'text to comment. Inline replies and signatures are ignored.'; + if (strlen($body) || $attachments) { + return; } - return null; - } + // Only send an error email if the user is talking to just Phabricator. + // We can assume if there is only one "To" address it is a Phabricator + // address since this code is running and everything. + $is_direct_mail = (count($mail->getToAddresses()) == 1) && + (count($mail->getCCAddresses()) == 0); - /** - * Only send an error email if the user is talking to just Phabricator. We - * can assume if there is only one To address it is a Phabricator address - * since this code is running and everything. - */ - private function shouldSendErrorEmail(PhabricatorMetaMTAReceivedMail $mail) { - return (count($mail->getToAddresses()) == 1) && - (count($mail->getCCAddresses()) == 0); - } - - private function sendErrorEmail($error, - PhabricatorMetaMTAReceivedMail $mail) { - $template = new PhabricatorMetaMTAMail(); - $template->setSubject('Exception: unable to process your mail request'); - $template->setBody($this->buildErrorMailBody($error, $mail)); - $template->setRelatedPHID($mail->getRelatedPHID()); - $phid = $this->getActor()->getPHID(); - $handle = id(new PhabricatorHandleQuery()) - ->setViewer($this->getActor()) - ->withPHIDs(array($phid)) - ->executeOne(); - $tos = array($phid => $handle); - $mails = $this->multiplexMail($template, $tos, array()); - - foreach ($mails as $email) { - $email->saveAndSend(); + if ($is_direct_mail) { + $status_code = MetaMTAReceivedMailStatus::STATUS_EMPTY; + } else { + $status_code = MetaMTAReceivedMailStatus::STATUS_EMPTY_IGNORED; } - return true; - } - - private function buildErrorMailBody($error, - PhabricatorMetaMTAReceivedMail $mail) { - $original_body = $mail->getRawTextBody(); - - $main_body = <<addRawSection($main_body); - $body->addReplySection($this->getReplyHandlerInstructions()); - - return $body->render(); + throw new PhabricatorMetaMTAReceivedMailProcessingException( + $status_code, + pht( + 'Your message does not contain any body text or attachments, so '. + 'Phabricator can not do anything useful with it. Make sure comment '. + 'text appears at the top of your message: quoted replies, inline '. + 'text, and signatures are discarded and ignored.')); } public function supportsPrivateReplies() { diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php b/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php index 7767f1221e..638fd2f886 100644 --- a/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php +++ b/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php @@ -108,6 +108,9 @@ final class PhabricatorMetaMTAReceivedMail extends PhabricatorMetaMTADAO { // Don't send an error email back in these cases, since they're // very unlikely to be the sender's fault. break; + case MetaMTAReceivedMailStatus::STATUS_EMPTY_IGNORED: + // This error is explicitly ignored. + break; default: $this->sendExceptionMail($ex); break;