如何在工作中摸鱼?试试用Python自动发送邮件以及钉钉消息

本文可以学习到以下内容:

  1. 使用requests库发送钉钉消息

  2. 使用email和smtplib库发送邮件

  3. 使用163邮箱服务,自动发送邮件及附件

项目背景

随着公司业务的不断扩展,业务部门产生的数据也越来越多,小凡开始忙上忙下,不断奔跑于各个部门之间。每天,小凡需要将各个部门产出的数据(大多数都是excel数据)汇总制作成日报,还要标注出异常数据发送给各部门经理。

随着时间的推移,工作的流程多数已经稳定下来,每天忙着这些重复的事情,让小凡感到有些疲惫。如果这些工作都能自动化完成,那该多好啊。

后来,小凡发现Python可以实现自动化发送邮件。这让小凡看到了希望,在业余时间里,小凡开始研究,并结合公司的实际情况编写代码。

为了可以更加普遍的使用,小凡将所学习到的内容全部封装为函数,只需要传入参数,调用即可。

自动发送邮件

smtplib和email库都是python内置的标准库,不需要额外安装。

send_email函数是小凡封装的,参数解释如下:

text:邮件内容

server:发送邮件服务方,默认为163服务方

sender:发送人

receivers:接收人,多个接收人封装为列表

psw:从163邮箱获取的服务密码

attachment:附件,单个附件地址,或者多个附件地址列表

to:收件人名称

subject:邮件主题

源码如下:

import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication


def send_email(text, server="smtp.163.com", sender=None, receivers=None, psw=None, attachment=None, to="收件人",subject="python自动发送邮件"):
    """
    text:邮件内容
    server:发送邮件服务方,默认为163服务方
    sender:发送人
    receivers:接收人,多个接收人封装为列表
    psw:从163邮箱获取的服务密码
    attachment:附件,单个附件地址,或者多个附件地址列表
    to:收件人名称
    subject:邮件主题
    """
    # 实例化一个邮箱对象
    smtp = smtplib.SMTP()
    # 发送的文本内容
    text = f'<p>{text}</p>'
    # 实例化一个发送文本的邮箱对象
    mime_text = MIMEText(_text=text, _subtype="html", _charset="utf-8")
    # 发件人
    mime_text["from"] = sender
    # 收件人
    mime_text["to"] = to
    # 主题
    # mime_text["subject"] = subject
    # 创建一个多部分的邮箱对象
    mime_multipart = MIMEMultipart()
    # 邮箱主题
    mime_multipart['Subject'] = subject
    mime_multipart.attach(mime_text)
    if attachment:
        # 发送附件
        if isinstance(attachment, str):
            # 单个附件地址
            with open(attachment, 'rb') as f:
                mime_application = MIMEApplication(f.read())
                mime_application.add_header('Content-Disposition', 'attachment', filename=attachment)
                mime_multipart.attach(mime_application)
        elif isinstance(attachment, list):
            # 多个附件地址列表
            for file in attachment:
                with open(file, 'rb') as f:
                    mime_application = MIMEApplication(f.read())
                    mime_application.add_header('Content-Disposition', 'attachment', filename=file)
                    mime_multipart.attach(mime_application)
    try:
        # 连接并登录发送邮件的服务方
        smtp.connect(server)
        smtp.login(sender, password=psw)
        # 发送邮件
        smtp.sendmail(from_addr=sender, to_addrs=receivers, msg=mime_multipart.as_string())
        print("发送邮件到 ", receivers, " 成功!")
    except Exception as e:
        print(str(e))
    finally:
        smtp.quit()


if __name__ == '__main__':
    text = "Python自动发送邮件"
    sender = 'xxxxxxxxxxx@163.com'
    psw = 'xxxxxxxxxxxxxxxx'
    receivers = ["xxxxxxxxxx@qq.com", "xxxxxxxxxx@163.com"]
    # 不发送附件方式
    # send_email(text=text,sender=sender,psw=psw,receivers=receivers)
    # 发送单个附件
    # attachment = "./requirements.txt"
    # send_email(text=text,sender=sender,psw=psw,receivers=receivers,attachment=attachment)
    # 发送多个附件
    # attachment = ["./requirements.txt","./sspython.ico"]
    # send_email(text=text,sender=sender,psw=psw,receivers=receivers,attachment=attachment)

发送钉钉消息

钉钉是小凡常用的办公软件,一些重要消息需要发送到指定的钉钉群。参考钉钉开发文档,小凡封装了dingding_robot函数。

需要修改钉钉群的配置才能使用,参数解释如下:

title: 在消息显示的时候的简短信息

secret: 密钥

key_msg_list: 自定义的关键词列表

msg: 发送的信息

safe_set:安全设置,自定义关键词,加签

send_type: 发送内容的类型:text,markdown(md)

webhook: 申请的webhook

at_mobiles: 默认为None,指定@某人,传入列表

at_all: @所有人,传入True或者False

return: 发送是否成功标志

源码如下:

import requests
import time
import hmac
import hashlib
import base64
import urllib.parse


def judge_msg(key_msg_list, msg):
    """
    判断发送的消息中是否包含关键字
    """
    for km in key_msg_list:
        if km in msg:
            return True
    return False


def make_sign(secret=None):
    # 当安全设置选择加签方式时,制作秘钥
    timestamp = str(round(time.time() * 1000))
    if secret is None:
        return None
    secret_enc = secret.encode('utf-8')
    string_to_sign = '{}\n{}'.format(timestamp, secret)
    string_to_sign_enc = string_to_sign.encode('utf-8')
    hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
    sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
    return timestamp, sign


def dingding_robot(msg=None, key_msg_list=None, safe_set=None, send_type=None, secret=None, webhook=None,
                   at_mobiles=None, at_all=False, title="钉钉机器人"):
    """
    钉钉机器人
    :param title: 在消息显示的时候的简短信息
    :param secret: 密钥
    :param key_msg_list: 自定义的关键词列表
    :param msg: 发送的信息
    :param safe_set:安全设置,自定义关键词,加签
    :param send_type: 发送内容的类型:text,markdown(md)
    :param webhook: 申请的webhook
    :param at_mobiles: 默认为None,指定@某人,传入列表
    :param at_all: @所有人,传入True或者False
    :return: 发送是否成功标志
    """
    if webhook is None:
        print("webhook参数为必选项")
        return None
    if at_mobiles is None:
        at_mobiles = []
    if send_type not in ["text", "md", "markdown"]:
        print("send_type必须为['text', 'md', 'markdown']其中一个")
        return None
    if safe_set in ['自定义关键词', '加签']:
        header = {
            "Content-Type": "application/json",
            "Charset": "UTF-8"
        }
        send_content = {"at": {"atMobiles": at_mobiles, "isAtAll": at_all}}
        if send_type == "text":
            send_content["msgtype"] = "text"
            send_content["text"] = {"content": msg}
        elif send_type in ["md", "markdown"]:
            send_content["msgtype"] = "markdown"
            send_content["markdown"] = {"title": title, "text": msg}
        if safe_set == "自定义关键词":
            if not isinstance(key_msg_list, list) and not judge_msg(key_msg_list, msg):
                print("key_msg_list传入自定义的关键词列表,msg中必须包含其中一个关键词")
                return None
            res = requests.post(url=webhook, json=send_content, headers=header)
            return res.text
        elif safe_set == "加签":
            if secret:
                timestamp, sign = make_sign(secret)
                webhook = webhook + "&timestamp=" + timestamp + "&sign=" + sign
                res = requests.post(url=webhook, json=send_content, headers=header)
                return res.text
            else:
                print("secret为密钥,加签方式必须传入;")
                return None
    else:
        print("safe_set参数为['自定义关键词', '加签']其中一个")
        return None


if __name__ == '__main__':
    # 1、安全设置为自定义关键词
    webhook = "从钉钉群中获取的webhook"
    safe_set = "自定义关键词"
    key_msg_list = ["自定义关键词1", "自定义关键词2", "自定义关键词3"]
    msg = "发送的内容"
    send_type = "text"  # 或 md、或 markdown
    at_mobiles = ["11111111111", "2222222222"]  # 默认为 None
    dingding_robot(webhook=webhook, safe_set=safe_set, key_msg_list=key_msg_list, msg=msg, send_type=send_type,
                   at_mobiles=at_mobiles)
    # 2、安全设置为加签
    # safe_set = "加签"
    # secret = "xxxxxxxxxxxxxxxxxxxxxxx"
    # dingding_robot(webhook=webhook, safe_set=safe_set, secret=secret, msg=msg, send_type=send_type,
    #                at_mobiles=at_mobiles)

结尾

这些代码减少了小凡的工作量,也让小凡收获了满满的成就感。

感兴趣的小伙伴,赠送全套Python学习资料,包含面试题、简历资料等具体看下方。

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。

img
img

二、Python必备开发工具

工具都帮大家整理好了,安装就可直接上手!img

三、最新Python学习笔记

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。

img

四、Python视频合集

观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

img

五、实战案例

纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

img

六、面试宝典

在这里插入图片描述

在这里插入图片描述

简历模板在这里插入图片描述
若有侵权,请联系删除
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值