接着上期代码内容,继续完善优化系统功能。
本次增加发送短信通知功能,学习任务系统发布的任务,为了更加及时通知到学生用户,再原有发送邮件通知基础上,再加上手机短信通知功能。
第一步:开通短信通知服务
目前短信通知都是要收费的,本人还没发现免费的短信通知服务,如有网友知道免费资源请分享下。
本人选用的是腾讯云的短信通知服务,一年1千条短信40多元。其他还有阿里云,华为云等等。自己选择实惠好用的平台服务。
1,创建短信签名
创建短信签名这步,目前比较严格了,前提条件,需要实名认证的网站,APP,公众号,小程序等,普通个人开发者要申请下来流程比较繁琐,具体的就不详说了,自己网上查询教程,不是本次重点。
2,创建正文模板
注意按照平台模板格式设置短信内容模板,腾讯云短信模板参数,是按照参数顺序1,2,3等数字来设置的。
3,等待审核
短信签名和模板提交申请,都要审核,一般10分钟左右,审核不通过,可以修改重新提交申请。
4,发送短信
短信签名和模板都审批通过了,就可以发送短信,简单测试下效果,平台有验证方式。
国内短信快速入门,参考官方教程:
https://cloud.tencent.com/document/product/382/37745
第二步:编写短信通知代码
腾讯云官网短信调用方式有2种:API和SDK方式,不过都不太好用,网上找了一个开源的腾讯短信调用库比较好用。
qcloudsms_py是一个基于Python的,使用腾讯云短信服务的开源库。
1. 安装
在终端中执行以下命令,可以使用 pip 安装 qcloudsms_py:
pip install qcloudsms_py
2. 导入
将 qcloudsms_py 导入项目中:
from qcloudsms_py import SmsSingleSender, SmsMultiSender
3. 发送单条短信
使用 SmsSingleSender 类可以发送单条短信。以下是一个示例代码:
from qcloudsms_py import SmsSingleSender from qcloudsms_py.httpclient import HTTPError # 短信应用 SDK AppID appid = 1412345679 # SDK AppID 以1400开头 # 短信应用 SDK AppKey appkey = "******************" # 需要发送短信的手机号码 phone_number = "12345678901" # 短信模板 ID,需要在短信应用中申请 template_id = 1234 # NOTE: 这里使用的模板 ID 必须已经审核通过 # 短信签名内容,使用 UTF-8 编码,必须填写已审核通过的签名 sms_sign = "腾讯云" try: ssender = SmsSingleSender(appid, appkey) # 指定模板单发 result = ssender.send_with_param(phone_number, template_id, ["123456"], sign=sms_sign) print(result) except HTTPError as e: print(e) except Exception as e: print(e)
第三步:短信通知整合到学习系统中
1,编写短信发送工具方法
./mysite/study_system/smsutil.py
# -*- coding: utf-8 -*- from qcloudsms_py import SmsMultiSender, SmsSingleSender from qcloudsms_py.httpclient import HTTPError '''================================================= 短信通知工具 腾讯云短信通知服务 发送频率限制 设置 对同一个手机号,30秒 内发送短信条数不超过1条 对同一个手机号,1小时内发送短信条数不超过5条 对同一个手机号,1 自然日内发送短信条数不超过10条 变量参数长度限制: 0-12个字符 ==================================================''' def send_sms_single(phone_num, template_id, template_param_list): ''' @方法名称: 单条发送短信 @中文注释: 单条发送短信 @入参: @param phone_num str 手机号 @param template_id int 腾讯云短信模板ID @param template_param_list list 短信模版参数列表 @出参: @返回状态: @return 0 失败 @return 1 成功 @返回错误码 @返回错误信息 @作 者: PandaCode辉 @weixin公众号: PandaCode辉 @创建时间: 2023-11-02 @使用范例: send_sms_single('15023456789', 1234567, [12345, 567]) 短信模板所需参数列表,例如:【验证码:{1},描述:{2}】,则传递参数 [888,666]按顺序去格式化模板 ''' try: if (not type(phone_num) is str): return [0, "F00001", "手机号参数类型错误,不为字符串", [None]] if (not type(template_id) is int): return [0, "F00001", "腾讯云短信模板ID类型错误,不为整数", [None]] if (not type(template_param_list) is list): return [0, "F00001", "短信模版参数列表类型错误,不为列表", [None]] # 自己应用ID appid = 123456789 # 自己应用Key appkey = '******************' # 新建单条短信发送实例对象 sender = SmsSingleSender(appid, appkey) # 自己腾讯云创建签名时填写的签名内容(使用公众号的话这个值一般是公众号全称或简称) sms_sign = '签名内容' response = sender.send_with_param(86, phone_num, template_id, template_param_list, sign=sms_sign) return [1, '000000', "单条短信发送成功", [response]] except HTTPError as e: return [0, '999999', "单条短信发送异常,网络异常发送失败" + str(e), [None]] def send_sms_multi(phone_num_list, template_id, template_param_list): ''' @方法名称: 批量发送短信 @中文注释: 批量发送短信 @入参: @param phone_num_list list 手机号列表 @param template_id int 腾讯云短信模板ID @param template_param_list list 短信模版参数列表 @出参: @返回状态: @return 0 失败 @return 1 成功 @返回错误码 @返回错误信息 @作 者: PandaCode辉 @weixin公众号: PandaCode辉 @创建时间: 2023-11-02 @使用范例: send_sms_multi(['15123456789','15123456789'], 1234567, [12345, 567]) 短信模板所需参数列表,例如:【验证码:{1},描述:{2}】,则传递参数 [888,666]按顺序去格式化模板 ''' try: if (not type(phone_num_list) is list): return [0, "F00001", "手机号列表参数类型错误,不为列表", [None]] if (not type(template_id) is int): return [0, "F00001", "腾讯云短信模板ID类型错误,不为整数", [None]] if (not type(template_param_list) is list): return [0, "F00001", "短信模版参数列表类型错误,不为列表", [None]] # 自己应用ID appid = 123456789 # 自己应用Key appkey = '******************' # 新建多条短信发送实例对象 sender = SmsMultiSender(appid, appkey) # 自己腾讯云创建签名时填写的签名内容(使用公众号的话这个值一般是公众号全称或简称) sms_sign = '签名内容' response = sender.send_with_param(86, phone_num_list, template_id, template_param_list, sign=sms_sign) return [1, '000000', "批量短信发送成功", [response]] except HTTPError as e: return [0, '999999', "批量短信发送异常,网络异常发送失败" + str(e), [None]] # 主方法 if __name__ == '__main__': phone_num = '15123456789' template_id = 1234567 # 模板参数列表:学习系统新任务:{1}; 任务内容:{2}; 完成时间:{3}; 奖励积分:{4}; 请及时处理。 # 变量参数长度限制: 0-12个字符 template_param_list = ['每天晚上学习英语新闻', '每晚阅读英语新闻30分钟', '1天', '10'] # 单条发送短信 rst = send_sms_single(phone_num, template_id, template_param_list) print(rst) phone_num_list = ['15123456789', '15123456789'] template_id = 1234567 # 模板参数列表:学习系统新任务:{1}; 任务内容:{2}; 完成时间:{3}; 奖励积分:{4}; 请及时处理。 # 变量参数长度限制: 0-12个字符 template_param_list = ['每天早上背英语单词', '每天背英语单词30个', '1天', '10'] # 批量发送短信 rst = send_sms_multi(phone_num_list, template_id, template_param_list) print(rst)
2,更新定时任务实现方法
./mysite/study_system/utils.py:
def study_sys_pub_day_task(): ''' @方法名称: 定时发布学习系统的定时任务,同时邮件通知,同时发短信通知 @中文注释: 定时发布学习系统的定时任务,同时邮件通知,同时发短信通知 @入参: @出参: @返回状态: @return 0 失败,数据库异常 @return 1 成功 @返回错误码 @返回错误信息 @作 者: PandaCode辉 @weixin公众号: PandaCode辉 @创建时间: 2023-08-28 ''' try: # 查询全部待发布定时日常任务列表 studyScheduledTaskList = StudyScheduledTask.objects.all() # 查询是否成功 if len(studyScheduledTaskList) > 0: # 循环发布定时任务 for scheduledTask in studyScheduledTaskList: # 定时任务参数信息 scheduled_id = str(scheduledTask.scheduled_id) schedule_type = scheduledTask.schedule_type task_title = scheduledTask.task_title task_description = scheduledTask.task_description deadline_days = str(scheduledTask.deadline_days) reward_points = str(scheduledTask.reward_points) user_id = scheduledTask.created_by task_type = str(scheduledTask.task_type) exp_daytime = str(scheduledTask.schedule_time) pub_daytime = str(scheduledTask.pub_daytime) phone_num = scheduledTask.phone_num # 今天 # UTC格式当前时区时间 t = time.localtime() now_daytime = str(time.strftime("%Y%m%d%H%M%S", t)) # print('当前日期时间:' + now_daytime) now_day = now_daytime[:8] print('当前日期:' + now_day) # 每天一次,判断当天是否已经发布任务? if (pub_daytime == now_day): print('当天已经发布任务,不用再发.') continue # 根据循环周期判断 if schedule_type == 'day-1': exp_daytime = now_day + exp_daytime + '00' # print(exp_daytime) exp_daytime = re.sub(r'\D', "", exp_daytime) # print('预定日期时间:' + exp_daytime) # 计算日期差值 dis = time_diff(now_daytime, exp_daytime, "minutes") # print(dis[3][0]) # 计算时间差值 dis_min = int(dis[3][0]) # print(dis_min) # 再判断当前时间是否处于预定时间区间内? # 比如 08:30,当前时间08:27或08:33查到都算预定时间区间,前后相差10分钟作为判断区间。 if dis_min <= 10: print('处于预定时间区间内,开始发布定时任务.') # 今天 # UTC格式当前时区时间 t = time.localtime() work_date = time.strftime("%Y-%m-%d %H:%M:%S", t) # print('当前日期时间:' + str(work_date)) actual_days = 0 task_status = 0 # 获取当前用户对象 cur_user = user_id # 创建对象并保存到数据库 study_task = StudyTask(task_title=task_title, task_type=task_type, task_description=task_description, reward_points=reward_points, deadline_days=deadline_days, task_status=task_status, actual_days=actual_days, created_by=cur_user, created_time=work_date, update_time=work_date) # 保存到数据库是否成功 study_task.save() # 发布成功后,再更新定时任务表日期字段 pub_daytime # 根据ID查询对象数据 scheduledTask2 = StudyScheduledTask.objects.filter(scheduled_id=scheduled_id) # 更新定时任务表,发布日期 scheduledTask2.update(pub_daytime=now_day) print('更新定时任务表,发布日期,成功') # 邮件通知,接收邮箱 receiver_mail = cur_user.email # 发邮件通知 # 邮件主题 subject = '【学习系统新任务:' + task_title + '】' # 邮件内容 content = '' # 邮件内容换行符,'plain'纯文本格式邮件时候用\n或者\r字符串换行符 # HTML格式,使用<br>换行符 content += '【任务ID :' + str(study_task.task_id) + '】' + '\n' content += '【发布时间 :' + work_date + '】' + '\n' content += '【任务名称 :' + task_title + '】' + '\n' # 任务类型 if task_type == 1: # color : blue content += '【任务类型 :1-系统任务】' + '\n' elif task_type == 2: content += '【任务类型 :2-辅导员任务】' + '\n' elif task_type == 4: content += '【任务类型 :4-自学任务】' + '\n' content += '【任务内容说明 :' + task_description + '】' + '\n' content += '【计划完成天数 :' + str(deadline_days) + ' 天】' + '\n' content += '【任务奖励 :' + str(reward_points) + '点】' + '\n' content += '=================================' # 发送邮件 rstmail = send_qq_mail(subject, content, receiver_mail) print('发送邮件成功') # 再发送短信通知 # 短信通知,接收手机号码,如果定时任务没有指定手机号码,则不发短信通知 if phone_num == '': continue # 腾讯云短信模板ID template_id = 1234567 # 模板参数列表:学习系统新任务:{1}; 任务内容:{2}; 完成时间:{3}; 奖励积分:{4}; 请及时处理。 # 变量参数长度限制: 0-12个字符 template_param_list = [task_title, task_title, str(deadline_days) + '天', str(reward_points)] # 单条发送短信 rst = send_sms_single(phone_num, template_id, template_param_list) print(rst) print('发送短信通知成功') else: print('不处于预定时间区间内,不用处理.') pass elif (schedule_type == 'timing'): # 定时一次,判断当前时间是否处于预定日期 + 时间区间内? exp_daytime = re.sub(r'\D', "", exp_daytime) + '00' # print('预定日期时间:' + exp_daytime) # 计算日期差值 dis = time_diff(now_daytime, exp_daytime, "minutes") # print(dis[3][0]) # 计算时间差值 dis_min = int(dis[3][0]) # print(dis_min) # 再判断当前时间是否处于预定时间区间内? # 比如 08:30,当前时间08:27或08:33查到都算预定时间区间,前后相差10分钟作为判断区间。 if dis_min <= 10: print('处于预定时间区间内,开始发布定时任务.') # 今天 # UTC格式当前时区时间 t = time.localtime() work_date = time.strftime("%Y-%m-%d %H:%M:%S", t) # print('当前日期时间:' + str(work_date)) actual_days = 0 task_status = 0 # 获取当前用户对象 cur_user = user_id # 创建对象并保存到数据库 study_task = StudyTask(task_title=task_title, task_type=task_type, task_description=task_description, reward_points=reward_points, deadline_days=deadline_days, task_status=task_status, actual_days=actual_days, created_by=cur_user, created_time=work_date, update_time=work_date) # 保存到数据库是否成功 study_task.save() receiver_mail = cur_user.email # 发邮件通知 # 邮件主题 subject = '【学习系统新任务:' + task_title + '】' # 邮件内容 content = '' # 邮件内容换行符,'plain'纯文本格式邮件时候用\n或者\r字符串换行符 # HTML格式,使用<br>换行符 content += '【任务ID :' + str(study_task.task_id) + '】' + '\n' content += '【发布时间 :' + work_date + '】' + '\n' content += '【任务名称 :' + task_title + '】' + '\n' # 任务类型 if task_type == 1: # color : blue content += '【任务类型 :1-系统任务】' + '\n' elif task_type == 2: content += '【任务类型 :2-辅导员任务】' + '\n' elif task_type == 4: content += '【任务类型 :4-自学任务】' + '\n' content += '【任务内容说明 :' + task_description + '】' + '\n' content += '【计划完成天数 :' + str(deadline_days) + ' 天】' + '\n' content += '【任务奖励 :' + str(reward_points) + '点】' + '\n' content += '=================================' # 发送邮件 rstmail = send_qq_mail(subject, content, receiver_mail) # 再发送短信通知 # 短信通知,接收手机号码,如果定时任务没有指定手机号码,则不发短信通知 if phone_num == '': continue # phone_num = cur_user.phone_num # 腾讯云短信模板ID template_id = 1234567 # 模板参数列表:学习系统新任务:{1}; 任务内容:{2}; 完成时间:{3}; 奖励积分:{4}; 请及时处理。 # 变量参数长度限制: 0-12个字符 template_param_list = [task_title, task_title, str(deadline_days) + '天', str(reward_points)] # 单条发送短信 rst = send_sms_single(phone_num, template_id, template_param_list) print(rst) print('发送短信通知成功') # 发布成功后,再删除定时任务表数据,1次性任务 if rstmail[0] == 1: # 发布完就自动删除任务配置。 scheduledTask.delete() print('发布完就自动删除任务配置,完成。') else: print('不处于预定时间区间内,不用处理.') pass else: # 每周几一次,判断当天是否已经发布任务?再判断当前时间是否处于预定时间区间内? week_int = datetime.now().weekday() + 1 # print('今天周:' + str(week_int)) week_str = 'week-' + str(week_int) # print('今天周:' + week_str) # 先判断当天是否预定周几 if week_str == schedule_type: # 然后再判断当前时间是否处于预定时间区间内? exp_daytime = now_day + exp_daytime + '00' # print(exp_daytime) exp_daytime = re.sub(r'\D', "", exp_daytime) # print('预定日期时间:' + exp_daytime) # 计算日期差值 dis = time_diff(now_daytime, exp_daytime, "minutes") # print(dis[3][0]) # 计算时间差值 dis_min = int(dis[3][0]) # print(dis_min) # 再判断当前时间是否处于预定时间区间内? # 比如 08:30,当前时间08:27或08:33查到都算预定时间区间,前后相差10分钟作为判断区间。 if dis_min <= 10: print('处于预定时间区间内,开始发布定时任务.') # 今天 # UTC格式当前时区时间 t = time.localtime() work_date = time.strftime("%Y-%m-%d %H:%M:%S", t) # print('当前日期时间:' + str(work_date)) actual_days = 0 task_status = 0 # 获取当前用户对象 cur_user = user_id # 创建对象并保存到数据库 study_task = StudyTask(task_title=task_title, task_type=task_type, task_description=task_description, reward_points=reward_points, deadline_days=deadline_days, task_status=task_status, actual_days=actual_days, created_by=cur_user, created_time=work_date, update_time=work_date) # 保存到数据库是否成功 study_task.save() # 发布成功后,再更新定时任务表日期字段 pub_daytime # 根据ID查询对象数据 scheduledTask2 = StudyScheduledTask.objects.filter(scheduled_id=scheduled_id) # 更新定时任务表,发布日期 scheduledTask2.update(pub_daytime=now_day) print('更新定时任务表,发布日期,成功') receiver_mail = cur_user.email # 发邮件通知 # 邮件主题 subject = '【学习系统新任务:' + task_title + '】' # 邮件内容 content = '' # 邮件内容换行符,'plain'纯文本格式邮件时候用\n或者\r字符串换行符 # HTML格式,使用<br>换行符 content += '【任务ID :' + str(study_task.task_id) + '】' + '\n' content += '【发布时间 :' + work_date + '】' + '\n' content += '【任务名称 :' + task_title + '】' + '\n' # 任务类型 if task_type == 1: # color : blue content += '【任务类型 :1-系统任务】' + '\n' elif task_type == 2: content += '【任务类型 :2-辅导员任务】' + '\n' elif task_type == 4: content += '【任务类型 :4-自学任务】' + '\n' content += '【任务内容说明 :' + task_description + '】' + '\n' content += '【计划完成天数 :' + str(deadline_days) + ' 天】' + '\n' content += '【任务奖励 :' + str(reward_points) + '点】' + '\n' content += '=================================' # 发送邮件 rstmail = send_qq_mail(subject, content, receiver_mail) print('发送邮件成功') # 再发送短信通知 # 短信通知,接收手机号码,如果定时任务没有指定手机号码,则不发短信通知 if phone_num == '': continue # phone_num = cur_user.phone_num # 腾讯云短信模板ID template_id = 1234567 # 模板参数列表:学习系统新任务:{1}; 任务内容:{2}; 完成时间:{3}; 奖励积分:{4}; 请及时处理。 # 变量参数长度限制: 0-12个字符 template_param_list = [task_title, task_title, str(deadline_days) + '天', str(reward_points)] # 单条发送短信 rst = send_sms_single(phone_num, template_id, template_param_list) print(rst) print('发送短信通知成功') else: print('不处于预定时间区间内,不用处理.') pass else: print('当天不是预定周几,不用处理.') pass print('========================') # 休眠2秒 time.sleep(2) print('循环发布结束成功.') else: print('查询失败') return [1, '000000', "循环发布结束成功", [None]] except Exception as e: return [0, '999999', "定时发布学习系统的日常任务,同时邮件通知异常," + str(e), [None]]
第三步:运行测试效果
1,定时发布学习任务
-------------------------------------------------end -------------------------------------------------
标签:实战,task,短信,str,Django,content,template,print From: https://www.cnblogs.com/xh2023/p/17814427.html