数据监控 | 生日自动发送 sms

服务器跑脚本,生日当天凌晨自动发送 sms 给朋友

Posted by Haauleon on May 20, 2022

代码设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# -*- coding:utf-8 -*-
"""
@Author   :   haauleon
@Contact  :   753494552@qq.com
@File         :   birthday_cul.py
@Date       :   2022-01-12 13:00:00
@Function :   生日监控
@Tips        :   安装版本 pip install sxtwl==1.0.5
"""

import requests
import json
import sys
import time
import logging
from datetime import datetime
from colorama import Fore, Style
from qcloudsms_py import SmsMultiSender, SmsSingleSender, sms
from qcloudsms_py.httpclient import HTTPError
from functools import wraps
import random
import sxtwl
import ssl
import certifi

# ssl_context = ssl.create_default_context()
# ssl_context.load_verify_locations(certifi.where())
ssl._create_default_https_context = ssl._create_unverified_context


# 腾讯云短信配置
TENCENT_SMS_APP_ID = '应用 ID'
TENCENT_SMS_APP_KEY = '应用 KEY'
TENCENT_SMS_SIGN = '短信签名'

# 短信接收者(主账号)
phone = [
    '电话号码',  # 自己的电话用作备份,第一时间知道发给了谁
]

# 日志配置
_logger = logging.getLogger('birthday')  # 获取日志记录器
_logger.setLevel(logging.DEBUG)  # 设置日志等级
_handler = logging.StreamHandler(sys.stdout)  # 输入到控制台的 handler
_logger.addHandler(_handler)  # 日志记录器增加 handler

# 日历中文索引
YMC = [
    "十一", "十二", "正", "二", "三",
    "四", "五", "六", "七", "八", "九", "十"
]

RMC = [
    "初一", "初二", "初三", "初四", "初五",
    "初六", "初七", "初八", "初九", "初十",
    "十一", "十二", "十三", "十四", "十五",
    "十六", "十七", "十八", "十九", "二十",
    "廿一", "廿二", "廿三", "廿四", "廿五",
    "廿六", "廿七", "廿八", "廿九", "三十", "卅一"
]


def info(msg):
    now = time.strftime("%Y-%m-%d %H:%M:%S")
    _logger.info(Fore.GREEN + now + " [INFO] " + str(msg) + Style.RESET_ALL)


def error(msg):
    now = time.strftime("%Y-%m-%d %H:%M:%S")
    _logger.error(Fore.RED + now + " [ERROR] " + str(msg) + Style.RESET_ALL)


def _print(msg):
    now = time.strftime("%Y-%m-%d %H:%M:%S")
    _logger.debug(Fore.BLUE + now + " [PRINT] " + str(msg) + Style.RESET_ALL)


def traceback_error(func):
    @wraps(func)
    def wraper(self, *args, **kwargs):
        try:
            result = func(self, *args, **kwargs)
        except Exception as e:
            import traceback
            ex_msg = '{exception}'.format(exception=traceback.format_exc())
            print(ex_msg)
            result = ex_msg
        return result

    return wraper


class SMSNotice:
    """短信发送类"""

    def __init__(self):
        self.appid = TENCENT_SMS_APP_ID  # 自己应用ID
        self.appkey = TENCENT_SMS_APP_KEY  # 自己应用Key
        self.sms_sign = TENCENT_SMS_SIGN  # 自己腾讯云创建签名时填写的签名内容(使用公众号的话这个值一般是公众号全称或简称)

    def send_sms_single(self, phone_num, template_id, template_param_list):
        """
        单条发送短信
        :param phone_num: 手机号(字符串格式,如 '111111')
        :param template_id: 腾讯云短信模板ID
        :param template_param_list: 短信模板所需参数列表,例如:【验证码:{1},描述:{2}】,则传递参数 [888,666]按顺序去格式化模板
        :return:
        """
        sender = SmsSingleSender(self.appid, self.appkey)
        try:
            response = sender.send_with_param(86, phone_num, template_id, template_param_list, sign=self.sms_sign)
        except HTTPError as e:
            response = {'result': 1000, 'errmsg': "网络异常发送失败"}
        return response

    def send_sms_multi(self, phone_num_list, template_id, param_list):
        """
        批量发送短信
        :param phone_num_list:手机号列表(列表格式,如 ['11111', '22222'])
        :param template_id:腾讯云短信模板ID
        :param param_list:短信模板所需参数列表,例如:【验证码:{1},描述:{2}】,则传递参数 [888,666]按顺序去格式化模板
        :return:
        """
        sender = SmsMultiSender(self.appid, self.appkey)
        try:
            response = sender.send_with_param(86, phone_num_list, template_id, param_list, sign=self.sms_sign)
        except HTTPError as e:
            response = {'result': 1000, 'errmsg': "网络异常发送失败"}
        return response


lunar = sxtwl.Lunar()  # 实例化日历库
today_year = int(datetime.now().strftime('%Y'))


class GetDay:
    """新旧历的转换"""

    @staticmethod
    def get_day_by_lunar(*solar_date):
        """旧历转新历"""
        year, month, day = solar_date
        lunar_date = lunar.getDayByLunar(year, month, day, False)
        return "%s年%s月%s日" % (lunar_date.y, str(lunar_date.m).rjust(2, '0'), str(lunar_date.d).rjust(2, '0'))

    @staticmethod
    def get_day_by_solar(*lunar_date):
        """新历转旧历"""
        year, month, day = lunar_date
        solar_date = lunar.getDayBySolar(year, month, day)
        # bool(solar_date.Lleap) 为True即润年,反之则不是
        return "%s月%s日" % (YMC[solar_date.Lmc], RMC[solar_date.Ldi])


# 生日(昵称-生日-电话号码)
birthday_data = [
    ('昵称1', GetDay.get_day_by_lunar(today_year, 8, 8), '电话号码1'),
    ('昵称2', '%d年05月20日' % today_year, '电话号码2')
]

# 红包(金额-寓意-口令)
red_envelope = [
    ('100.01', '你就是百里挑一', '你要去桃花岛吗?我有船'),
    ('166.66', '人生顺风顺水', '你的益达,不,是你的益达'),
    ('168.88', '一路发发发', '土豆土豆,我是牛肉'),
    ('178.88', '一起发发发', '天王盖地虎,小猫抓老鼠'),
    ('188.88', '一直发发发', '山无棱天地合,我是夏雨荷'),
]


class BirthdayNotice:
    def __init__(self):
        self.today = datetime.now().strftime('%Y年%m月%d日')
        self.red_envelope = red_envelope
        self.birthday_data = birthday_data
        self.new_phone = phone

    def get_random_red_envelope(self):
        return random.choice(self.red_envelope)

    def get_someone_birthday(self):
        for p in self.birthday_data:
            _, birthday, _ = p
            if birthday == self.today:
                yield p

    def push_msg(self):
        x = self.get_someone_birthday()
        while True:
            try:
                _, _, salt = self.get_random_red_envelope()
                nickname, _, phonenum = next(x)
                sms_msg = [
                    nickname,
                    salt,
                ]
                # _print(nickname, ':', balance, ':', mean)
                s = SMSNotice()
                self.new_phone.append(phonenum)
                sms_result = s.send_sms_multi(self.new_phone, 1409481, sms_msg)
                if "'errmsg': 'OK'" in str(sms_result):
                    _print("短信发送成功")
                else:
                    error("短信异常 >>> %s" % str(sms_result))
            except StopIteration:
                break


if __name__ == '__main__':

    b = BirthdayNotice()
    b.push_msg()
    _print("脚本执行完成")