前言:
公司最近要做一个库存预警的定时任务,当库存低于或者高于一定的数量时,系统自动发送邮件给相关人员,而我公司的odoo设置的不是私人的发件服务器,而是设置了域名,实在搜不到解决方案的我决定参悟一下源码,虽然并没有全部看懂,但也会了个大概
1、系统参数配置和发件服务器配置
1.1 最简单的发件服务器配置
配置之前准备工作:自己先开通邮箱服务,不管是网易还是QQ或者其他邮箱
依次点击 技术-->发件服务器-->创建
其中三个重要的参数就是 smtp服务器地址
以QQ邮箱为例:stmp服务器地址是:smtp.qq.com
不同的smtp服务器和它所对应的地址可以百度搜到
然后用户名是邮箱账号,密码是邮箱的授权码
当所有信息输入完成之后,点击测试连接可以看到自己配置是否成功。
1.2 代发服务器配置
进入系统参数,筛选mail
mail.catchall.domain : 设置收发邮箱的域名,默认就是@后面的部分,不设置的话就是简单的发送模式,发件人与所配置的账号相同. |
mail.bounce.alias:值为bounce,表示反弹发送,在mail.catchall.domain使用的同时,开启代理发送 |
同时设置mail.bounce.alias和mail.catchall.domain,设置的值如下所示:
mail.bounce.alias: postmaster-odoo
mail.catchall.domain: dcmanufacture.com
邮件的授权账号就是:postmaster-odoo@dcmanufacture.com,在发件服务器就要做相应的配置
注意:以代理的方式配置发件服务器后点击测试连接报错是正常的
邮件的代发人就是:“postmaster-odoo+mail.id@dcmanufacture.com”
其中的 mail.id 指的是创建的mail.mail模型的id
代发人的来源需要分析源码:odoo/addons/mail/models/mail_mail.py
也就是通过设置的这几个不同的参数构造headers
2、分析源码创建定时任务
依次点击 技术-->Email-->创建,
从中我们可以看到原生的email发送过程,直接从页面创建就行,但是这个往往无法满足我们定时任务的需求。
页面分析:
这个页面所用的模型时mail.mail,立即发送对应的python方法是send
于是去源码里面搜索 _name = 'mail.mail',进入这个模型,我们在模型定义的时候可以看到
_inherits = {'mail.message': 'mail_message_id'},委托继承,就相当于res_users与res_partners的关系。后续的发送邮件会用到一个message_id的参数,就是来自mail.message这个模型。
然后搜索def send 找到发送邮件的方法:
可以看到这个方法获取了所有要发送的邮件的id,用某种加密算法生成了一个smtp_session,
然后调用 _send方法进行邮件发送。
我们进入到_send方法:
最终发送邮件用的是ir.mail_server这个模型中的send方法,其他的无非就是传一些参数。
通过观察,我们可以看到这几个重要的参数:headers,mail_server_id,smtp_session,message_id
其他参数其实都挺好理解
2.1、发件方式一(直接用不配置域名的私人服务器):
代码如下所示:
ir_mail_server = self.env['ir.mail_server'].search([("id",'=',2)], order='sequence asc', limit=1)
message = 'hello world!'
email = self.env['ir.mail_server'].build_email(
email_from=ir_mail_server.smtp_user,
# 发送至
email_to=['xxx'],
subject=_('节日问候'),
body=_(message),
)
ir_mail_server.send_email(email)
ir.mail_server就是你所配置的发件服务器的模型,这种方式创建邮件比较简单。
2.2、发件方式二(使用代理,并且使用mail.mail模型):
这样在发送邮件之后会有一个记录在 设置-->email里面
message = '库存数量有误,请及时调整!'
# 返回一个session对象,具有时效性
smtp_session = self.env['ir.mail_server'].connect(mail_server_id=False)
# 创建 mail.mail
mail = self.env['mail.mail'].create(
{'subject': '库存警告', 'email_to': '1163799797@qq.com\n2794998378@qq.com', 'state': 'outgoing',
'auto_delete': True})
# 构造headers参数,28094是mail.mail的id,其实就是代发人
headers = {'Return-Path': 'postmaster-odoo+%s@dcmanufacture.com' % mail.id}
email = self.env['ir.mail_server'].build_email(
# 发件人
email_from='xxx',
# 发送至
email_to=[mail.email_to],
subject=_(mail.subject),
body=_(message),
message_id=mail.mail_message_id.message_id, # 必填
headers=headers
)
self.env['ir.mail_server'].send_email(email, mail_server_id=False, smtp_session=smtp_session)
其中的难点无非就是参数的设置,在创建mail 的时候,会自动生成一个加密的message_id,通过mail_message_id.message_id来获取
相关问题欢迎各位小伙伴留言!