邮件发送是一种很常见的应用场景,特别是在企业应用中。
实际开发中,这块宜独立抽取为公共的方法进行实现,将样式、结构统一处理。下面以Python为例进行简单的介绍:
1,邮件内容分析:
一般的邮件,我们可以将展示的内容分为如下5个部分:
subject,greeting,content,list_data和footer。
2,样式常量定义
const.MAIL_FOOTER = (u"P.S.
" u"本邮件由【堡垒机(CloudSecureMgmt, CSM)】自动发送,如有疑问," u"请加堡垒机eSpace沟通群:12345678 进行咨询。
" u"This mail is sent by CSM system automatically, if any questions, " u"please contact us by joining eSpace group: 12345678 for further learn.") const.MAIL_CSM_ADDRESS = u"堡垒机地址:https://csm.demo.com.
" const.MAIL_TITLE = u"【堡垒机(CSM)知会】" const.MAIL_OUTER_TABLE_STYLE = \ u'align="left" border="0" cellpadding="5" cellspacing="0" width="100%" style="border-collapse: collapse;"' const.MAIL_INNER_TABLE_STYLE = \ u'align="left" border="3" cellpadding="5" cellspacing="0" style="border-collapse: collapse;margin-left:-5px;"'
3, 底层邮件发送方法:
def send_mail(mail_title, mail_msg, mail_to): """ 发送邮件信息 :param mail_title: 邮件标题 :param mail_msg: 邮件内容 :param mail_to: 收件人 :return: True or False """ try: msg = EmailMessage(mail_title, mail_msg, EMAIL_HOST_USER, mail_to) msg.content_subtype = "html" msg.send() return True except Exception as e: logger.error(u"邮件发送失败, 错误信息: {}".format(e)) return False
4,列表展示的HTML生成代码:
def build_mail_table(show_name_list, data): """ 返回数据展示的HTML表格代码 :param: show_name_list: 对外展示的表头名称列表 data: 要展示的数据,格式为[tuple] """ show_name_list.insert(0, u"序号") for i in range(len(data)): temp_data = list(data[i]) temp_data.insert(0, i + 1) data[i] = temp_data html_table = u"".format(table_style=const.MAIL_INNER_TABLE_STYLE) html_table = u"".join( [html_table, u"".join([u"
"]) return html_table{} ".format(name) for name in show_name_list]), u""]) table_content = u"".join([u"{row_content} ".format( row_content=u"".join([u"{cell_content} ".format( cell_content=u"{}".format( value)) for value in item])) for item in data]) html_table = u"".join([html_table, table_content, u"
5,邮件构建方法:
def build_and_send_mail(**kwargs): """ 提供堡垒机统一的邮件发送方法, 负责邮件的构建、样式渲染和发送 :param kwargs: subject: 邮件主题, 必选, 注明本邮件的目的, 如:权限过期提醒 content: 邮件的正文内容, 必选, 如:***正在申请以下服务的成员权限,请登录堡垒机(https://www.huaweicloud.com)查看: show_name_list: 表格展示的表头列表,可选, 如:[u"姓名", u"工号", u"电话"] data: 要表格形式展示的数据,格式为[tuple], 可选, 注意tuple中的数据顺序要和表头保持一致 mail_to_list: 收件人地址列表, 必选 :return: True or False """ if not kwargs.get("subject") or not kwargs.get("content") or not kwargs.get("mail_to_list"): logger.error(u"邮件发送失败:必选参数缺失!") return False mail_title = "{}{}".format(const.MAIL_TITLE, kwargs.get("subject")) mail_to = kwargs.get("mail_to_list") mail_msg = (u"" u"
"]) return send_mail(mail_title, mail_msg, mail_to){greeting} ").format( table_style=const.MAIL_OUTER_TABLE_STYLE, greeting=u"Hi 亲爱的堡垒机用户, " if len(mail_to) > 1 else (u"Hi {}, ".format( User.objects.filter(email=mail_to[0]).first().name )) ) mail_msg = u"".join([mail_msg, u"", u" ".format(content=kwargs.get("content"))]) if kwargs.get("show_name_list") and kwargs.get("data"): html_table = build_mail_table(kwargs.get("show_name_list"), kwargs.get("data")) if html_table: mail_msg = u"".join([mail_msg, u" {content} "]) mail_msg = u"".join([mail_msg, u" ", html_table, u" ", u"
", const.MAIL_CSM_ADDRESS, u"", u" ", const.MAIL_FOOTER, u"
6,调用示范:
subject = u"用户信息公示" content = u"您所需的堡垒机用户信息如下,请查阅:" users = models.User.objects.all()[:10] show_name_list = [u"姓名", u"工号", u"电话", u"Mail"] data = [(user.name, user.username, user.phone, user.email) for user in users] mail_to_list = ["[email protected]", "[email protected]"] if utils.build_and_send_mail(subject=subject, content=content, show_name_list=show_name_list, data=data, mail_to_list=mail_to_list): print("Send mail to {} successfully.".format("yonguo")) else: print("Failed")
7,如此便实现了内容和样式的分离。后续如需要改动邮件的结构和样式,只需要维护构建函数即可。