auto-submitted header usage

This commit is contained in:
Yuri Kuznetsov
2025-08-18 13:00:03 +03:00
parent 5c0d6fa9e8
commit 5d35bde5b7
8 changed files with 50 additions and 17 deletions
@@ -31,7 +31,6 @@ namespace Espo\Core\Mail\Account\GroupAccount\Hooks;
use Espo\Core\Name\Field;
use Espo\Core\Name\Link;
use Laminas\Mail\Message;
use Espo\Core\Mail\Account\GroupAccount\AccountFactory as GroupAccountFactory;
use Espo\Core\Mail\SenderParams;
@@ -97,7 +96,7 @@ class AfterFetch implements AfterFetchInterface
}
if ($account->createCase()) {
if ($beforeFetchResult->get('isAutoReply')) {
if ($beforeFetchResult->get('isAutoSubmitted')) {
return;
}
@@ -117,7 +116,10 @@ class AfterFetch implements AfterFetchInterface
}
if ($account->autoReply()) {
if ($beforeFetchResult->get('skipAutoReply')) {
if (
$beforeFetchResult->get('isAutoSubmitted') ||
$beforeFetchResult->get('skipAutoReply')
) {
return;
}
@@ -75,7 +75,7 @@ class BeforeFetch implements BeforeFetchInterface
return BeforeFetchResult::create()
->with('skipAutoReply', $this->checkMessageCannotBeAutoReplied($message))
->with('isAutoReply', $this->checkMessageIsAutoReply($message));
->with('isAutoSubmitted', $this->checkMessageIsAutoSubmitted($message));
}
private function processBounced(Message $message): bool
@@ -127,16 +127,23 @@ class BeforeFetch implements BeforeFetchInterface
private function checkMessageIsAutoReply(Message $message): bool
{
if ($this->checkMessageIsAutoSubmitted($message)) {
return true;
}
return $this->autoReplyDetector->detect($message);
}
private function checkMessageCannotBeAutoReplied(Message $message): bool
{
if ($message->getHeader('X-Auto-Response-Suppress') === 'AutoReply') {
if (
$message->getHeader('X-Auto-Response-Suppress') === 'AutoReply' ||
$message->getHeader('X-Auto-Response-Suppress') === 'All'
) {
return true;
}
if ($message->getHeader('X-Auto-Response-Suppress') === 'All') {
if ($this->checkMessageIsAutoSubmitted($message)) {
return true;
}
@@ -146,4 +153,14 @@ class BeforeFetch implements BeforeFetchInterface
return false;
}
private function checkMessageIsAutoSubmitted(Message $message): bool
{
if ($this->autoReplyDetector->detect($message)) {
return true;
}
return $message->getHeader('Auto-Submitted') &&
strtolower($message->getHeader('Auto-Submitted')) !== 'no';
}
}
@@ -44,8 +44,8 @@ class DefaultAutoReplyDetector implements AutoReplyDetector
}
if (
$message->getHeader('Auto-submitted') &&
strtolower($message->getHeader('Auto-submitted')) !== 'no'
$message->getHeader('Auto-Submitted') &&
strtolower($message->getHeader('Auto-Submitted')) === 'auto-replied'
) {
return true;
}
+6 -2
View File
@@ -305,7 +305,7 @@ class Sender
$params = array_merge($this->params, $this->overrideParams);
$this->applyHeaders($message);
$this->applyHeaders($email, $message);
$this->applyFrom($email, $message, $params);
$this->addRecipientAddresses($email, $message);
$this->applyReplyTo($email, $message, $params);
@@ -589,7 +589,7 @@ class Sender
$message->subject($email->getSubject() ?? '');
}
private function applyHeaders(Message $message): void
private function applyHeaders(Email $email, Message $message): void
{
foreach ($this->headers as $item) {
$message->getHeaders()->addTextHeader($item[0], $item[1]);
@@ -605,6 +605,10 @@ class Sender
$message->getHeaders()->addTextHeader($it->getFieldName(), $it->getFieldValue());
}
}
if ($email->isAutoReply() && !$message->getHeaders()->has('Auto-Submitted')) {
$message->getHeaders()->addTextHeader('Auto-Submitted', 'auto-replied');
}
}
private function prepareEnvelope(Message $message): ?Envelope
@@ -43,6 +43,7 @@ class DefaultMessageHeadersPreparator implements MessageHeadersPreparator
{
$headers->addTextHeader('X-Queue-Item-Id', $data->getId());
$headers->addTextHeader('Precedence', 'bulk');
$headers->addTextHeader('Auto-Submitted', 'auto-generated');
$this->addMandatoryOptOut($headers, $data);
}
@@ -339,8 +339,7 @@ class Processor
$subject = $this->getHtmlizer()->render($note, $subjectTpl, 'mention-email-subject', $data, true);
$body = $this->getHtmlizer()->render($note, $bodyTpl, 'mention-email-body', $data, true);
/** @var Email $email */
$email = $this->entityManager->getNewEntity(Email::ENTITY_TYPE);
$email = $this->entityManager->getRDBRepositoryByClass(Email::class)->getNew();
$email
->setSubject($subject)
@@ -365,10 +364,15 @@ class Processor
}
}
$sender = $this->emailSender
->withParams($senderParams);
if ($note->getType() !== Note::TYPE_POST) {
$sender = $sender->withAddedHeader('Auto-Submitted', 'auto-generated');
}
try {
$this->emailSender
->withParams($senderParams)
->send($email);
$sender->send($email);
} catch (Exception $e) {
$this->log->error("Email notification: {$e->getMessage()}", ['exception' => $e]);
}
@@ -218,6 +218,7 @@ class ConfirmationSender
}
$sender
->withAddedHeader('Auto-Submitted', 'auto-generated')
->withAttachments($emailData->getAttachmentList())
->send($email);
}
@@ -88,7 +88,9 @@ class Sender
->setSubject($subject)
->setBody($body);
$this->createSender()->send($email);
$this->createSender()
->withAddedHeader('Auto-Submitted', 'auto-generated')
->send($email);
}
/**
@@ -127,7 +129,9 @@ class Sender
->setBody($body)
->addToAddress($emailAddress);
$this->createSender()->send($email);
$this->createSender()
->withAddedHeader('Auto-Submitted', 'auto-generated')
->send($email);
}
private function createSender(): EmailSenderSender