【14.0】手机号接口

【一】校验手机号是否存在

from django.shortcuts import render, HttpResponse
from rest_framework.viewsets import ViewSet
from rest_framework.decorators import action
from luffyCity.apps.user.models import User
from luffyCity.utils.common_response import CommonResponse
from rest_framework.exceptions import APIException


# Create your views here.
class UserView(ViewSet):
    '''
    验证手机号接口
    get请求
    与数据库交互但不需要序列化
    继承 ViewSet 自动生成路由
    '''

    @action(methods=['GET'], detail=False)
    def check_mobile(self, request, *args, **kwargs):
        '''
        get 请求 携带在地址参数
        :param request:
        :param args:
        :param kwargs:
        :return:
        '''
        mobile = request.query_params.get('mobile', None)
        if mobile:
            user = User.objects.filter(mobile=mobile).first()
            if user:
                return CommonResponse(msg="手机号已存在")
        # 抛出全局异常被异常捕获,状态码
        raise APIException("手机号不存在")

  • 优化
from django.shortcuts import render, HttpResponse
from rest_framework.viewsets import ViewSet
from rest_framework.decorators import action
from luffyCity.apps.user.models import User
from luffyCity.utils.common_response import CommonResponse
from rest_framework.exceptions import APIException


# Create your views here.
class UserView(ViewSet):
    '''
    验证手机号接口
    get请求
    与数据库交互但不需要序列化
    继承 ViewSet 自动生成路由
    '''

    @action(methods=['GET'], detail=False)
    def check_mobile(self, request, *args, **kwargs):
        '''
        get 请求 携带在地址参数
        :param request:
        :param args:
        :param kwargs:
        :return:
        '''
        try:
            mobile = request.query_params.get('mobile', None)
            User.objects.get(mobile=mobile)  # 有且只有一条才不会报错
            return CommonResponse(msg="手机号存在")
        except Exception as e:
            raise APIException("手机号不存在")

【二】阿里云短信

【1】阿里云发送短信验证码

网上第三方短信平台很多

这里以云片网和阿里云为例

阿里云为例:短信服务_企业短信营销推广_验证码通知-阿里云 (aliyun.com)

(1)购买短信服务

(2)进入短信管理控制台

地址:短信服务 (aliyun.com)

  • 开发阶段可以使用免签名的测试模板来发送验证码,配置几个测试测手机号码(网站备案后可以申请自己的签名)

(3)安装SDK

pip install alibabacloud_dysmsapi20170525==2.0.24

可以在上面调用方法进行测试

3.1 封装函数

# -*-coding: Utf-8 -*-
# @File : aliyun_sms .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/7/10
'''

签名名称 阿里云短信测试
使用场景 发送测试短信
模版名称 测试专用模板
模版 CodeSMS_154950909
模版类型 验证码
模版内容 您正在使用阿里云短信测试服务,体验验证码是:${code},如非本人操作,请忽略本短信!

'''

# -*- coding: utf-8 -*-
# This file is auto-generated, don't edit it. Thanks.
import json
from alibabacloud_dysmsapi20170525.client import Client
from alibabacloud_tea_openapi.models import Config
from alibabacloud_dysmsapi20170525.models import SendSmsRequest
from alibabacloud_tea_util.models import RuntimeOptions


class AliYunSMS:
    # 必填,您的 AccessKey ID,
    access_key_id = ''
    # 必填,您的 AccessKey Secret,
    access_key_secret = ''
    # 访问的域名
    endpoint = f'dysmsapi.aliyuncs.com'
    sign_name = '阿里云短信测试'
    template_code = 'SMS_154950909'

    def __init__(self):
        self.config = Config(
            access_key_id=self.access_key_id,
            access_key_secret=self.access_key_secret,
            endpoint=self.endpoint
        )

    def send(self, mobile: str, code: str):
        '''

        :param mobile:手机号
        :param code:验证码
        :return:
        '''
        # (1) 创建 一个客户端
        client = Client(self.config)
        # (2) 创建短信对象
        send_sms_request = SendSmsRequest(
            # 手机号
            phone_numbers=mobile,
            # 验证码
            template_param=json.dumps({"code": code}),

            sign_name=self.sign_name,
            template_code=self.template_code,

        )
        # (3) 设置运行时间选项
        runtime = RuntimeOptions()
        # (4)发送短息
        client.send_sms_with_options(send_sms_request, runtime)


def main_sms(mobile, code):
    '''
    使用方法:
    from 包名 import main_sms
    send_sms = main_sms(1323636,8686)
    :return:
    '''
    SMS = AliYunSMS()
    mobile = str(mobile)
    code = str(code)
    return SMS.send(mobile, code)


if __name__ == '__main__':
    AliYunSMS().send(mobile='13253184923', code='698312')

3.2 配置发送验证码的相关信息

  • 创建key

  • 生成key

3.3 配置开发文档

# -*-coding: Utf-8 -*-
# @File : aliyun_sms .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/7/10
'''

签名名称 阿里云短信测试
使用场景 发送测试短信
模版名称 测试专用模板
模版 CodeSMS_154950909
模版类型 验证码
模版内容 您正在使用阿里云短信测试服务,体验验证码是:${code},如非本人操作,请忽略本短信!

'''

# -*- coding: utf-8 -*-
# This file is auto-generated, don't edit it. Thanks.
import json
from alibabacloud_dysmsapi20170525.client import Client
from alibabacloud_tea_openapi.models import Config
from alibabacloud_dysmsapi20170525.models import SendSmsRequest
from alibabacloud_tea_util.models import RuntimeOptions


class AliYunSMS:
    # 必填,您的 AccessKey ID,
    access_key_id = 'LTAI5tC8jjSEdzvHeDgbSSVk'
    # 必填,您的 AccessKey Secret,
    access_key_secret = 'GmEGtkSruI1KWyLRszFpNxqhWQ1JhQ'
    # 访问的域名
    endpoint = f'dysmsapi.aliyuncs.com'
    sign_name = '阿里云短信测试'
    template_code = 'SMS_154950909'

    def __init__(self):
        self.config = Config(
            access_key_id=self.access_key_id,
            access_key_secret=self.access_key_secret,
            endpoint=self.endpoint
        )

    def send(self, mobile: str, code: str):
        '''

        :param mobile:手机号
        :param code:验证码
        :return:
        '''
        # (1) 创建 一个客户端
        client = Client(self.config)
        # (2) 创建短信对象
        send_sms_request = SendSmsRequest(
            # 手机号
            phone_numbers=mobile,
            # 验证码
            template_param=json.dumps({"code": code}),

            sign_name=self.sign_name,
            template_code=self.template_code,

        )
        # (3) 设置运行时间选项
        runtime = RuntimeOptions()
        # (4)发送短息
        client.send_sms_with_options(send_sms_request, runtime)


def main_sms(mobile, code):
    '''
    使用方法:
    send_sms = main(1323636,8686)
    :return:
    '''
    SMS = AliYunSMS()
    mobile = str(mobile)
    code = str(code)
    return SMS.send(mobile, code)


if __name__ == '__main__':
    AliYunSMS().send(mobile='13253184923', code='698312')
  • 模板参考二
import json
from alibabacloud_dysmsapi20170525.client import Client
from alibabacloud_tea_openapi.models import Config
from alibabacloud_dysmsapi20170525.models import SendSmsRequest
from alibabacloud_tea_util.models import RuntimeOptions


class ALiyunMessage:
    def __init__(self):
        self.endpoint = f'dysmsapi.aliyuncs.com'
        # 必填,您的 AccessKey ID,
        self.access_key_id = 'LTAI5tC8jjSEdzvHeDgbSSVk'
        # 必填,您的 AccessKey Secret,
        self.access_key_secret = 'GmEGtkSruI1KWyLRszFpNxqhWQ1JhQ'
        # 申请的签名
        self.sign_name = '阿里云短信测试'
        # 短信模板
        self.template_code = 'SMS_154950909'

    def send_msg(self, mobile: str, code: str):
        '''

        :param mobile: 接收验证码的手机号
        :param code: 验证码内容
        :return:
        '''
        message = SendSmsRequest(
            # 手机号
            phone_numbers=mobile,
            # 验证码
            template_param=json.dumps({"code": code}),

            sign_name=self.sign_name,
            template_code=self.template_code,

        )
        config = Config(
            access_key_id=self.access_key_id,
            access_key_secret=self.access_key_secret,
            endpoint=self.endpoint
        )
        client = Client(config)
        # (3) 设置运行时间选项
        runtime = RuntimeOptions()
        try:
            # 发送短信
            res = client.send_sms_with_options(message, runtime)
            if res.body.code == 'OK':
                return {'code': "OK", 'message': "短信发送成功"}
            else:
                return {'code': "No", 'errors': res.body.message}
        except Exception as e:
            return {'code': "NO", 'message': "短信发送失败"}

【2】阿里云获取短信验证码

(1)接口设计

1.1 接口描述

  • 获取验证码

1.2 请求URL

  • /api/users/sendms/

1.3 请求方式

  • POST

1.4 请求体参数

参数名 必选 类型 说明
mobile str 手机号码

1.5 返回示例

  • 状态码 200
    • 校验通过 无响应体
  • 要求:
    • 验证验证码是否有效
    • 进行限流,每个IP一分钟只能发一次验证码

1.6 限流设置

通过IP来区分用户,每个用户每分钟只能获取一次验证码

  • 全局配置
# DRF配置鉴权
REST_FRAMEWORK = {
    # 限流配置
    'DEFAULT_THROTTLE_RATES': {
        'anon': '1/minute',  # 未认证用户,每天1次
    },
}
  • 类视图指定限流的类型
# 限流策略
from rest_framework.throttling import AnonRateThrottle

class SendSMSView(APIView):
    throttle_classes = (AnonRateThrottle,)

(2)代码实现

2.1 基本功能

2.1.1 视图
class SendSMSView(APIView):
    '''短信验证码管理视图'''
    # 设置限流 : 每分钟只能获取一次
    throttle_classes = (AnonRateThrottle,)

    def post(self, request, *args, **kwargs):
        # 获取手机号
        mobile = request.data.get('mobile')
        # 验证手机号格式是否正确(正则表达式匹配)
        re_text = r'^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$'
        re_code = re.compile(re_text, re.S)
        res = re.match(re_code, str(mobile))
        if not res:
            return Response({"errors": "无效的手机号码!"}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)
        # 发送短信验证码
        # 随机生成六位数验证码校验
        random_code = self.get_random_code(6)
        result = main_sms(13253184923, random_code)

        if result['code'] == "OK":
            # 将短信验证码入库
            obj = VerifyCode.objects.create(mobile=mobile, code=random_code)
            # 返回验证码ID
            result['codeID'] = obj.id

            return Response(result, status=status.HTTP_200_OK)
        return Response(result, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def get_random_code(self, n):
        '''随机生成六位数的验证码'''
        code = ''
        for i in range(n):
            random_int = str(random.randint(0, 9))  # 0-9之间的整数
            temp = random.choice([random_int])
            code += temp
        return code

2.2.2 注册路由
urlpatterns = [
    # 发送短信验证码接口
    path('sendsms/', views.SendSMSView.as_view())

]

【三】腾讯云短信注册

【1】登陆腾讯云官网

【2】进入控制台

【3】进入短信模块

【4】点击创建签名

  • 输入信息进行验证

  • 公众号示例

【5】验证完成

【6】创建模版

【7】等待审核

【8】SDK发送短信模板

(1)API

  • api接口----》发送http请求,到某些接口,携带需要携带的数据,就能完成某些操作
  • python发送http请求,目前不会=====》requests模块
  • API(Application Programming Interface)是一组定义了不同软件组件之间如何通信的规范。
    • 它允许不同的软件系统之间相互交互和集成,通过API接口可以发送HTTP请求到特定的服务端接口,并携带必要的数据以完成特定的操作。
    • API可以以不同的形式出现,包括Web API、库函数API等。
  • 以Python为例,可以使用第三方库例如requests模块来发送HTTP请求,实现与API接口的交互。
    • requests模块提供了简洁易用的方法,方便进行GET、POST等常见请求操作,它会根据传入的参数构建请求并发送到指定的API接口,从而实现与API的通信。

(2)SDK

  • 集成开发工具包,跟语言有关系---》官方提供的,使用某种语言对api接口做了封装---》使用难度很低
  • 有sdk优先用sdk---》正统用法,下载,导入,类实例化---》调用类的某个方法完成功能
  • SDK(Software Development Kit)是一套软件开发工具包,通常由API和一些辅助工具、示例代码等组成,旨在帮助开发人员更方便地使用特定平台、语言或框架进行开发。

    • SDK为开发者提供了一系列封装好的函数、类和方法,隐藏了底层复杂的细节,降低了开发的难度。
  • SDK一般由服务提供方官方提供,并针对不同 的编程语言进行了封装。

    • 使用SDK可以简化开发过程,开发者只需下载官方提供的SDK包并将其导入项目中,然后根据官方提供的文档和示例代码,进行类的实例化、方法调用等操作,就能完成特定功能的开发。
  • 因此,在使用某种服务或平台时,如果官方提供了SDK,推荐优先使用SDK进行开发,因为SDK已经提供了封装好的接口和方法,使得开发过程更加简单和高效。

    • 但如果没有官方提供的SDK,也可以通过API接口与服务进行交互,只需自行编写代码来构建与API接口的通信过程。

【9】短信发送模板

(1)前提条件

  • 已开通短信服务,创建签名和模板并通过审核,具体操作请参见 国内短信快速入门

  • 如需发送国内短信,需要先 购买国内短信套餐包

  • 已准备依赖环境:Python 2.7 - 3.6 版本。

  • 已在访问管理控制台 >

    API密钥管理

    页面获取 SecretID 和 SecretKey。

    • SecretID 用于标识 API 调用者的身份。
    • SecretKey 用于加密签名字符串和服务器端验证签名字符串的密钥,SecretKey 需妥善保管,避免泄露
  • 短信的调用地址为sms.tencentcloudapi.com

(2)安装SDK

通过 pip 安装(推荐)

通过源码包安装

(3)官方示例模板

# -*- 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/capi
    cred = credential.Credential("secretId", "secretKey")
    # 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.A8
    client = 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 = "1400787878"
    # 短信签名内容: 使用 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 = "449739"
    # 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致,,若无模板参数,则设置为空
    req.TemplateParamSet = ["1234"]
    # 下发手机号码,采用 E.164 标准,+[国家或地区码][手机号]
    # 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号
    req.PhoneNumberSet = ["+8613711112222"]
    # 用户的 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)

【四】腾讯云短信使用

【1】安装官方SDK

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/capi
    cred = credential.Credential("secretId", "secretKey")
    # 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.A8
    client = 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 = "1400787878"
    # 短信签名内容: 使用 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 = "449739"
    # 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致,,若无模板参数,则设置为空
    req.TemplateParamSet = ["1234"]
    # 下发手机号码,采用 E.164 标准,+[国家或地区码][手机号]
    # 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号
    req.PhoneNumberSet = ["+8613711112222"]
    # 用户的 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)

【3】创建API秘钥

try:
    # 为了保护密钥安全,建议将密钥设置在环境变量中或者配置文件中,请参考本文凭证管理章节。
    # 硬编码密钥到代码中有可能随代码泄露而暴露,有安全隐患,并不推荐。
    cred = credential.Credential(
        os.environ.get("secretId"),
        os.environ.get("secretKey"))
    # SecretId、SecretKey 查询: https://console.cloud.tencent.com/cam/capi
    # 实例化一个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.A8
    client = 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 = "1400837802"
    # 短信签名内容: 使用 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 = "1891656"
    # 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致,,若无模板参数,则设置为空
    req.TemplateParamSet = ['888', '5']
    # 下发手机号码,采用 E.164 标准,+[国家或地区码][手机号]
    # 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号
    req.PhoneNumberSet = ["+8613253184923"]
    # 用户的 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))
except TencentCloudSDKException as err:
    print(err)

【4】短信接口封装

  • 主功能封装
    • luffyCity\luffyCity\libs\SMS_TencentCloud_Sender\SMS_Ten_Send.py
# -*-coding: Utf-8 -*-
# @File : SMS_Ten_Send .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/8/9
import os

# -*- coding: utf-8 -*-
from tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.sms.v20210111 import sms_client, models
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
import random
from . import settings


def get_verify_code(circle_bum):
    code = ''
    for i in range(circle_bum):
        code += str(random.randint(0, 9))
    return code


class SMS_TencentCloud_Sender():
    def __init__(self, code, phone):
        # 初始化 SecretId、SecretKey (为了安全防盗,置于本地环境变量中获取)
        self.cred = credential.Credential(settings.SECRET_ID, settings.SECRET_KEY)
        # 下发手机号码 : 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号
        self.phone = phone
        # 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致,,若无模板参数,则设置为空
        # 验证码发送成功,验证码为:{self.code},{self.timeout}分钟内有效!
        # 目标验证码 , 目标超时时间(如果模板中设置了有效时间)
        self.template_param_set = [f'{code}', f'{settings.FAIL_TIME}']
        # APPID : 添加应用后生成的实际SdkAppId,示例如1400006666
        self.appid = settings.SMS_SDK_APPID
        # 必须填写已审核通过的签名
        self.sign_name = settings.SIGN_NAME
        # 必须填写已审核通过的模板 ID
        self.template_id = settings.TEMPLATE_ID

    def create_Client(self):
        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 = httpProfile

        # 实例化要请求产品(以sms为例)的client对象
        # 第二个参数是地域信息,可以直接填写字符串ap-guangzhou
        # 支持的地域列表参考 https://cloud.tencent.com/document/api/382/52071#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8
        self.client = sms_client.SmsClient(self.cred, "ap-guangzhou", clientProfile)

    def create_Request(self):
        # 实例化一个请求对象,根据调用的接口和实际情况,可以进一步设置请求参数
        req = models.SendSmsRequest()

        req.SmsSdkAppId = self.appid

        req.SignName = self.sign_name
        req.TemplateId = self.template_id
        req.TemplateParamSet = self.template_param_set
        req.PhoneNumberSet = [f"+86{self.phone}"]
        # 用户的 session 内容(无需要可忽略): 可以携带用户侧 ID 等上下文信息,server 会原样返回
        req.SessionContext = ""
        # 短信码号扩展号(无需要可忽略): 默认未开通,如需开通请联系 [腾讯云短信小助手]
        req.ExtendCode = ""
        # 国内短信无需填写该项;国际/港澳台短信已申请独立 SenderId 需要填写该字段,默认使用公共 SenderId,无需填写该字段。
        req.SenderId = ""

        resp = self.client.SendSms(req)

        # 输出json格式的字符串回包
        res_dict = resp._serialize(allow_none=True)
        if res_dict['SendStatusSet'][0]['Code'] == "Ok":
            return True
        else:
            print(res_dict)
            return False

    def send_sms(self):
        self.create_Client()
        return self.create_Request()


def tencent_sms_main(verify_code, tag_phone):
    try:
        t_sms = SMS_TencentCloud_Sender(verify_code, tag_phone)
        return t_sms.send_sms()
    except Exception as e:
        print(e)
        return False


if __name__ == '__main__':
    phone = 
    code = get_verify_code(4)
    result = tencent_sms_main(code, phone)
    print(result)
    # print(os.environ)
  • 配置文件
    • luffyCity\luffyCity\libs\SMS_TencentCloud_Sender\settings.py
# -*-coding: Utf-8 -*-
# @File : settings .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/8/9
import os

# 腾讯云账户密钥对 secretId
SECRET_ID = os.environ.get("TENCENTCLOUD_SECRET_ID")
# 腾讯云账户密钥对 secretKey
SECRET_KEY = os.environ.get("TENCENTCLOUD_SECRET_KEY")

# 添加应用后生成的实际SdkAppId
SMS_SDK_APPID = '1400837802'
# 必须填写已审核通过的签名
SIGN_NAME = '梦梦的知识星球公众号'
# 必须填写已审核通过的模板 ID
TEMPLATE_ID = '1891656'
# 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致
TEMPLATE_PARAM_SET = ''
# 用户的 session 内容(无需要可忽略)
SESSION_CONTEXT = ''
# 短信码号扩展号(无需要可忽略)
EXTEND_CODE = ''
# 国内短信无需填写该项
SENDER_ID = ''
# 验证码失效时间
FAIL_TIME = '2'
  • 包入口封装
    • luffyCity\luffyCity\libs\SMS_TencentCloud_Sender\__init__.py
from .SMS_Ten_Send import get_verify_code, tencent_sms_main

【补充】微信公众号注册

【1】输入邮箱激活

【2】选择企业地区

【3】选择订阅号

【4】信息登记

  • 可以选择博客园或CSDN进行验证

【5】公众号信息完善

【6】注册完成

posted @ 2023-08-19 17:09  Chimengmeng  阅读(31)  评论(0编辑  收藏  举报
/* */