fastapi-template/src/utils/sms.py

149 lines
4.4 KiB
Python

import base64
import datetime
import hashlib
import hmac
import json
import logging
import random
import time
import traceback
import uuid
from urllib.parse import quote, urlencode
import requests
__author__ = 'Woodstock'
__doc__ = '''阿里大鱼短信接口'''
logger = logging.getLogger(__name__)
class AliDaYuProvider(object):
def __init__(self, key, secret, url="https://dysmsapi.aliyuncs.com/", template_code='', sign_name='水明堂', code_count=6):
"""
:param key:
:param secret:
:param url:
:param template_code:
:param sign_name:
"""
self.key = key
self.secret = secret
self.url = url
self.template_id = template_code
self.sign_name = sign_name
self.get_url = None
self.params = None
self.code_count = code_count
def send(self, to, data):
"""
发送模板短信
:param to:
:param data:
:return:
"""
return self.send_template_sms(to=to, data=data, temp_id=self.template_id, sign_name=self.sign_name)
def send_template_sms(self, to, data, temp_id, sign_name):
"""
发送模板短信
:param to:
:param data: 内容数据 格式为数组 例如:{'code': '123456'},如不需替换请填 ''
:param temp_id:
:param sign_name:
:return:
"""
if isinstance(data, dict):
data = json.dumps(data)
self.params = {
'PhoneNumbers': to,
'SignName': sign_name,
'TemplateCode': temp_id,
'TemplateParam': data,
'OutId': '123'
}
try:
self.sign('GET')
resp = self.get_response()
if resp['Code'] == 'OK':
return 0
else:
return -1
except:
logger.error(traceback.format_exc())
return -1
def sign(self, method):
"""
签名
:param method:
:return:
"""
self.params.update({
"SignatureMethod": "HMAC-SHA1",
"SignatureNonce": str(uuid.uuid4()),
"AccessKeyId": self.key,
"SignatureVersion": "1.0",
"Timestamp": datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ'), # '2017-07-12T02:42:19Z',
"Format": "json", # XML
"Action": "SendSms",
"Version": "2017-05-25",
"RegionId": "cn-hangzhou"
})
params_str = urlencode(sorted(self.params.items()))
params_str = "&".join([method, "%2F", quote(params_str)]).replace("%2B", '%2520') # 因url将空格改成加号
print(params_str)
key = "{}&".format(self.secret)
sign_str = hmac_sha1_base64(key, params_str)
params_sign_str = "&".join([urlencode({'Signature': sign_str}), urlencode(sorted(self.params.items()))])
self.get_url = "?".join([self.url, params_sign_str])
def get_response(self):
"""
获取发送结果
:return:
"""
start = time.time()
response = requests.get(self.get_url)
result_json = response.content.decode()
result = json.loads(result_json)
end = time.time()
print(result_json)
print("发送阿里大鱼短信:\n 耗时:{}\n 请求参数:{}\n 返回结果:{}".format(end - start, json.dumps(self.params), result_json))
return result
def send_sms_code_msg(self, to, code):
sms_msg = json.dumps(dict(code=code))
return self.send_template_sms(to, sms_msg, temp_id=self.template_id, sign_name=self.sign_name)
def gen_sms_code(code_count=6):
random_str = str(random.random())
if code_count < 16:
code = random_str[-code_count:]
else:
code = random_str[-6:]
return code
def hmac_sha1_base64(key, content):
"""
sha1签名后base64
:param key:
:param content:
:return:
"""
return base64.b64encode(hmac.new(key.encode("utf-8"), content.encode("utf-8"), hashlib.sha1).digest()).decode()
if __name__ == '__main__':
cfg = {"type": "alidayu", "config": {"key": "LTAI9pTVsFg68Tjw", "secret": "WToG39WC6eLkdnzxhKzlNYEqDV2WFd",
"template_code": "SMS_130918971", "sign_name": "水名堂"}}
api = AliDaYuProvider(**cfg['config'])
sms_code = gen_sms_code()
res = api.send_sms_code_msg("15359827092", sms_code)
print(res)