diff --git a/include/api.tickets.php b/include/api.tickets.php index f0758d5d2ea75324620ce12acbf30fe76222fb06..f030918493087fb71ddcddc339c493052376c7cc 100644 --- a/include/api.tickets.php +++ b/include/api.tickets.php @@ -39,7 +39,7 @@ class TicketApiController extends ApiController { if(!strcasecmp($format, 'email')) { $supported = array_merge($supported, array('header', 'mid', 'emailId', 'ticketId', 'reply-to', 'reply-to-name', - 'in-reply-to', 'references')); + 'in-reply-to', 'references', 'thread-type')); $supported['attachments']['*'][] = 'cid'; } diff --git a/include/class.mailparse.php b/include/class.mailparse.php index 0882fb3cd842e4a4be45f131d4fa4b3fc8f30f6e..3356cb9bf1a596272d3e46e9a2cb72dfc0c41ca5 100644 --- a/include/class.mailparse.php +++ b/include/class.mailparse.php @@ -169,6 +169,40 @@ class Mail_Parse { return Mail_Parse::parseAddressList($header); } + function isBounceNotice() { + if (!($body = $this->getPart($this->struct, 'message/delivery-status'))) + return false; + + $info = self::splitHeaders($body); + if (!isset($info['Action'])) + return false; + + return strcasecmp($info['Action'], 'failed') === 0; + } + + function getDeliveryStatusMessage() { + $ctype = @strtolower($this->struct->ctype_primary.'/'.$this->struct->ctype_secondary); + if ($ctype == 'multipart/report' + && isset($this->struct->ctype_parameters['report-type']) + && $this->struct->ctype_parameters['report-type'] == 'delivery-status' + ) { + return sprintf('<pre>%s</pre>', + Format::htmlchars( + $this->getPart($this->struct, 'text/plain', 1) + )); + } + return false; + } + + function getOriginalMessage() { + foreach ($this->struct->parts as $p) { + $ctype = $p->ctype_primary.'/'.$p->ctype_secondary; + if (strtolower($ctype) === 'message/rfc822') + return $p->parts[0]; + } + return null; + } + function getBody(){ global $cfg; @@ -394,16 +428,27 @@ class EmailDataParser { } } + if ($parser->isBounceNotice()) { + // Fetch the original References and assign to 'references' + if ($msg = $parser->getOriginalMessage()) + $data['references'] = $msg->headers['references']; + // Fetch deliver status report + $data['message'] = $parser->getDeliveryStatusMessage(); + $data['thread-type'] = 'N'; + } + else { + // Typical email + $data['message'] = Format::stripEmptyLines($parser->getBody()); + $data['in-reply-to'] = $parser->struct->headers['in-reply-to']; + $data['references'] = $parser->struct->headers['references']; + } + $data['subject'] = $parser->getSubject(); - $data['message'] = Format::stripEmptyLines($parser->getBody()); $data['header'] = $parser->getHeader(); $data['mid'] = $parser->getMessageId(); $data['priorityId'] = $parser->getPriority(); $data['emailId'] = $emailId; - $data['in-reply-to'] = $parser->struct->headers['in-reply-to']; - $data['references'] = $parser->struct->headers['references']; - if (($replyto = $parser->getReplyTo()) && !PEAR::isError($replyto)) { $replyto = $replyto[0]; $data['reply-to'] = $replyto->mailbox.'@'.$replyto->host;