/** * Check if message is autoryply * * @param Mzax_Bounce_Message $message * @return boolean */ public function isAutoReply(Mzax_Bounce_Message $message) { if ($header = $message->searchHeader(self::$headers)) { $message->info('autoreply_header', $header); return true; } $subject = trim($message->getSubject()); if (!$subject) { return false; } foreach (self::$subjects as $needle) { if (stripos($subject, $needle) === 0) { $message->info('autoreply_subject', $needle); return true; } } foreach (self::$regex as $regex) { if (preg_match("/{$regex}/i", $subject, $matches)) { $message->info('autoreply_subject', $matches[0]); return true; } } // bit more aggressive, check the acctual content $body = $message->asString(); $body = preg_replace('/[\\s]+/', ' ', $body); foreach (self::$body as $needle) { if (stripos($subject, $needle) === 0) { $message->info('autoreply_body', $needle); return true; } } return false; }
/** * Try to detect the original recipiet id and campaign id * * * (non-PHPdoc) * @see Mzax_Bounce_Detector_Abstract::inspect() */ public function inspect(Mzax_Bounce_Message $message) { $to = strtolower($this->findEmail($message->getHeader('to'))); if ($store = $this->getStoreByEmail($to)) { $message->info('store_id', $store->getId()); } }
/** * * (non-PHPdoc) * @see Mzax_Bounce_Detector_Abstract::inspect() */ public function inspect(Mzax_Bounce_Message $message) { $subject = trim($message->getSubject()); if (preg_match('/^Unsubscribe ([^\\s]+) \\(([0-9A-Z]+)\\)$/i', $subject, $matches)) { $email = $matches[1]; $hash = $matches[2]; /* @var $recipient Mzax_Emarketing_Model_Recipient */ $recipient = Mage::getModel('mzax_emarketing/recipient')->loadByBeacon($hash); if ($recipient->getId()) { $recipient->prepare(); if (strtolower($recipient->getAddress()) == strtolower($email)) { $message->info('recipient_id', $recipient->getId(), 200); $message->info('campaign_id', $recipient->getCampaignId(), 200); $message->info('recipient', $email, 200); $message->info(Mzax_Bounce::TYPE_UNSUBSCRIBE, true); $message->info('type', Mzax_Bounce::TYPE_UNSUBSCRIBE); $storeId = Mage::getResourceSingleton('mzax_emarketing/recipient')->getStoreId($recipient->getId()); if ($storeId) { $message->info('store_id', $storeId, 100); } return true; // stop } } } }
public function inspect(Mzax_Bounce_Message $message) { if ($message->type !== self::REPORT) { return false; } if ($message->getContentType('report-type') !== self::FEEDBACK) { return false; } $part = $message->getMimePart('message/feedback-report'); if (!$part) { return false; } $report = $part->getDecodedHash(); if (!is_array($report)) { return false; } $message->info(Mzax_Bounce::TYPE_ARF, true); $message->info('status', self::STATUS); $message->info('type', Mzax_Bounce::TYPE_ARF); // abuse|froud|virus|other|not-spam if (isset($report['feedback-type'])) { $feedbackType = $report['feedback-type']; $message->info('feedback-type', $feedbackType); } if (isset($report['removal-recipient'])) { $recipient = $this->findEmail($report['removal-recipient']); $message->info('recipient', $recipient); } else { if (isset($report['original-rcpt-to'])) { $recipient = $this->findEmail($report['original-rcpt-to']); $message->info('recipient', $recipient); } } /* * If we still have no recipient, look for our * old orignal message and get it from the To header */ if (!$message->info('recipient')) { // check for embedded rfc822 message if ($rfc822 = $message->getMimePart('message/rfc822')) { $recipient = $this->findEmail($rfc822->getHeader('to')); $message->info('recipient', $recipient); } } return true; }
public function inspect(Mzax_Bounce_Message $message) { // Check for Hotmail Abuse Feedback Message if ($recipient = $message->getHeader('X-HmXmrOriginalRecipient')) { $message->info('feedback-type', 'abuse'); $message->info('status', Mzax_Bounce_Detector_Arf::STATUS); $message->info('type', Mzax_Bounce::TYPE_ARF); $message->info('recipient', $recipient, 10); $message->info('hotmail_fbl', true); return; } // Check for Hotmail Abuse Feedback Message in embedded message if ($rfc822 = $message->getMimePart('message/rfc822')) { $hash = $rfc822->getDecodedHash(); if (isset($hash['x-hmxmroriginalrecipient'])) { $recipient = $hash['x-hmxmroriginalrecipient']; $message->info('feedback-type', 'abuse'); $message->info('status', Mzax_Bounce_Detector_Arf::STATUS); $message->info('type', Mzax_Bounce::TYPE_ARF); $message->info('recipient', $recipient, 10); $message->info('hotmail_fbl', $rfc822); } } }
public function inspect(Mzax_Bounce_Message $message) { if ($message->type !== self::REPORT) { return false; } if ($message->getContentType('report-type') !== self::DELIVERY_STATUS) { return false; } $part = $message->getMimePart('message/delivery-status'); if (!$part) { return false; } $status = $part->getDecodedHash(); if (!is_array($status)) { return false; } $message->info('rfc1892', true); $message->info('type', Mzax_Bounce::TYPE_BOUNCE); // @see https://ohse.de/uwe/rfc/rfc1894.html#2.3.4 if (isset($status['status'])) { if (preg_match(self::STATUS_REGEX, $status['status'], $matches)) { $message->info('status', $matches[1]); } else { $message->info('status', $status['status']); } } else { $message->info('status', self::DEFAULT_STATUS); } // @see https://ohse.de/uwe/rfc/rfc1894.html#2.3.1 if (isset($status['original-recipient'])) { // address-type ; generic-address $recipient = $this->findEmail($status['original-recipient']); $message->info('recipient', $recipient); } else { if (isset($status['final-recipient'])) { // address-type ; generic-address $recipient = $this->findEmail($status['final-recipient']); $message->info('recipient', $recipient); } } // @see https://ohse.de/uwe/rfc/rfc1894.html#2.2.1 if (isset($status['original-envelope-id'])) { $envelopeId = $status['original-envelope-id']; $message->info('envelope_id', $envelopeId); } }
public function isAutoReply(Mzax_Bounce_Message $message) { if ($header = $message->searchHeader(self::$headers)) { $message->info('autoreply_header', $header); return true; } $subject = trim($message->getSubject()); if (!$subject) { return false; } foreach (self::$subjects as $needle) { if (stripos($subject, $needle) === 0) { $message->info('autoreply_subject', $needle); return true; } } foreach (self::$regex as $regex) { if (preg_match("/{$regex}/i", $subject, $matches)) { $message->info('autoreply_subject', $matches[0]); return true; } } return false; }
public function detectStatus(Mzax_Bounce_Message $message) { $body = $message->asString(); $body = strtolower($body); $body = preg_replace('/[\\s]+/', ' ', $body); $RFC3463 = self::RFC3463_CODE; $RFC2821 = self::RFC2821_CODE; // e.g. 421 #4.7.0 | 421-4.7.1/ if (preg_match("/{$RFC2821}[- ]#?({$RFC3463})/i", $body, $matches)) { $message->info('found_phrase', strtolower($matches[0])); return $matches[1]; } // e.g. Diagnostic-Code: smtp; 41 4.5.12 if (preg_match("/diagnostic[- ]code: smtp; ?\\d\\d\\ ({$RFC3463})/i", $body, $matches)) { $message->info('found_phrase', strtolower($matches[0])); return $matches[1]; } // e.g. Status: 4.5.12 if (preg_match("/status: ({$RFC3463})/i", $body, $matches)) { $message->info('found_phrase', strtolower($matches[0])); return $matches[1]; } // Use common phrases to detect status code foreach (self::getPhrases() as $sort => $phrasesByCodes) { foreach ($phrasesByCodes as $code => $phrases) { foreach ($phrases as $phrase) { if (stripos($body, $phrase) !== false) { $message->info('found_phrase', strtolower($phrase)); $message->info('found_phrase_sort', $sort); return $code; } } } } // https://tools.ietf.org/html/rfc3463#section-2 if (preg_match("/\\W({$RFC3463})\\W/", $body, $matches)) { $message->info('found_phrase', strtolower($matches[0])); return $matches[1]; } // search for RFC2821 return code // thanks to mark.tolman@gmail.com // Maybe at some point it should have it's own place within the main parsing scheme (at line 88) if (preg_match("/\\]?: ({$RFC2821}) /", $body, $matches) || preg_match("/^({$RFC2821}) (?:.*?)(?:denied|inactive|deactivated|rejected|disabled|unknown|no such|not (?:our|activated|a valid))+/i", $body, $matches)) { // map RFC2821 -> RFC3463 codes $map = array('5.1.1' => '550, 551, 553, 554', '4.2.2' => '452, 552', '4.3.2' => '450, 421'); foreach ($map as $convert => $values) { if (strpos($values, $matches[1]) !== false) { return $convert; } } } return self::DEFAULT_STATUS; }