要给自己的树莓派语音助手增加一个收邮件的功能,在优快云上对比了pop3收邮件和imap收邮件的两种不同方案,最终选择用imap来收取163邮箱的邮件。代码如下:
# -*- coding: utf-8 -*-
import imaplib
import email
import re
class Email(object):
def __init__(self):
self.host = "imap.163.com"
# 163的imap服务
self.account = 'xxxx@163.com'
# 你的163邮箱
self.password = 'BXXXXXXXXXXX2'
# 这不是你的邮箱密码,是163邮箱开启imap服务后提供的授权码,有效期180天!!
self.server = self.login()
def login(self):
# 连接服务器:
server = imaplib.IMAP4(self.host)
server.login(self.account, self.password)
# 以下三行是为了解决网易邮箱报错
imaplib.Commands["ID"] = ('AUTH',)
args = ("name", self.account, "contact", self.account, "version", "1.0.0", "vendor", "myclient")
server._simple_command("ID", str(args).replace(",", "").replace("\'", "\""))
return server
def getMail(self, mail_box='INBOX', mail_type='UNSEEN'):
'''
收取邮件
:param mail_box: 选择邮箱,默认是INBOX(收件箱),其他选择还有Drafts(草稿箱)/Junk(垃圾箱)/Trash(已删除)/Sent Messages(已发送)
:param mail_type: 返回邮件类型,默认是UNSEEN(未读邮件),其他选择还有ALL(全部邮件)/SEEN(已读邮件)
:return: result
'''
result = []
self.server.select(mailbox=mail_box)
stat, data = self.server.search(None, mail_type)
if stat == 'OK':
count = len(data[0].split())
if count >0:
tp1 = '共有'+str(count)+'封邮件'
result.append(tp1)
mail_list = data[0].split()
# mail_list按照时间升序存储,最新的在最后
n = 1
for index in mail_list:
status, message = self.server.fetch(index, "(RFC822)")
if status == 'OK':
msg = email.message_from_bytes(message[0][1])
# 邮件日期
msg_date = email.header.decode_header(msg['Date'])[0][0]
# 邮件主题
msg_subject = email.header.decode_header(msg["Subject"])
subject = self.str_to_unicode(msg_subject[0][0], msg_subject[0][1])
# 发件人
msg_sender = email.header.decode_header(msg["From"])
sender = self.str_to_unicode(msg_sender[0][0], msg_sender[0][1])
# 邮件正文信息
content = self.parse_message(msg)
tp2 = '第'+ str(n) + '封邮件来自 ' + sender +' ,邮件主题: '+ subject + ',具体内容是:' + content
result.append(tp2)
n += 1
return result
@staticmethod
def str_to_unicode(s, encoding=None):
return str(s, encoding) if encoding else str(s)
@staticmethod
def parse_message(msg):
message_content = None
for part in msg.walk():
if not part.is_multipart():
if part.get_charsets() is None:
message_content = part.get_payload(decode=True)
else:
message_content = part.get_payload(decode=True).decode(part.get_charsets()[0])
# 下面两行是通过正则表达式,将html格式转换为纯文本
pat = re.compile('>(.*?)<')
msg_data = ''.join(pat.findall(str(message_content)))
return msg_data
请注意:因为我是要让语音助手播报邮件内容,所以上面代码在邮件正文内容部分做了html转纯文本的格式转换。
接下来,我就可以在rasa的actions.py中调用这个class,并最终实现语音助手收取最新邮件的功能了。相关代码我会在我的公众号“天飓”发布,感兴趣的朋友欢迎关注“天飓”。