Installation:
composer require alexeyshockov/postman-bundle
Enable the bundle in AppKernel.php:
new Alexeyshockov\PostmanBundle\PostmanBundle(),
Configure MTA (Exim4 Example):
/etc/exim4/conf.d/router/postman) and transport (/etc/exim4/conf.d/transport/postman) as shown in the README.service exim4 restart.First Use Case:
user@example.com).postman:mail:handle command, triggering event listeners or processing logic.Email Ingestion:
/usr/bin/php /var/www/app/app/console postman:mail:handle
zetacomponents/mail for parsing raw email data.Event-Driven Processing:
PostmanBundle by subscribing to events (e.g., postman.mail.received).use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Alexeyshockov\PostmanBundle\Event\MailEvent;
class MyMailSubscriber implements EventSubscriberInterface {
public static function getSubscribedEvents() {
return ['postman.mail.received' => 'onMailReceived'];
}
public function onMailReceived(MailEvent $event) {
$mail = $event->getMail();
// Process email (e.g., parse attachments, extract text).
}
}
Reply Parsing:
willdurand/email-reply-parser to handle email threads/replies:
$parser = new \EmailReplyParser\Parser();
$isReply = $parser->isReply($mail->getRawMessage());
Storage/Logging:
MonologBundle:
# app/config/config.yml
monolog:
handlers:
mail_handler:
type: stream
path: "%kernel.logs_dir%/postman.log"
level: debug
Command Customization:
src/Alexeyshockov/PostmanBundle/Command/MailHandleCommand.php or extend it.MTA Configuration:
command in Exim’s transport fails to execute, emails are frozen. Test with:
chmod +x /usr/bin/php /var/www/app/app/console
www-data (or your MTA user) has read/write access to Symfony’s var/ directory.Email Parsing:
mb_convert_encoding() or iconv():
$rawMessage = mb_convert_encoding($rawMessage, 'UTF-8', 'ISO-8859-1');
zetacomponents/mail may struggle with large attachments. Stream files directly to storage:
$attachment = $mail->getAttachments()[0];
file_put_contents($path, $attachment->getContent());
Event Dispatcher:
public static function getSubscribedEvents() {
return ['postman.mail.received' => ['onMailReceived', 10]]; // Lower = higher priority
}
Debugging:
exim -d -bS < test@example.com
var/logs/postman.log for processing errors.Testing:
swiftmailer to simulate incoming emails in tests:
$mailer = $this->get('mailer');
$mailer->send($message);
MailHandleCommand in PHPUnit:
$command = $this->getMockBuilder('Alexeyshockov\PostmanBundle\Command\MailHandleCommand')
->disableOriginalConstructor()
->getMock();
Performance:
// In your listener:
if ($batchSize >= 100) {
$this->processBatch();
}
Security:
if (strpos($header, 'Content-Disposition: attachment') !== false) {
$filename = basename($header);
if (!preg_match('/^[a-z0-9_\-\.]+$/i', $filename)) {
throw new \RuntimeException('Invalid filename');
}
}
Extending:
Zeta\Mail\Message for domain-specific logic:
class AppMail extends \Zeta\Mail\Message {
public function isNewsletter() {
return strpos($this->getHeader('Subject'), 'Newsletter') !== false;
}
}
PostmanBundle to replace core behavior.Dependencies:
alexeyshockov/colada for queue-based processing if needed:
$queue = new \Colada\Queue();
$queue->push('process_email', [$mail->getId()]);
How can I help you explore Laravel packages today?