|
@@ -19,10 +19,16 @@ from firebase_admin import messaging
|
|
|
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, CONFIG_INFO, HONORPUSH_CONFIG, DATA_PUSH_EVENT_TYPE_LIST
|
|
|
+ , VIVOPUSH_CONFIG, OPPOPUSH_CONFIG, MEIZUPUSH_CONFIG, CONFIG_INFO, HONORPUSH_CONFIG, DATA_PUSH_EVENT_TYPE_LIST, \
|
|
|
+ CONFIG_TEST
|
|
|
+from AnsjerPush.packages import apns2
|
|
|
+import jwt
|
|
|
+import httpx
|
|
|
+
|
|
|
from Model.models import UidPushModel
|
|
|
from Object.RedisObject import RedisObject
|
|
|
from Object.S3Email import S3Email
|
|
|
+from Object.enums.ConstantEnum import ConstantEnum
|
|
|
from Object.enums.EventTypeEnum import EventTypeEnumObj
|
|
|
from Service.CommonService import CommonService
|
|
|
from Service.VivoPushService.push_admin.APIMessage import PushMessage
|
|
@@ -127,27 +133,150 @@ class PushObject:
|
|
|
LOGGER.info('IOS推送: uid:{}, app_bundle_id:{}, pem_path:{}, msg_text:'.format(
|
|
|
uid, app_bundle_id, pem_path, msg_text))
|
|
|
try:
|
|
|
- cli = apns2.APNSClient(mode=APNS_MODE, client_cert=pem_path)
|
|
|
- alert = apns2.PayloadAlert(title=msg_title, body=msg_text, launch_image=launch_image)
|
|
|
- # 跳转类型,1:推送消息,2:系统消息,3:音视频通话消息
|
|
|
+ apns_url = "https://api.sandbox.push.apple.com" if CONFIG_INFO == CONFIG_TEST else "https://api.push.apple.com"
|
|
|
+ url = f"{apns_url}/3/device/{token_val}"
|
|
|
+
|
|
|
jump_type = CommonService.get_jump_type(event_type)
|
|
|
- push_data = {'alert': msg_text, 'msg': '', 'sound': '', 'zpush': '1', 'uid': uid, 'channel': channel,
|
|
|
- 'received_at': n_time, 'event_time': n_time, 'event_type': event_type, 'nickname': nickname,
|
|
|
- 'image_url': launch_image, 'jump_type': jump_type
|
|
|
- }
|
|
|
+ push_data = {
|
|
|
+ 'alert': msg_text, 'msg': '', 'sound': '',
|
|
|
+ 'zpush': '1', 'uid': uid, 'channel': channel,
|
|
|
+ 'received_at': n_time, 'event_time': n_time, 'event_type': event_type,
|
|
|
+ 'nickname': nickname, 'image_url': launch_image, 'jump_type': jump_type
|
|
|
+ }
|
|
|
sound = 'call_phone.mp3' if event_type in DATA_PUSH_EVENT_TYPE_LIST else 'default'
|
|
|
- payload = apns2.Payload(alert=alert, custom=push_data, sound=sound, category='myCategory',
|
|
|
- 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推送响应状态码{},token:{},uid:{},params:{}'
|
|
|
- .format(res.status_code, token_val, uid, json.dumps(push_data)))
|
|
|
- assert res.status_code == 200 or res.status_code == 410
|
|
|
- return True
|
|
|
+
|
|
|
+ body = {
|
|
|
+ "aps": {
|
|
|
+ "alert": {
|
|
|
+ "title": msg_title,
|
|
|
+ "body": msg_text,
|
|
|
+ "launch-image": launch_image
|
|
|
+ },
|
|
|
+ "sound": sound,
|
|
|
+ "category": "myCategory",
|
|
|
+ "mutable-content": 1
|
|
|
+ },
|
|
|
+ "custom": push_data
|
|
|
+ }
|
|
|
+
|
|
|
+ headers = {
|
|
|
+ "apns-topic": app_bundle_id,
|
|
|
+ "apns-push-type": "alert"
|
|
|
+ }
|
|
|
+
|
|
|
+ with httpx.Client(http2=True,timeout=10,cert=pem_path,) as client:
|
|
|
+ res = client.post(url, headers=headers, json=body)
|
|
|
+
|
|
|
+ if res.status_code == 200:
|
|
|
+ LOGGER.info(f"{uid} iOS 推送成功, token:{token_val}")
|
|
|
+ return True
|
|
|
+ else:
|
|
|
+ LOGGER.error(f"{uid} iOS 推送失败,状态码: {res.status_code}, 原因: {res.text}")
|
|
|
+ return False
|
|
|
+
|
|
|
except Exception as e:
|
|
|
- LOGGER.info('IOS推送异常: {}, 证书路径: {}'.format(repr(e), pem_path))
|
|
|
+ LOGGER.error(f"{uid} iOS 推送异常: {repr(e)}, 行数: {e.__traceback__.tb_lineno}")
|
|
|
return False
|
|
|
|
|
|
+ @staticmethod
|
|
|
+ def ios_p8_push(nickname, app_bundle_id, token_val, n_time, event_type, msg_title, msg_text,
|
|
|
+ uid='', channel='1', launch_image=None):
|
|
|
+ """
|
|
|
+ iOS推送 (P8证书模式)
|
|
|
+ @param nickname: 设备昵称
|
|
|
+ @param app_bundle_id: app包id
|
|
|
+ @param token_val: 推送 token
|
|
|
+ @param n_time: 当前时间
|
|
|
+ @param event_type: 事件类型
|
|
|
+ @param msg_title: 推送标题
|
|
|
+ @param msg_text: 推送内容
|
|
|
+ @param uid:uid
|
|
|
+ @param channel: 通道
|
|
|
+ @param launch_image: 推送图片链接
|
|
|
+ @return: bool
|
|
|
+ """
|
|
|
+ if app_bundle_id not in ConstantEnum.IOS_P8_CONFIG.value:
|
|
|
+ return PushObject.ios_apns_push(
|
|
|
+ nickname=nickname,
|
|
|
+ app_bundle_id=app_bundle_id,
|
|
|
+ token_val=token_val,
|
|
|
+ n_time=n_time,
|
|
|
+ event_type=event_type,
|
|
|
+ msg_title=msg_title,
|
|
|
+ msg_text=msg_text,
|
|
|
+ uid=uid,
|
|
|
+ channel=channel,
|
|
|
+ launch_image=launch_image
|
|
|
+ )
|
|
|
+ else:
|
|
|
+ LOGGER.info("进入 ios_p8_push 方法,准备开始推送")
|
|
|
+
|
|
|
+ try:
|
|
|
+ team_id = ConstantEnum.IOS_P8_CONFIG.value[app_bundle_id]['team_id']
|
|
|
+ key_id = ConstantEnum.IOS_P8_CONFIG.value[app_bundle_id]['key_id']
|
|
|
+ p8_path = os.path.join(BASE_DIR, ConstantEnum.IOS_P8_CONFIG.value[app_bundle_id]['pem_path'])
|
|
|
+
|
|
|
+
|
|
|
+ with open(p8_path, "r") as f:
|
|
|
+ private_key = f.read()
|
|
|
+ now = int(time.time())
|
|
|
+
|
|
|
+ token = jwt.encode(
|
|
|
+ {"iss": team_id, "iat": now},
|
|
|
+ private_key,
|
|
|
+ algorithm="ES256",
|
|
|
+ headers={"kid": key_id}
|
|
|
+ )
|
|
|
+ if isinstance(token, bytes):
|
|
|
+ token = token.decode("utf-8")
|
|
|
+
|
|
|
+ apns_url = "https://api.sandbox.push.apple.com" if CONFIG_INFO == CONFIG_TEST else "https://api.push.apple.com"
|
|
|
+ url = f"{apns_url}/3/device/{token_val}"
|
|
|
+
|
|
|
+
|
|
|
+ jump_type = CommonService.get_jump_type(event_type)
|
|
|
+ push_data = {
|
|
|
+ 'alert': msg_text, 'msg': '', 'sound': '',
|
|
|
+ 'zpush': '1', 'uid': uid, 'channel': channel,
|
|
|
+ 'received_at': n_time, 'event_time': n_time, 'event_type': event_type,
|
|
|
+ 'nickname': nickname, 'image_url': launch_image, 'jump_type': jump_type
|
|
|
+ }
|
|
|
+ sound = 'call_phone.mp3' if event_type in DATA_PUSH_EVENT_TYPE_LIST else 'default'
|
|
|
+
|
|
|
+ body = {
|
|
|
+ "aps": {
|
|
|
+ "alert": {
|
|
|
+ "title": msg_title,
|
|
|
+ "body": msg_text,
|
|
|
+ "launch-image": launch_image
|
|
|
+ },
|
|
|
+ "sound": sound,
|
|
|
+ "category": "myCategory",
|
|
|
+ "mutable-content": 1
|
|
|
+ },
|
|
|
+ "custom": push_data
|
|
|
+ }
|
|
|
+
|
|
|
+ headers = {
|
|
|
+ "authorization": f"bearer {token}",
|
|
|
+ "apns-topic": app_bundle_id,
|
|
|
+ "apns-push-type": "alert"
|
|
|
+ }
|
|
|
+
|
|
|
+ with httpx.Client(http2=True, timeout=10,) as client:
|
|
|
+ res = client.post(url, headers=headers, json=body)
|
|
|
+
|
|
|
+ if res.status_code == 200:
|
|
|
+ LOGGER.info(f"{uid} iOS p8 推送成功, token:{token_val}")
|
|
|
+ return True
|
|
|
+ else:
|
|
|
+ LOGGER.error(f"{uid} iOS p8 推送失败,状态码: {res.status_code}, 原因: {res.text}")
|
|
|
+ return False
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ LOGGER.error(f"{uid} iOS p8 推送异常: {repr(e)}, 行数: {e.__traceback__.tb_lineno}")
|
|
|
+ return False
|
|
|
+
|
|
|
@staticmethod
|
|
|
def android_fcm_push(nickname, app_bundle_id, token_val, n_time, event_type, msg_title, msg_text,
|
|
|
uid='', channel='1', image=''):
|