当前位置: 首页 > news >正文

【实战:python-Django发送邮件-短信-钉钉通知】

一 Python发送邮件

1.1 使用SMTP模块发送邮件

import smtplib
from email.mime.text import MIMEText
from email.header import Headermsg_from = '306334678@qq.com'  # 发送方邮箱
passwd = 'luzdikipwhjjbibf'  # 填入发送方邮箱的授权码(填入自己的授权码,相当于邮箱密码)
msg_to = ['616564099@qq.com']  # 收件人邮箱
# msg_to = '616564099@qq.com'  # 收件人邮箱subject = "邮件标题"  # 主题
# *************发送html的邮件**********
content = '''
<p>Python 邮件发送测试...</p>
<p><a href="http://www.baidu.com">这是一个链接</a></p>
'''
# 生成一个MIMEText对象
msg = MIMEText(content)
# 放入邮件主题
msg['Subject'] = subject
# 也可以这样传参
# msg['Subject'] = Header(subject, 'utf-8')
# 放入发件人
msg['From'] = msg_from
# 放入收件人
# msg['To'] = '616564099@qq.com'
# msg['To'] = '发给你的邮件啊'
try:# 通过ssl方式发送s = smtplib.SMTP_SSL("smtp.qq.com", 465)# 登录到邮箱s.login(msg_from, passwd)# 发送邮件:发送方,收件方,要发送的消息s.sendmail(msg_from, msg_to, msg.as_string())print('成功')
except s.SMTPException as e:print(e)
finally:s.quit()

1.2 发送html格式邮件

import smtplib
from email.mime.text import MIMEText
from email.header import Headermsg_from = '306334678@qq.com'  # 发送方邮箱
passwd = 'ldoetnwqdjqqbjjj'  # 填入发送方邮箱的授权码(填入自己的授权码,相当于邮箱密码)
msg_to = ['616564099@qq.com']  # 收件人邮箱
# msg_to = '616564099@qq.com'  # 收件人邮箱subject = "邮件标题"  # 主题
# *************发送html的邮件**********
content = '''
<p>Python 邮件发送测试...</p>
<p><a href="http://www.baidu.com">这是一个链接</a></p>
'''
# 生成一个MIMEText对象
msg = MIMEText(content)
# 放入邮件主题
msg['Subject'] = subject
# 也可以这样传参
# msg['Subject'] = Header(subject, 'utf-8')
# 放入发件人
msg['From'] = msg_from
# 放入收件人
# msg['To'] = '616564099@qq.com'
# msg['To'] = '发给你的邮件啊'
try:# 通过ssl方式发送s = smtplib.SMTP_SSL("smtp.qq.com", 465)# 登录到邮箱s.login(msg_from, passwd)# 发送邮件:发送方,收件方,要发送的消息s.sendmail(msg_from, msg_to, msg.as_string())print('成功')
except s.SMTPException as e:print(e)
finally:s.quit()

1.3 发送带附件格式

import smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email import  encoders
msg_from = '306334678@qq.com'  # 发送方邮箱
passwd = '***'  # 填入发送方邮箱的授权码(填入自己的授权码,相当于邮箱密码)
msg_to = ['616564099@qq.com']  # 收件人邮箱subject = "邮件标题"  # 主题
# 创建一个带附件的实例
msg = MIMEMultipart()
# 放入邮件主题
msg['Subject'] = subject
# 也可以这样传参
# msg['Subject'] = Header(subject, 'utf-8')
# 放入发件人
msg['From'] = msg_from# 邮件正文内容
msg.attach(MIMEText('Python 邮件发送测试……', 'plain', 'utf-8'))# 构造附件1,传送当前目录下的 test.txt 文件
att1 = MIMEText(open('test.txt', 'rb').read(), 'base64', 'utf-8')
att1["Content-Type"] = 'application/octet-stream'
# 这里的filename可以任意写,写什么名字,邮件中显示什么名字
att1["Content-Disposition"] = 'attachment; filename="test.txt"'
msg.attach(att1)# 构造附件2,
with open('test.png', 'rb') as f:# 设置附件的MIME和文件名,这里是png类型:mime = MIMEBase('image', 'png', filename='test.png')# 加上必要的头信息:mime.add_header('Content-Disposition', 'attachment', filename='test.png')mime.add_header('Content-ID', '<0>')mime.add_header('X-Attachment-Id', '0')# 把附件的内容读进来:mime.set_payload(f.read())# 用Base64编码:encoders.encode_base64(mime)# 添加到MIMEMultipart:msg.attach(mime)
# 构造附件3,图片格式
fp = open('test.png', 'rb')
msgImage = MIMEImage(fp.read())
fp.close()
# 定义图片 ID,在 HTML 文本中引用
msgImage.add_header('Content-ID', '<image1>')
msg.attach(msgImage)
try:# 通过ssl方式发送s = smtplib.SMTP_SSL("smtp.qq.com", 465)# 登录到邮箱s.login(msg_from, passwd)# 发送邮件:发送方,收件方,要发送的消息s.sendmail(msg_from, msg_to, msg.as_string())print('成功')
except s.SMTPException as e:print(e)
finally:s.quit()

1.4 Django发送邮件

在setting中配置

# EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.qq.com'  # 如果是 163 改成 smtp.163.com
EMAIL_PORT = 465
EMAIL_HOST_USER = '306334678@qq.com'  # 帐号
EMAIL_HOST_PASSWORD = '***'  # 密码
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
#这样收到的邮件,收件人处就会这样显示
#DEFAULT_FROM_EMAIL = 'lqz<'306334678@qq.com>'
EMAIL_USE_SSL = True   #使用ssl
#EMAIL_USE_TLS = False # 使用tls#EMAIL_USE_SSL 和 EMAIL_USE_TLS 是互斥的,即只能有一个为 True

view视图函数

    from django.core.mail import send_mailimport threadingfrom mybbs import settingst = threading.Thread(target=send_mail, args=("您的文章%s新增了一条评论内容" ,'ddd',settings.EMAIL_HOST_USER,["616564099@qq.com"]))t.start()

一次性发多封邮件

from django.core.mail import send_mass_mailmessage1 = ('第一封邮件标题', '这是邮件内容', 'from@example.com', ['first@example.com', 'other@example.com'])
message2 = ('第二封邮件标题', '这是邮件内容', 'from@example.com', ['second@test.com'])
'''
fail_silently: (可选)布尔值。为 False 时, send_mail 会抛出 smtplib.SMTPException 异常。smtplib 文档列出了所有可能的异常。 这些异常都是 SMTPException 的子类
'''
send_mass_mail((message1, message2), fail_silently=False)
'''
send_mail 每次发邮件都会建立一个连接,发多封邮件时建立多个连接。而 send_mass_mail 是建立单个连接发送多封邮件,所以一次性发送多封邮件时 send_mass_mail 要优于 send_mail。
'''

携带附件或发送html(需要接收方支持)

from django.core.mail import EmailMultiAlternatives
# subject 主题 content 内容 to_addr 是一个列表,发送给哪些人
msg = EmailMultiAlternatives('邮件标题', '邮件内容', '发送方', ['接收方'])
msg.content_subtype = "html"
# 添加附件(可选)
msg.attach_file('test.txt')
# 发送
msg.send()

备注:send_mail 每次发邮件都会建立一个连接,发多封邮件时建立多个连接。而 send_mass_mail 是建立单个连接发送多封邮件,所以一次性发送多封邮件时 send_mass_mail 要优于 send_mail

各大邮箱smtp服务器及端口

新浪邮箱smtp服务器
外发服务器:smtp.vip.sina.com
收件服务器:pop3.vip.sina.com
新浪免费邮件
外发服务器:smtp.sina.com.cn
收件服务器:pop3.sina.com.cn
163邮箱smtp服务器
pop: pop.163.com
smtp: smtp.163.com
QQ邮箱smtp服务器及端口
接收邮件服务器:imap.exmail.qq.com,使用SSL,端口号993
发送邮件服务器:smtp.exmail.qq.com,使用SSL,端口号465587
yahoo邮箱smtp服务器
接:pop.mail.yahoo.com.cn
发:smtp.mail.yahoo.com
126邮箱smtp服务器
pop: pop.126.com
smtp: smtp.126.com
新浪免费邮箱
POP3:pop.sina.com
SMTP:smtp.sina.com
SMTP端口号:25
新浪VIP邮箱
POP3:pop3.vip.sina.com
SMTP:smtp.vip.sina.com
SMTP端口号:25
新浪企业邮箱
POP3:pop.sina.com
SMTP:smtp.sina.com
SMTP端口号:25
雅虎邮箱
POP3:pop.mail.yahoo.cn
SMTP:smtp.mail.yahoo.cn
SMTP端口号:25
搜狐邮箱
POP3:pop3.sohu.com
SMTP:smtp.sohu.com
SMTP端口号:25
TOM邮箱
POP3:pop.tom.com
SMTP:smtp.tom.com
SMTP端口号:25
Gmail邮箱
POP3:pop.gmail.com
SMTP:smtp.gmail.com
SMTP端口号:58725
QQ邮箱
POP3:pop.exmail.qq.com
SMTP:smtp.exmail.qq.com
SMTP端口号:25
263邮箱
域名:263.net
POP3:263.net
SMTP:smtp.263.net
SMTP端口号:25
域名:x263.net
POP3:pop.x263.net
SMTP:smtp.x263.net
SMTP端口号:25
域名:263.net.cn
POP3:263.net.cn
SMTP:263.net.cn
SMTP端口号:25
域名:炫我型
POP3:pop.263xmail.com
SMTP:smtp.263xmail.com
SMTP端口号:25
21CN 免费邮箱
POP3:pop.21cn.com
SMTP:smtp.21cn.com
IMAP:imap.21cn.com
SMTP端口号:25
21CN 经济邮邮箱
POP3:pop.21cn.com
SMTP:smtp.21cn.com
SMTP端口号:25
21CN 商务邮邮箱
POP3:pop.21cn.net
SMTP:smtp.21cn.net
SMTP端口号:25
21CN 快感邮箱
POP3:vip.21cn.com
SMTP:vip.21cn.com
SMTP端口号:25
21CN Y邮箱
POP3:pop.y.vip.21cn.com
SMTP:smtp.y.vip.21cn.com
SMTP端口号:25
中华网任我邮邮箱
POP3:rwpop.china.com
SMTP:rwsmtp.china.com
SMTP端口号:25
中华网时尚、商务邮箱
POP3:pop.china.com
SMTP:smtp.china.com
SMTP端口号:25

1.5 qq邮箱配置smtp

登录qq邮箱:

[img]

在这里插入图片描述

在这里插入图片描述

开启smtp服务,生成授权码

二 Python发送短信

# 发送短信需要借助于第三方短信平台,比较知名的有-腾讯云短信:https://cloud.tencent.com/act/pro/csms-阿里短信:https://cn.aliyun.com/product/sms?from_alibabacloud=-容联云短信:https://www.yuntongxun.com/sms/note-inform

在这里插入图片描述

2.1 腾讯云发送短信-准备

# 访问地址,完成以下操作:https://console.cloud.tencent.com/smsv21)申请短信签名 - 国内短信 > 签名管理【需要有公众号/备案网站/小程序等】
2)申请短信模块 - 国内短信 > 正文模板管理【发送短信的格式】
3)使用Python-sdk发送短信-https://cloud.tencent.com/document/product/382/43196

在这里插入图片描述

2.2 测试发送短信

# 1 安装模块
pip install --upgrade tencentcloud-sdk-python
# 2 复制官方代码测试
# -*- coding: utf-8 -*-
from tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
# 导入对应产品模块的client models。
from tencentcloud.sms.v20210111 import sms_client, models# 导入可选配置类
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
try:# 必要步骤:# 实例化一个认证对象,入参需要传入腾讯云账户密钥对secretId,secretKey。# 这里采用的是从环境变量读取的方式,需要在环境变量中先设置这两个值。# 您也可以直接在代码中写死密钥对,但是小心不要将代码复制、上传或者分享给他人,# 以免泄露密钥对危及您的财产安全。# SecretId、SecretKey 查询: https://console.cloud.tencent.com/cam/capicred = credential.Credential("AKIDqLdhZJvQk9QaXLvHOMRKzQuMhqrlibOy", "YuIYggjdaKuc7Seo16zkKnL3kNpAPTQK")# cred = credential.Credential(#     os.environ.get(""),#     os.environ.get("")# )# 实例化一个http选项,可选的,没有特殊需求可以跳过。httpProfile = HttpProfile()# 如果需要指定proxy访问接口,可以按照如下方式初始化hp(无需要直接忽略)# httpProfile = HttpProfile(proxy="http://用户名:密码@代理IP:代理端口")httpProfile.reqMethod = "POST"  # post请求(默认为post请求)httpProfile.reqTimeout = 30    # 请求超时时间,单位为秒(默认60秒)httpProfile.endpoint = "sms.tencentcloudapi.com"  # 指定接入地域域名(默认就近接入)# 非必要步骤:# 实例化一个客户端配置对象,可以指定超时时间等配置clientProfile = ClientProfile()clientProfile.signMethod = "TC3-HMAC-SHA256"  # 指定签名算法clientProfile.language = "en-US"clientProfile.httpProfile = httpProfile# 实例化要请求产品(以sms为例)的client对象# 第二个参数是地域信息,可以直接填写字符串ap-guangzhou,支持的地域列表参考 https://cloud.tencent.com/document/api/382/52071#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8client = sms_client.SmsClient(cred, "ap-guangzhou", clientProfile)# 实例化一个请求对象,根据调用的接口和实际情况,可以进一步设置请求参数# 您可以直接查询SDK源码确定SendSmsRequest有哪些属性可以设置# 属性可能是基本类型,也可能引用了另一个数据结构# 推荐使用IDE进行开发,可以方便的跳转查阅各个接口和数据结构的文档说明req = models.SendSmsRequest()# 基本类型的设置:# SDK采用的是指针风格指定参数,即使对于基本类型您也需要用指针来对参数赋值。# SDK提供对基本类型的指针引用封装函数# 帮助链接:# 短信控制台: https://console.cloud.tencent.com/smsv2# 腾讯云短信小助手: https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81# 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId,示例如1400006666# 应用 ID 可前往 [短信控制台](https://console.cloud.tencent.com/smsv2/app-manage) 查看req.SmsSdkAppId = "1400635776"# 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名# 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看req.SignName = "小猿取经公众号"# 模板 ID: 必须填写已审核通过的模板 ID# 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看req.TemplateId = "1049981"# 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致,,若无模板参数,则设置为空req.TemplateParamSet = ["8888",'5']# 下发手机号码,采用 E.164 标准,+[国家或地区码][手机号]# 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号req.PhoneNumberSet = ["+8618953675221"]# 用户的 session 内容(无需要可忽略): 可以携带用户侧 ID 等上下文信息,server 会原样返回req.SessionContext = ""# 短信码号扩展号(无需要可忽略): 默认未开通,如需开通请联系 [腾讯云短信小助手]req.ExtendCode = ""# 国内短信无需填写该项;国际/港澳台短信已申请独立 SenderId 需要填写该字段,默认使用公共 SenderId,无需填写该字段。注:月度使用量达到指定量级可申请独立 SenderId 使用,详情请联系 [腾讯云短信小助手](https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81)。req.SenderId = ""resp = client.SendSms(req)# 输出json格式的字符串回包print(resp.to_json_string(indent=2))# 当出现以下错误码时,快速解决方案参考# - [FailedOperation.SignatureIncorrectOrUnapproved](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Afailedoperation.signatureincorrectorunapproved-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)# - [FailedOperation.TemplateIncorrectOrUnapproved](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Afailedoperation.templateincorrectorunapproved-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)# - [UnauthorizedOperation.SmsSdkAppIdVerifyFail](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Aunauthorizedoperation.smssdkappidverifyfail-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)# - [UnsupportedOperation.ContainDomesticAndInternationalPhoneNumber](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Aunsupportedoperation.containdomesticandinternationalphonenumber-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)# - 更多错误,可咨询[腾讯云助手](https://tccc.qcloud.com/web/im/index.html#/chat?webAppId=8fa15978f85cb41f7e2ea36920cb3ae1&title=Sms)except TencentCloudSDKException as err:print(err)

2.3 django中封装

# 封装包:-libssend_tx_sms  #包名__init__.pysettings.py #配置文件sms.py      # 核心文件
################ __init__.py ##############
from .sms import get_code,send_sms_by_phone################ settings.py ##############
SECRET_ID = 'AKIDqLdhZJvQk9QaXLvHOMRKzQuMhqrlibOy'
SECRET_KEY = 'YuIYggjdaKuc7Seo16zkKnL3kNpAPTQK'
APP_ID = '1400635776'
SIGN_NAME='小猿取经公众号'
TEMPLATE_ID='1049981'################ sms.py  ##############
import randomfrom tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
# 导入对应产品模块的client models。
from tencentcloud.sms.v20210111 import sms_client, models# 导入可选配置类
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from . import settings# 获取n位随机数组验证码的函数
def get_code(num=4):code = ''for i in range(num):random_num = random.randint(0, 9)code += str(random_num)return code# 发送短信函数
def send_sms_by_phone(mobile, code):try:cred = credential.Credential(settings.SECRET_ID, settings.SECRET_KEY)httpProfile = HttpProfile()httpProfile.reqMethod = "POST"  # post请求(默认为post请求)httpProfile.reqTimeout = 30  # 请求超时时间,单位为秒(默认60秒)httpProfile.endpoint = "sms.tencentcloudapi.com"  # 指定接入地域域名(默认就近接入)# 非必要步骤:# 实例化一个客户端配置对象,可以指定超时时间等配置clientProfile = ClientProfile()clientProfile.signMethod = "TC3-HMAC-SHA256"  # 指定签名算法clientProfile.language = "en-US"clientProfile.httpProfile = httpProfileclient = sms_client.SmsClient(cred, "ap-guangzhou", clientProfile)req = models.SendSmsRequest()req.SmsSdkAppId = settings.APP_ID  # 腾讯短信创建app把app的id号复制过来https://console.cloud.tencent.com/smsv2/app-manage# 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名# 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看req.SignName = settings.SIGN_NAME# 模板 ID: 必须填写已审核通过的模板 ID# 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看req.TemplateId = settings.TEMPLATE_ID# 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致,,若无模板参数,则设置为空req.TemplateParamSet = [code, '1']# 下发手机号码,采用 E.164 标准,+[国家或地区码][手机号]# 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号req.PhoneNumberSet = ["+86" + mobile, ]# 用户的 session 内容(无需要可忽略): 可以携带用户侧 ID 等上下文信息,server 会原样返回req.SessionContext = ""req.ExtendCode = ""req.SenderId = ""resp = client.SendSms(req)# 输出json格式的字符串回包# 字符串类型print(resp.to_json_string(indent=2))return Trueexcept TencentCloudSDKException as err:return False################ views.py ##############
from libs.send_tx_sms import get_code, send_sms_by_phone
def send(request):code = get_code()res = send_sms_by_phone('18953675221', code)if res:return HttpResponse('短信发送成功')else:return HttpResponse('短信发送失败')

三 Python发送钉钉通知

# 在公司内部,我们可能会使用钉钉发送群通知或个人通知,需要使用钉钉软件-手机端-pc端(mac,win)
# 钉钉发送通知主要有以下两种方式-1 发送群通知【群机器人-webhook方式】-使用场景:发送消息到聊天群,需要创建一个聊天机器人-2 发送个人通知【API方式】-使用场景:给公司内某个同事-发送通知类的消息-如果请假审批通过,报销单审批完成,员工生日祝福等

3.1 发送群通知

#1 文档(定义群聊天机器人):
https://open.dingtalk.com/document/robots/custom-robot-access
# 2 参照文档创建聊天机器人单击群管理 > 机器人 > 添加机器人,选择自定义机器人# 3 参照api文档编写消息发送
https://open.dingtalk.com/document/orgapp/robot-overview

3.1.1 创建机器人

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3.1.2 发送消息

发送DING消息

# https://open.dingtalk.com/document/orgapp/robot-sends-nail-message
import requests
import time
import hmac
import base64
import hashlib
import urllib
timestamp = str(round(time.time() * 1000))
secret = 'SEC8e6b93d027b9d27443ed6fb24e67777eb89a23d6a6f07e2c6738c3fb98e9549a'
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))
print(timestamp)
print(sign)url = 'https://oapi.dingtalk.com/robot/send?access_token=7f38316d68b269eac5a94aaded02839e5c27ed1365419e16fce6ad24f5e5198b&timestamp=%s&sign=%s'%(timestamp,sign)data = {"msgtype": "text","text": {"content": "通知:监控报警: 服务异常"}
}
res = requests.post(url, json=data)
print(res.text)

发送普通消息[链接、markdown消息,feedCard消息]

# https://oapi.dingtalk.com/robot/send?access_token=7f38316d68b269eac5a94aaded02839e5c27ed1365419e16fce6ad24f5e5198b
import requests
import time
import hmac
import base64
import hashlib
import urllib
timestamp = str(round(time.time() * 1000))
secret = 'SEC8e6b93d027b9d27443ed6fb24e67777eb89a23d6a6f07e2c6738c3fb98e9549a'
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))
print(timestamp)
print(sign)url = 'https://oapi.dingtalk.com/robot/send?access_token=7f38316d68b269eac5a94aaded02839e5c27ed1365419e16fce6ad24f5e5198b&timestamp=%s&sign=%s'%(timestamp,sign)data = {"msgtype": "link","link": {"text": "这个即将发布的新版本,创始人xx称它为红树林。而在此之前,每当面临重大升级,产品经理们都会取一个应景的代号,这一次,为什么是红树林","title": "时代的火车向前开","picUrl": "","messageUrl": "https://www.dingtalk.com/s?__biz=MzA4NjMwMTA2Ng==&mid=2650316842&idx=1&sn=60da3ea2b29f1dcc43a7c8e4a7c97a16&scene=2&srcid=09189AnRJEdIiWVaKltFzNTw&from=timeline&isappinstalled=0&key=&ascene=2&uin=&devicetype=android-23&version=26031933&nettype=WIFI"}
}res = requests.post(url, json=data)
print(res.text)

发送互动卡片

#1 步骤:
步骤一:登录开发者后台,创建内部应用。步骤二:获取AppKey和AppSecret。步骤三:申请机器人接口权限,搜索“机器人”,选择机器人相关接口权限并申请。步骤四:获取应用访问凭证获取企业内部应用的access_token。步骤五:登录互动卡片普通版搭建平台,搭建卡片模板。步骤六:调用互动卡片服务端接口。调用新版服务端API-机器人发送互动卡片接口,实现发送卡片信息。根据cardBizId卡片标识ID,调用新版服务端API-更新机器人发送互动卡片接口,实现更新卡片内容# 2 文档地址:
https://open.dingtalk.com/document/resourcedownload/ding-card-interactive-card-operation-process?spm=ding_open_doc.document.0.0.616d40e9XD0pGZ# 3 安装sdk
pip install alibabacloud_dingtalk

3.3 发送个人通知

# 1 给公司某个发送通知-https://open.dingtalk.com/document/orgapp/asynchronous-sending-of-enterprise-session-messages# 2 在钉钉开放平台创建企业内部应用/钉钉应用-获取应用凭证(AgentId、AppKey、AppSecret)-https://open-dev.dingtalk.com/fe/app#/corp/app# 3 获取用户token-https://open.dingtalk.com/document/orgapp/obtain-orgapp-token# 4 获取部门id# 5 获取部门下所有用户# 6 获取所有员工# 7 发送消息

3.3.1 创建应用

# 1 访问地址:
https://open-dev.dingtalk.com/fe/app#/corp/app
# 2 创建应用# 3 得到应用基本信息
AgentId、AppKey、AppSecret

在这里插入图片描述

在这里插入图片描述

3.3.2 获取token

# 1 文档地址:
https://open.dingtalk.com/document/orgapp/obtain-orgapp-token# 2 编写代码获取token
def get_access_token(appkey, appsecret):"""获取access_tokenhttps://open.dingtalk.com/document/orgapp/obtain-orgapp-token"""url = 'https://oapi.dingtalk.com/gettoken'params = {'appkey': appkey,'appsecret': appsecret}res = requests.get(url, params=params)return res.json()

在这里插入图片描述

3.3.4 获取在职员工

# 1 接口文档
https://open.dingtalk.com/document/orgapp/intelligent-personnel-query-the-list-of-on-the-job-employees-of-the# 2 给应用授权# 3 代码获取
def get_all_member(access_token):url = "https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/queryonjob"data = {"access_token": access_token,}body={'status_list':3,'offset':0,'size':50}res_json = requests.post(url=url, params=data,json=body).json()return res_json

在这里插入图片描述

3.3.5 发送消息

# 1 接口文档地址
https://open.dingtalk.com/document/orgapp/asynchronous-sending-of-enterprise-session-messages# 2 给应用授权# 3 代码发送消息
def send_message(access_token, body):"""发送应用消息https://open.dingtalk.com/document/orgapp/asynchronous-sending-of-enterprise-session-messages"""url = 'https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2'params = {'access_token': access_token,}res = requests.post(url, params=params, json=body)return res.json()ret = send_message(token['access_token'], {"agent_id": agent_id,#"userid_list": res['userIds'][0],"userid_list": res['result']['data_list'][0],"msg": {"msgtype": "text","text": {"content": "你好,钉钉"},},
})

3.3.6 获取部门列表

# 旧版本接口:https://open.dingtalk.com/document/orgapp/obtains-a-list-of-industry-departments
def get_dep_list(access_token):url = "https://oapi.dingtalk.com/department/list"data = {"access_token": access_token,}res_json = requests.get(url=url, params=data).json()print(res_json)return res_json['department'][0]['id']# 新版本接口
def get_dep_list(access_token):url = "https://oapi.dingtalk.com/topapi/v2/department/listsub"data = {"access_token": access_token,}body={# 'dept_id':0,# 'language':'zh_CN'}res_json = requests.post(url=url, params=data,json=body).json()print(res_json)return res_json['result'][0]['dept_id']

3.3.7 获取部门下人员

# 旧版本接口
def get_memberList(access_token,depId):url = "https://oapi.dingtalk.com/user/getDeptMember"data = {"access_token": access_token,"deptId": depId,}res_json = requests.get(url=url, params=data).json()return res_json# 新版本接口:https://open.dingtalk.com/document/orgapp/obtains-the-list-of-people-under-a-department
def get_memberList(access_token):url = "https://oapi.dingtalk.com/topapi/industry/user/list"data = {"access_token": access_token,}body={"dept_id": 922598227,'cursor':1,'size':10}res_json = requests.post(url=url, params=data,json=body).json()return res_json

在这里插入图片描述
**在这里插入图片描述**

3.3.8 总代码


import requestsdef get_access_token(appkey, appsecret):"""获取access_tokenhttps://open.dingtalk.com/document/orgapp/obtain-orgapp-token:param appkey: 应用的唯一标识key:param appsecret: 应用的密钥:return:{"errcode": 0,"access_token": "96fc7a7axxx","errmsg": "ok","expires_in": 7200}"""url = 'https://oapi.dingtalk.com/gettoken'params = {'appkey': appkey,'appsecret': appsecret}res = requests.get(url, params=params)return res.json()def send_message(access_token, body):"""发送应用消息https://open.dingtalk.com/document/orgapp/asynchronous-sending-of-enterprise-session-messages"""url = 'https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2'params = {'access_token': access_token,}res = requests.post(url, params=params, json=body)return res.json()def get_dep_list(access_token):url = "https://oapi.dingtalk.com/department/list"data = {"access_token": access_token,}res_json = requests.get(url=url, params=data).json()print(res_json)return res_json['department'][0]['id']def get_memberList(access_token,depId):url = "https://oapi.dingtalk.com/user/getDeptMember"data = {"access_token": access_token,"deptId": depId,}res_json = requests.get(url=url, params=data).json()return res_jsondef get_all_member(access_token):url = "https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/queryonjob"data = {"access_token": access_token,}body={'status_list':3,'offset':0,'size':50}res_json = requests.post(url=url, params=data,json=body).json()return res_jsonif __name__ == '__main__':# 应用的唯一标识keyappkey = 'dingonm5dhwzzwc1sgnj'# 应用的密钥appsecret = 'uIn2WinJ87THxLSjUAcuWQwg3hSVwG462UPm6yhi-mkvd2tb3ASjTOetYvuhvXef'# 发送消息时使用的微应用的AgentIDagent_id = '3017843676'# 接收者的userid列表userid_list = ''token = get_access_token(appkey, appsecret)print(token)# 获取部门dept_id=get_dep_list(token['access_token'])# res=get_memberList(token['access_token'],dept_id)res=get_all_member(token['access_token'])print(res['result']['data_list'][0])# 发消息ret = send_message(token['access_token'], {"agent_id": agent_id,# "userid_list": res['userIds'][1],"userid_list": res['result']['data_list'][0],"msg": {"msgtype": "text","text": {"content": "你好,钉钉通知~~~~"},},})# print(ret)

相关文章:

【实战:python-Django发送邮件-短信-钉钉通知】

一 Python发送邮件 1.1 使用SMTP模块发送邮件 import smtplib from email.mime.text import MIMEText from email.header import Headermsg_from 306334678qq.com # 发送方邮箱 passwd luzdikipwhjjbibf # 填入发送方邮箱的授权码(填入自己的授权码&#xff0c;相当于邮箱…...

Todo List

待整理的笔记&#xff0c;先列出来&#xff0c;防止后面忘记要整理什么内容。一个一个整理&#xff1a; Linux内核ARM架构(v8)的系统调用的实现过程&#xff1b;open()/write()/read()在Linux内核中的详细实现过程&#xff0c;到驱动中注册的操作集的调用过程&#xff1b;文件…...

【Redis】Redis十大类型

文章目录 前言一、string字符串类型二、List列表类型三、 Hash表四、 Set集合五、 ZSet有序集合六、 GEO地理空间七、 HyperLogLog基数统计八、Bitmap位图九、bitfield位域十、 Stream流10.1 队列指令10.2 消费组指令10.3 ACK机制 前言 redis是k-v键值对进行存储&#xff0c;k…...

存储实验:Linux挂载iscsi硬盘与华为OceanStor创建LUN全流程

目录 目的环境规划实验实验流程Centos配置0. 关闭防火墙1. 设置网卡信息2. 配置路由3. iscsiadm连接存储 iSCSI LUN创建&#xff08;以华为OceanStor为例&#xff09;验证1. 验证是否成功2. 开启自动挂载 目的 实现Linux连接iscsi硬盘&#xff0c;同时实现开机自启挂载 环境规…...

高可用系统架构设计技术方案:Java架构师视角

在现代互联网环境下&#xff0c;高可用性&#xff08;High Availability, HA&#xff09;已成为衡量系统质量的重要指标之一。对于Java架构师而言&#xff0c;设计一套能够保证业务连续性、快速恢复和持续服务的高可用系统架构&#xff0c;是一项复杂而挑战性的任务。本文将从J…...

C++ --> 类和对象(三)

欢迎来到我的Blog&#xff0c;点击关注哦&#x1f495; 前言 前面已经对类和对象有一定的了解&#xff0c;接下来再次深入的了解一下。 一、深入理解构造函数 构造函数体赋值&#xff1a; 虽然上述构造函数调用之后&#xff0c;对象中已经有了一个初始值&#xff0c;但是不能…...

JS【详解】类 class ( ES6 新增语法 )

本质上&#xff0c;类只是一种特殊的函数。 console.log(typeof 某类); //"function"声明类 class 方式 1 – 类声明 class Car {constructor(model, year) {this.model model;this.year year;} }方式 2 – 类表达式 匿名式 const Car class {constructor(mod…...

vue中使用$set方法给对象添加属性

vue中可以使用$set()给对象添加属性&#xff0c;但不是所有的对象都可以使用&#xff0c;vue中api明确说明&#xff0c;它必须用于向响应式对象上添加属性 响应式对象&#xff0c;vue的响应式原理&#xff0c;可以查看&#xff1a;深入响应式原理 — Vue.js ①对象赋值 this…...

【Python】ftplib的使用

仅描述基础要点&#xff0c;备忘。 python自带ftplib库&#xff0c;可实现ftp读写。 1 要点 ftp未使用默认端口21时&#xff0c;需显示指定端口。ftp路径带有中文&#xff0c;可能需要设置ftp的encoding属性为 gbk。ftplib不支持递归创建目录&#xff0c;需手动创建层级目录…...

CSS 【详解】CSS 函数(含 calc,min,max,clamp,cubic-bezier,env,steps 等)

函数描述CSS 版本attr()返回选择元素的属性值。2calc()允许计算 CSS 的属性值&#xff0c;比如动态计算长度值。3cubic-bezier()定义了一个贝塞尔曲线(Cubic Bezier)。3hsl()使用色相、饱和度、亮度来定义颜色。3hsla()使用色相、饱和度、亮度、透明度来定义颜色。3linear-grad…...

简单理解Lua 协程(coroutine)

也许更好的阅读体验 协程简单理解为可以暂停的线程&#xff0c;但是同一时刻只有一个协程可以处于运行状态。 文章目录 coroutine.create()coroutine.resume()coroutine.wrap()coroutine.yield()coroutine.resume()参数传递resume和yield之间互换数据 coroutine.create() lua…...

(day18) leetcode 204.计数质数

描述 给定整数 n &#xff0c;返回 所有小于非负整数 n 的质数的数量 。 示例 1&#xff1a; 输入&#xff1a;n 10 输出&#xff1a;4 解释&#xff1a;小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。示例 2&#xff1a; 输入&#xff1a;n 0 输出&#xff1a;0示例 3…...

SadTalker数字人服务器部署

一、单独SadTalker部署 git clone https://github.com/OpenTalker/SadTalker.gitcd SadTalker conda create -n sadtalker python3.8conda activate sadtalkerpip install torch1.12.1cu113 torchvision0.13.1cu113 torchaudio0.12.1 --extra-index-url https://download.pyto…...

Python实现一对多WebSocket发送给指定多个客户端

在一对多的WebSocket场景下&#xff0c;如果你想要向特定的多个客户端发送消息&#xff0c;而不是广播给所有客户端&#xff0c;你需要维护一个能够标识每个客户端的方式&#xff0c;比如使用用户名或者客户端ID。这样&#xff0c;你就可以根据需要选择向哪些客户端发送消息。 …...

Power BI 工具介绍

Power BI是一款商业智能&#xff08;BI&#xff09;软件&#xff0c;由微软开发&#xff0c;旨在帮助用户将复杂的数据转化为视觉化的交互式见解。Power BI提供了一套完整的工具&#xff0c;包括数据连接、数据准备、数据建模、数据分析和数据可视化等功能&#xff0c;使用户能…...

银河麒麟高级服务器操作系统V10加固操作指南

1:检查系统openssh安全配置: 2:检查是否设置口令过期前警告天数: 3:检查账户认证失败次数限制: 修改/etc/pam.d/system-auth文件中deny的参数即可 4:检查是否配置SSH方式账户认证失败次数限制:...

(leetcode学习)15. 三数之和

给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组。 示例 1&a…...

算法训练 | 图论Part8 | 117. 软件构建、47. 参加科学大会

目录 117. 软件构建 拓扑排序法 47. 参加科学大会 dijkstra法 117. 软件构建 题目链接&#xff1a;117. 软件构建 文章讲解&#xff1a;代码随想录 拓扑排序法 代码一&#xff1a;拓扑排序 #include <iostream> #include <vector> #include <queue> …...

编程从零基础到进阶(更新中)

题目描述 依旧是输入三个整数&#xff0c;要求按照占8个字符的宽度&#xff0c;并且靠左对齐输出 输入格式 一行三个整数&#xff0c;空格分开 输出格式 输出它们按格式输出的效果&#xff0c;占一行 样例输入 123456789 -1 10 样例输出 123456789-1 10 #include "stdio.…...

MySQL运维实战之ProxySQL(9.6)SQL黑名单

作者&#xff1a;俊达 利用mysql_query_rules表中的error_msg字段&#xff0c;可以实现SQL黑名单的功能。如果规则设置了error_msg&#xff0c;当SQL语句匹配这条规则时&#xff0c;proxysql会直接将error_msg的内容返回给客户端。 当遇到一些大查询严重影响数据库性能时&…...

深入了解MySQL中的innodb_lock_wait_timeout

引言 在数据库管理中&#xff0c;确保数据的一致性和完整性是至关重要的。MySQL的InnoDB存储引擎通过行级锁定机制来实现这一点。然而&#xff0c;当多个事务同时操作数据库时&#xff0c;可能会出现锁等待的情况。了解并合理配置innodb_lock_wait_timeout参数&#xff0c;对于…...

102.qt qml-最全Table交互之多列固定、行列拖拽、自定义委托、标题交互使用教程

自定义实现的Table控件&#xff0c;支持跨qt版本&#xff0c;兼容qt5,qt6&#xff01; 截图如下所示: 黑色风格如下所示&#xff1a; 视频演示入口&#xff1a;Qt QML QianWindowV2.5(新增曲线综合示例、QML最全Table交互示例、支持qt5/qt6)_哔哩哔哩_bilibili 1.示例页面入口…...

文章管理小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;作者管理&#xff0c;文章管理&#xff0c;文章分类管理&#xff0c;论坛&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;文章&#xff0c;论坛&#xff0c;我的 开发系统…...

Ubuntu22.04安装NIVIDIA显卡驱动总结

1.首先在安装驱动时需要判断系统有无GPU以及GPU的型号 可以参考这篇文章&#xff1a; https://blog.51cto.com/u_13171517/8814753#:~:textubuntu%20%E7%B3%BB%E7%BB%9F%20%E6%80%8E%E4%B9%88%E5%88%A4%E6%96%AD%E7%B3%BB%E7%BB%9F%E6%9C%89%E6%B2%A1%E6%9C%89GPU%201%20%E6%…...

Redis的配置优化、数据类型、消息队列

文章目录 一、Redis的配置优化redis主要配置项CONFIG 动态修改配置慢查询持久化RDB模式AOF模式 Redis多实例Redis命令相关 二、Redis数据类型字符串string列表list集合 set有序集合sorted set哈希hash 三、消息队列生产者消费者模式发布者订阅者模式 一、Redis的配置优化 redi…...

数据结构之初始二叉树(2)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;数据结构&#xff08;Java版&#xff09; 二叉树的前置知识&#xff08;概念、性质、、遍历&#xff09; 通过上篇文章的学习&#xff0c;我们…...

如何预防最新的baxia变种勒索病毒感染您的计算机?

引言 在当今数字化时代&#xff0c;网络安全威胁层出不穷&#xff0c;其中勒索病毒已成为企业和个人面临的重大挑战之一。近期&#xff0c;.baxia勒索病毒以其高隐蔽性和破坏性引起了广泛关注。本文将详细介绍.baxia勒索病毒的特点、传播方式&#xff0c;并给出相应的应对策略…...

git列出提交记录的文件路径

一、如何列出某次提交记录中修改过/新增的文件&#xff1f; 方法1&#xff1a;使用 git diff-tree 命令来查看某个提交记录中修改过/新增的文件。具体来说&#xff0c;你可以使用以下命令&#xff1a; git diff-tree --no-commit-id --name-only -r <commit-hash>命令解…...

微信小程序密码 显示隐藏 真机兼容问题

之前使用type来控制&#xff0c;发现不行&#xff0c;修改为password属性即可 <van-fieldright-icon"{{passwordType password? closed-eye:eye-o}}"model:value"{{ password }}"password"{{passwordType password ? true: false}}"borde…...

C# 中,使用 LINQ 示例 备忘

语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称。 数据查询历来都表示为简单的字符串&#xff0c;没有编译时类型检查或 IntelliSense 支持。 此外&#xff0c; … 对于编写查询的开发者来说&#xff0c;LINQ 最明显的“语言集成”部分就是查询表达式。 …...