Fuglu插件中如何向发件人发送自定义退信消息?
关于Fuglu插件自定义退信消息的问题及解决办法
问题1:Fuglu 0.10版本中同时处理允许/拒绝收件人列表的逻辑问题
问题描述
维护允许/拒绝收件人列表时,尝试向拒绝列表收件人发送退信,同时向允许列表收件人投递邮件,但因邮件处理流程只能返回一个状态值,当前代码逻辑存在冲突,导致允许列表的邮件无法正常投递。
现有代码
if allow_group_list: suspect.recipients = allow_group_list self._logger().info( '888 ==== allowed suspect.recipients: %s' %(suspect.recipients)) if deny_group_list: suspect.recipients = deny_group_list self._logger().info( '9999 ====== denied suspect.recipients: %s' %(suspect.recipients)) self.send_bounce_message(suspect,deny_group_list,msubject) self._mark_bounce_sent(message_id, deny_group_list,msubject) return REJECT return DUNNO def send_bounce_message(self, suspect,mto,msubject): blockinfo = 'Please add the specific user and resend' queueid = suspect.get_tag('specificuser.bounce.queueid') #suspect.set_tag(mto_address,suspect.recipient) if queueid: self._logger().info( f'{suspect.id} already sent specific user block bounce ' f'to {suspect.from_address} with queueid {queueid}') else: #tmm self._logger().info(f"{suspect.id} sending specific user block " f"bounce to {suspect.from_address}") bounce = Bounce(self.config) queueid = bounce.send_template_file(suspect.from_address, self.template_bounce, suspect, {'blockinfo':blockinfo, 'mto':mto, 'msubject':msubject }) suspect.set_tag('specificuser.bounce.queueid', queueid)
问题分析
- 若同时存在允许和拒绝列表,代码会先将
suspect.recipients设为允许列表,随后又覆盖为拒绝列表,最终返回REJECT,导致允许列表的邮件也被拒绝。 - 手动调用退信方法后直接返回
REJECT,终止了后续流程,允许列表的邮件无法进入投递环节。
解决方案
拆分收件人处理逻辑,分离允许列表的投递和拒绝列表的退信操作:
# 从原始收件人中拆分允许/拒绝列表 original_recipients = suspect.recipients.copy() # 替换为你的实际允许/拒绝数据源 allow_group_list = [rcpt for rcpt in original_recipients if rcpt in self.allowed_list] deny_group_list = [rcpt for rcpt in original_recipients if rcpt in self.denied_list] if allow_group_list: suspect.recipients = allow_group_list self._logger().info('888 ==== allowed suspect.recipients: %s' % suspect.recipients) if deny_group_list: self._logger().info('9999 ====== denied recipients to bounce: %s' % deny_group_list) # 逐个处理拒绝收件人,避免重复退信 for rcpt in deny_group_list: bounce_tag = f'specificuser.bounce.{rcpt}' queueid = suspect.get_tag(bounce_tag) if not queueid: self._logger().info(f"{suspect.id} sending bounce to {suspect.from_address} for {rcpt}") bounce = Bounce(self.config) queueid = bounce.send_template_file( suspect.from_address, self.template_bounce, suspect, {'blockinfo': 'Please add the specific user and resend', 'mto': rcpt, 'msubject': msubject }) suspect.set_tag(bounce_tag, queueid) self._mark_bounce_sent(message_id, [rcpt], msubject) # 返回DUNNO让Fuglu继续处理允许列表的邮件投递 return DUNNO
问题2:Fuglu 1.2版本中发件人给自己发邮件时未收到退信
问题描述
编写插件维护允许/拒绝列表,当收件人在拒绝列表时返回REJECT和自定义消息,但发件人another@y.com给自己发送邮件时,未收到预期的退信。
现有配置及代码
fuglu.conf配置
plugins=custom_msg disablebounces=0 [PluginAlias] custom_msg=custom_msg.CustomMessagePlugin
custom_msg.py代码
from fuglu.shared import ScannerPlugin, DUNNO, DELETE, Suspect, REJECT class CustomMessagePlugin(ScannerPlugin): def __init__(self, *args, **kwargs): ScannerPlugin.__init__(self, *args, **kwargs) self.allowed_recipients = ['test9@y.com'] self.denied_recipients = ['test8@y.com','another@y.com'] def examine(self, suspect): sender = suspect.from_address.lower() recipient = suspect.recipients[0].lower() if recipient in self.denied_recipients: # Send bounce message to the sender bounce_message = "Your email to {} has been rejected.".format(recipient) return REJECT, bounce_message else: return DUNNO def lint(self): return def __str__(self): return "Custom Plugin"
问题分析
- Fuglu默认可能会跳过发件人与收件人相同的退信,避免循环退信。
- 仅处理第一个收件人,若存在多收件人场景会遗漏;同时返回
REJECT的自定义消息是否触发内置退信,需确认版本行为。
解决方案
修改插件逻辑,手动发送退信并处理所有收件人:
from fuglu.shared import ScannerPlugin, DUNNO, REJECT, Bounce class CustomMessagePlugin(ScannerPlugin): def __init__(self, *args, **kwargs): ScannerPlugin.__init__(self, *args, **kwargs) self.allowed_recipients = ['test9@y.com'] self.denied_recipients = ['test8@y.com','another@y.com'] def examine(self, suspect): sender = suspect.from_address.lower() denied_recipients = [] # 遍历所有收件人,筛选拒绝列表项 for rcpt in suspect.recipients: rcpt_lower = rcpt.lower() if rcpt_lower in self.denied_recipients: denied_recipients.append(rcpt) if denied_recipients: bounce_msg = "Your email to the following recipients has been rejected: {}".format(', '.join(denied_recipients)) # 手动发送退信,强制处理发件人等于收件人的场景 bounce = Bounce(self.config) bounce.send(sender, bounce_msg, suspect) # 保留未被拒绝的收件人继续投递 suspect.recipients = [rcpt for rcpt in suspect.recipients if rcpt not in denied_recipients] # 无有效收件人则返回REJECT,否则返回DUNNO继续处理 return REJECT, bounce_msg if not suspect.recipients else DUNNO else: return DUNNO def lint(self): return def __str__(self): return "Custom Plugin"
Fuglu退信自定义的技术支持获取途径
- 查看Fuglu本地部署的内置文档或源码中的
docs、README目录; - 参考Fuglu源码中的内置插件实现,学习官方的退信处理逻辑;
- 查阅
fuglu.conf配置文件的注释,了解退信相关配置项的作用; - 参与项目代码托管平台的社区讨论,获取其他开发者的经验分享。
内容的提问来源于stack exchange,提问作者user956424
相关产品推荐
相关产品推荐

