import json import uuid import time import hmac import random import base64 import hashlib import logging import datetime import requests import traceback from urllib.parse import urlencode, quote __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)