如何在Symfony中通过Postmark使用不同消息流发送批量邮件
问题原因
- 手动添加的
X-PM-Message-Stream头部未生效,请求仍然走默认事务消息流:symfony/postmark-mailer组件会优先读取DSN配置的消息流自动生成对应头部,覆盖你手动添加的自定义头部,因此触发了事务流的限制规则。 - Postmark全类型消息流均限制单封邮件的To/CC/BCC总收件人数量不得超过50,即便成功切换到广播流,一次性将所有订阅者加入BCC也会触发报错。
解决方案
第一步:修复广播流不生效的问题
添加自定义头部前先移除组件自动生成的同名字段,避免被覆盖:
$headers = $email->getHeaders(); // 先移除已存在的流配置头部 if ($headers->has('X-PM-Message-Stream')) { $headers->remove('X-PM-Message-Stream'); } // 再添加自定义广播流配置 $headers->addTextHeader('X-PM-Message-Stream', 'broadcast');
操作前请先确认Postmark后台已创建名为broadcast的消息流,且当前使用的Token拥有该流的使用权限。
第二步:解决收件人超限问题
推荐两种实现方案,可按需选择:
方案1:分块批量发送(无个性化需求时使用)
将订阅者列表按每49个为一组拆分,每组生成一封单独邮件发送,留1个余量避免触达50的上限:
// 拆分订阅者列表 $subscriberChunks = array_chunk($subscribers, 49); foreach ($subscriberChunks as $chunk) { $email = (new TemplatedEmail()) ->from(new Address('emailaddress', 'Sitename')) ->subject('Subject line') ->htmlTemplate('email/post.html.twig') ->context([ 'postTitle' => $post_title, 'postContent' => $post_content_updated, 'profilePicture' => $user->getProfilePicture(), 'displayName' => $user->getDisplayName(), ]); foreach ($chunk as $subscriber) { $email->addBcc($subscriber->getEmail()); } // 配置广播流 $headers = $email->getHeaders(); if ($headers->has('X-PM-Message-Stream')) { $headers->remove('X-PM-Message-Stream'); } $headers->addTextHeader('X-PM-Message-Stream', 'broadcast'); $mailer->send($email); }
方案2:单用户单独发送(推荐,送达率更高)
为每个订阅者生成专属邮件,直接发送到用户收件箱,无需使用BCC,还可支持插入个性化内容,有效降低垃圾邮件判定概率:
foreach ($subscribers as $subscriber) { $email = (new TemplatedEmail()) ->from(new Address('emailaddress', 'Sitename')) ->to($subscriber->getEmail()) ->subject('Subject line') ->htmlTemplate('email/post.html.twig') ->context([ 'postTitle' => $post_title, 'postContent' => $post_content_updated, 'profilePicture' => $user->getProfilePicture(), 'displayName' => $user->getDisplayName(), // 可扩展添加订阅者专属个性化字段 'subscriberName' => $subscriber->getDisplayName(), ]); // 配置广播流 $headers = $email->getHeaders(); if ($headers->has('X-PM-Message-Stream')) { $headers->remove('X-PM-Message-Stream'); } $headers->addTextHeader('X-PM-Message-Stream', 'broadcast'); $mailer->send($email); }
如果订阅者量级较大,建议搭配Symfony Messenger队列异步发送,避免请求超时。
内容的提问来源于stack exchange,提问作者UXerUIer
相关产品推荐
相关产品推荐

