Преглед на файлове

IOS推送异常邮件提醒,优化部分代码

locky преди 2 години
родител
ревизия
b603f58b8c
променени са 3 файла, в които са добавени 88 реда и са изтрити 105 реда
  1. 45 0
      Object/S3Email.py
  2. 22 94
      Service/DevicePushService.py
  3. 21 11
      Service/PushService.py

+ 45 - 0
Object/S3Email.py

@@ -0,0 +1,45 @@
+# @Author    : Rocky
+# @File      : S3Email.py
+# @Time      : 2023/8/11 10:01
+import smtplib
+import email.utils
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+
+SENDER = 'rdpublic@ansjer.com'
+SENDER_NAME = 'rdpublic@ansjer.com'
+USERNAME_SMTP = 'AKIA2E67UIMD6MOSFKXW'  # 带有邮件权限的 IAM 帐号
+PASSWORD_SMTP = 'BHuQ6EQTtFK4qh46o9omO9ZzO3NXzjk/JCWLXnVFmqzM'  # 带有邮件权限的 IAM 密码
+HOST = 'email-smtp.us-east-1.amazonaws.com'
+PORT = 587
+
+
+class S3Email:
+
+    @staticmethod
+    def send_email(email_content, username):
+        body_text = (email_content)
+        body_html = """<html>
+        <head></head>
+        <body>
+            <h1>{}<h1>
+        </body>
+        </html>
+        """.format(email_content)
+
+        msg = MIMEMultipart('alternative')
+        msg['Subject'] = email_content
+        msg['From'] = email.utils.formataddr((SENDER_NAME, SENDER))
+        msg['To'] = username
+        part1 = MIMEText(body_text, 'plain')
+        part2 = MIMEText(body_html, 'html')
+        msg.attach(part1)
+        msg.attach(part2)
+
+        server = smtplib.SMTP(HOST, PORT)
+        server.ehlo()
+        server.starttls()
+        server.ehlo()
+        server.login(USERNAME_SMTP, PASSWORD_SMTP)
+        server.sendmail(SENDER, username, msg.as_string())
+        server.close()

+ 22 - 94
Service/DevicePushService.py

@@ -102,7 +102,6 @@ class DevicePushService:
             detect_interval = new_detect_interval if new_detect_interval > 0 else detect_interval
             detect_interval = 60 if detect_interval < 60 else detect_interval
         redis_obj.set_data(key=name, val=1, expire=detect_interval - 5)
-        LOGGING.info('消息推送-缓存设置APP推送间隔:{}s'.format(detect_interval))
 
     @classmethod
     def save_msg_push(cls, uid_set_push_list, **params):
@@ -247,7 +246,8 @@ class DevicePushService:
             # 判断是否进行APP消息推送,如app_push不为空,则不进行推送
             if not param['app_push']:
                 LOGGING.info('APP准备推送:{}, {}'.format(param['uid'], param))
-                # 推送显示图片
+
+                # is_st为1或3,且推送类型为apns,gcm,华为,异步推送图片
                 if (param['is_st'] == 1 or param['is_st'] == 3) and \
                         (push_type == 0 or push_type == 1 or push_type == 3):
                     if param['is_st'] == 1:
@@ -255,17 +255,32 @@ class DevicePushService:
                     else:
                         key = '{}/{}/{}_0.jpeg'.format(param['uid'], param['channel'], param['n_time'])
                     push_thread = threading.Thread(target=cls.async_send_picture_push, args=(
-                        push_type, param['aws_s3_client'], param['bucket'], key, param['uid'], param['appBundleId'],
-                        param['token_val'], param['event_type'], param['n_time'],
+                        push_type, param['aws_s3_client'], param['bucket'], key,
+                        param['uid'], param['appBundleId'], param['token_val'], param['event_type'], param['n_time'],
                         param['kwag_args']['msg_title'], param['kwag_args']['msg_text'], param['channel']))
                     push_thread.start()
+                # 不推图
                 else:
                     if push_type == 0:  # ios apns
-                        result['do_apns_code'] = cls.do_apns(**kwargs)
+                        result['do_apns_code'] = PushObject.ios_apns_push(param['uid'], param['appBundleId'],
+                                                                          param['token_val'], param['n_time'],
+                                                                          param['event_type'],
+                                                                          param['kwag_args']['msg_title'],
+                                                                          param['kwag_args']['msg_text'],
+                                                                          param['uid'], param['channel'])
                     elif push_type == 1:  # android gcm
-                        result['do_fcm_code'] = cls.do_fcm(**kwargs)
+                        result['do_fcm_code'] = PushObject.android_fcm_push(param['uid'], param['appBundleId'],
+                                                                            param['token_val'], param['n_time'],
+                                                                            param['event_type'],
+                                                                            param['kwag_args']['msg_title'],
+                                                                            param['kwag_args']['msg_text'],
+                                                                            param['uid'], param['channel'])
                     elif push_type == 2:  # android jpush
-                        result['do_jpush_code'] = cls.do_jpush(**kwargs)
+                        result['do_jpush_code'] = PushObject.android_jpush(param['uid'], param['appBundleId'],
+                                                                           param['token_val'], param['n_time'],
+                                                                           param['event_type'],
+                                                                           param['kwag_args']['msg_title'],
+                                                                           param['kwag_args']['msg_text'])
                     elif push_type == 3:
                         huawei_push_object = HuaweiPushObject()
                         huawei_push_object.send_push_notify_message(**kwargs)
@@ -464,93 +479,6 @@ class DevicePushService:
                     send_text = '{}'.format(msg_type)
         return send_text
 
-    @staticmethod
-    def do_jpush(uid, channel, appBundleId, token_val, event_type, n_time,
-                 msg_title, msg_text):
-        """
-        android 国内极光APP消息提醒推送
-        """
-        app_key = JPUSH_CONFIG[appBundleId]['Key']
-        master_secret = JPUSH_CONFIG[appBundleId]['Secret']
-        _jpush = jpush.JPush(app_key, master_secret)
-        push = _jpush.create_push()
-        push.audience = jpush.registration_id(token_val)
-        push_data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
-                     "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
-        android = jpush.android(alert=msg_text, priority=1, style=1, alert_type=7,
-                                big_text=msg_text, title=msg_title,
-                                extras=push_data)
-        push.notification = jpush.notification(android=android)
-        push.platform = jpush.all_
-        res = push.send()
-        LOGGING.info('{}极光推送响应:{}'.format(uid, res))
-        print(res)
-        return res.status_code
-
-    @staticmethod
-    def do_fcm(uid, channel, appBundleId, token_val, event_type, n_time, msg_title, msg_text):
-        """
-        android 谷歌APP消息提醒推送
-        """
-        try:
-            serverKey = FCM_CONFIG[appBundleId]
-        except Exception as e:
-            LOGGING.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-            return 'serverKey abnormal'
-        push_service = FCMNotification(api_key=serverKey)
-        data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
-                "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
-        result = push_service.notify_single_device(registration_id=token_val, message_title=msg_title,
-                                                   message_body=msg_text, data_message=data,
-                                                   extra_kwargs={
-                                                       'default_vibrate_timings': True,
-                                                       'default_sound': True,
-                                                       'default_light_settings': True
-                                                   })
-        return result
-
-    @staticmethod
-    def do_apns(uid, channel, appBundleId, token_val, event_type, n_time, msg_title,
-                msg_text):
-        """
-        ios 消息提醒推送
-        """
-        LOGGING.info("进来do_apns函数了")
-        LOGGING.info(token_val)
-        LOGGING.info(APNS_MODE)
-        LOGGING.info(os.path.join(BASE_DIR, APNS_CONFIG[appBundleId]['pem_path']))
-        try:
-            cli = apns2.APNSClient(
-                mode=APNS_MODE, client_cert=os.path.join(BASE_DIR, APNS_CONFIG[appBundleId]['pem_path']))
-
-            push_data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
-                         "received_at": n_time, "sound": "", "uid": uid, "zpush": "1", "channel": channel}
-            alert = apns2.PayloadAlert(body=msg_text, title=msg_title)
-            payload = apns2.Payload(alert=alert, custom=push_data, sound="default")
-
-            # return uid, channel, appBundleId, str(token_val), event_type, n_time, msg_title,msg_text
-            n = apns2.Notification(payload=payload, priority=apns2.PRIORITY_LOW)
-            res = cli.push(n=n, device_token=token_val, topic=appBundleId)
-            print(res.status_code)
-            LOGGING.info("apns_推送状态:")
-            LOGGING.info(res.status_code)
-
-            if res.status_code == 200:
-                return res.status_code
-            else:
-                print('apns push fail')
-                print(res.reason)
-                LOGGING.info('apns push fail')
-                LOGGING.info(res.reason)
-                return res.status_code
-        except (ValueError, ArithmeticError):
-            return 'The program has a numeric format exception, one of the arithmetic exceptions'
-        except Exception as e:
-            print(repr(e))
-            print('do_apns函数错误行号', e.__traceback__.tb_lineno)
-            LOGGING.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-            return repr(e)
-
     @staticmethod
     def do_xmpush(channel_id, uid, channel, appBundleId, token_val, event_type, n_time,
                   msg_title, msg_text):

+ 21 - 11
Service/PushService.py

@@ -17,11 +17,14 @@ import requests
 from pyfcm import FCMNotification
 
 from AnsjerPush.config import APP_BUNDLE_DICT, APNS_MODE, BASE_DIR, APNS_CONFIG, FCM_CONFIG, JPUSH_CONFIG, XMPUSH_CONFIG \
-    , VIVOPUSH_CONFIG, OPPOPUSH_CONFIG, MEIZUPUSH_CONFIG
+    , VIVOPUSH_CONFIG, OPPOPUSH_CONFIG, MEIZUPUSH_CONFIG, CONFIG_INFO
 from Model.models import UidPushModel
+from Object.RedisObject import RedisObject
+from Object.S3Email import S3Email
 from Service.CommonService import CommonService
 from Service.VivoPushService.push_admin.APIMessage import PushMessage
 from Service.VivoPushService.push_admin.APISender import APISender
+from AnsjerPush.config import LOGGER
 
 
 class PushObject:
@@ -116,10 +119,9 @@ class PushObject:
         @param launch_image: 推送图片链接
         @return: None
         """
-        logger = logging.getLogger('info')
+        pem_path = os.path.join(BASE_DIR, APNS_CONFIG[app_bundle_id]['pem_path'])
+        LOGGER.info('IOS推送: app_bundle_id:{}, pem_path:{}'.format(app_bundle_id, pem_path))
         try:
-            pem_path = os.path.join(BASE_DIR, APNS_CONFIG[app_bundle_id]['pem_path'])
-            logger.info('apns推送app_bundle_id:{}, pem_path:{}'.format(app_bundle_id, pem_path))
             cli = apns2.APNSClient(mode=APNS_MODE, client_cert=pem_path)
             alert = apns2.PayloadAlert(title=msg_title, body=msg_text, launch_image=launch_image)
             push_data = {'alert': 'Motion', 'msg': '', 'sound': '', 'zpush': '1', 'uid': uid, 'channel': channel,
@@ -130,11 +132,20 @@ class PushObject:
                                     mutable_content=True)
             n = apns2.Notification(payload=payload, priority=apns2.PRIORITY_LOW)
             res = cli.push(n=n, device_token=token_val, topic=app_bundle_id)
-            logger.info('IOS推送响应状态码{},params,uid:{},{}'.format(res.status_code, uid, json.dumps(push_data)))
+            LOGGER.info('IOS推送响应状态码{},params,uid:{},{}'.format(res.status_code, uid, json.dumps(push_data)))
             assert res.status_code == 200
+        except (AssertionError, ConnectionResetError) as e:
+            LOGGER.info('IOS推送异常: {}, 证书路径: {}'.format(repr(e), pem_path))
         except Exception as e:
-            logger.info('--->IOS推送异常{}'.format(repr(e)))
-            return repr(e)
+            LOGGER.info('IOS推送异常: {}, 证书路径: {}'.format(repr(e), pem_path))
+
+            # 限制每小时发送一次
+            redis_obj = RedisObject()
+            time_limit = redis_obj.get_data('ios_push_error_mail')
+            if not time_limit:
+                redis_obj.set_data('ios_push_error_mail', 1, 60 * 60)
+                email_content = '{}服IOS推送异常: {}, 证书路径: {}'.format(CONFIG_INFO, repr(e), pem_path)
+                S3Email().send_email(email_content, 'servers@ansjer.com')
 
     @staticmethod
     def android_fcm_push(nickname, app_bundle_id, token_val, n_time, event_type, msg_title, msg_text,
@@ -168,10 +179,9 @@ class PushObject:
                                                                      'default_light_settings': True,
                                                                      }
                                                        )
-            logger.info('fcm推送结果:{}'.format(result))
+            LOGGER.info('fcm推送结果:{}'.format(result))
         except Exception as e:
-            logger.info('fcm推送异常:{}'.format(e))
-            return repr(e)
+            LOGGER.info('fcm推送异常:{}'.format(repr(e)))
 
     @staticmethod
     def android_jpush(nickname, app_bundle_id, token_val, n_time, event_type, msg_title, msg_text):
@@ -204,7 +214,7 @@ class PushObject:
             res = push.send()
             assert res.status_code == 200
         except Exception as e:
-            return repr(e)
+            LOGGER.info('极光推送异常:{}'.format(repr(e)))
 
     @staticmethod
     def android_xmpush(channel_id, nickname, app_bundle_id, token_val, n_time, event_type, msg_title, msg_text,