PushService.py 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. # -*- coding: utf-8 -*-
  2. """
  3. @Time : 2022/5/19 11:43
  4. @Auth : Locky
  5. @File :PushService.py
  6. @IDE :PyCharm
  7. """
  8. import hashlib
  9. import json
  10. import logging
  11. import os
  12. import time
  13. import apns2
  14. import firebase_admin
  15. import jpush
  16. import requests
  17. from firebase_admin import messaging
  18. from pyfcm import FCMNotification
  19. from AnsjerPush.config import APP_BUNDLE_DICT, APNS_MODE, BASE_DIR, APNS_CONFIG, FCM_CONFIG, JPUSH_CONFIG, XMPUSH_CONFIG \
  20. , VIVOPUSH_CONFIG, OPPOPUSH_CONFIG, MEIZUPUSH_CONFIG, CONFIG_INFO, HONORPUSH_CONFIG
  21. from Model.models import UidPushModel
  22. from Object.RedisObject import RedisObject
  23. from Object.S3Email import S3Email
  24. from Object.enums.EventTypeEnum import EventTypeEnumObj
  25. from Service.CommonService import CommonService
  26. from Service.VivoPushService.push_admin.APIMessage import PushMessage
  27. from Service.VivoPushService.push_admin.APISender import APISender
  28. from AnsjerPush.config import LOGGER
  29. TIME_LOGGER = logging.getLogger('time')
  30. class PushObject:
  31. # 推送对象
  32. @staticmethod
  33. def get_msg_title(nickname):
  34. """
  35. 获取推送消息标题
  36. @param nickname: 设备名
  37. @return: msg_title
  38. """
  39. return nickname
  40. @staticmethod
  41. def get_gateway_msg_text(n_time, tz, lang, alarm):
  42. """
  43. 获取网关推送消息内容
  44. @param n_time: 当前时间
  45. @param tz: 时区
  46. @param lang: 语言
  47. @param alarm: 警报
  48. @return: msg_text
  49. """
  50. n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz, lang=lang)
  51. if lang == 'cn':
  52. msg_text = '{} 日期:{}'.format(alarm, n_date)
  53. else:
  54. msg_text = '{} date:{}'.format(alarm, n_date)
  55. return msg_text
  56. @staticmethod
  57. def get_ai_msg_text(channel, n_time, lang, tz, label):
  58. """
  59. 获取AI推送内容
  60. @param channel: 通道
  61. @param n_time: 当前时间
  62. @param lang: 语言
  63. @param tz: 时区
  64. @param label: 识别到的标签
  65. @return: ai_msg_text
  66. """
  67. n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz, lang=lang)
  68. if lang == 'cn':
  69. msg = '摄像头AI识别到了{}'.format(label)
  70. ai_msg_text = '{msg} 通道:{channel} 日期:{date}'.format(msg=msg, channel=channel, date=n_date)
  71. else:
  72. msg = 'Camera AI recognizes {}'.format(label)
  73. ai_msg_text = '{msg} channel:{channel} date:{date}'.format(msg=msg, channel=channel, date=n_date)
  74. return ai_msg_text
  75. @staticmethod
  76. def get_low_power_msg_text(channel, n_time, lang, tz, electricity, is_sys=0):
  77. """
  78. 获取低电量推送内容
  79. @param channel: 通道
  80. @param n_time: 当前时间
  81. @param lang: 语言
  82. @param tz: 时区
  83. @param electricity: 电量
  84. @param is_sys: 是否为系统消息
  85. @return: low_power_msg_text
  86. """
  87. n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz, lang=lang)
  88. if lang == 'cn':
  89. alarm = '剩余电量 ' + electricity
  90. if is_sys:
  91. low_power_msg_text = '{} 通道:{}'.format(alarm, channel)
  92. else:
  93. low_power_msg_text = '{} 通道:{} 日期:{}'.format(alarm, channel, n_date)
  94. else:
  95. alarm = 'Battery remaining ' + electricity
  96. if is_sys:
  97. low_power_msg_text = '{} channel:{}'.format(alarm, channel)
  98. else:
  99. low_power_msg_text = '{} channel:{} date:{}'.format(alarm, channel, n_date)
  100. return low_power_msg_text
  101. @staticmethod
  102. def ios_apns_push(nickname, app_bundle_id, token_val, n_time, event_type, msg_title, msg_text,
  103. uid='', channel='1', launch_image=None):
  104. """
  105. ios apns 推送
  106. @param nickname: 设备昵称
  107. @param app_bundle_id: app包id
  108. @param token_val: 推送token
  109. @param n_time: 当前时间
  110. @param event_type: 事件类型
  111. @param msg_title: 推送标题
  112. @param msg_text: 推送内容
  113. @param uid: uid
  114. @param channel: 通道
  115. @param launch_image: 推送图片链接
  116. @return: bool
  117. """
  118. pem_path = os.path.join(BASE_DIR, APNS_CONFIG[app_bundle_id]['pem_path'])
  119. LOGGER.info('IOS推送: uid:{}, app_bundle_id:{}, pem_path:{}, msg_text:'.format(
  120. uid, app_bundle_id, pem_path, msg_text))
  121. try:
  122. cli = apns2.APNSClient(mode=APNS_MODE, client_cert=pem_path)
  123. alert = apns2.PayloadAlert(title=msg_title, body=msg_text, launch_image=launch_image)
  124. # 跳转类型,1:推送消息,2:系统消息,3:音视频通话消息
  125. jump_type = CommonService.get_jump_type(event_type)
  126. push_data = {'alert': msg_text, 'msg': '', 'sound': '', 'zpush': '1', 'uid': uid, 'channel': channel,
  127. 'received_at': n_time, 'event_time': n_time, 'event_type': event_type, 'nickname': nickname,
  128. 'image_url': launch_image, 'jump_type': jump_type
  129. }
  130. sound = 'call_phone.mp3' if event_type in EventTypeEnumObj.DATA_PUSH_EVENT_TYPE_LIST.value else 'default'
  131. payload = apns2.Payload(alert=alert, custom=push_data, sound=sound, category='myCategory',
  132. mutable_content=True)
  133. n = apns2.Notification(payload=payload, priority=apns2.PRIORITY_LOW)
  134. res = cli.push(n=n, device_token=token_val, topic=app_bundle_id)
  135. LOGGER.info('IOS推送响应状态码{},token:{},uid:{},params:{}'
  136. .format(res.status_code, token_val, uid, json.dumps(push_data)))
  137. assert res.status_code == 200 or res.status_code == 410
  138. return True
  139. except Exception as e:
  140. LOGGER.info('IOS推送异常: {}, 证书路径: {}'.format(repr(e), pem_path))
  141. return False
  142. @staticmethod
  143. def android_fcm_push(nickname, app_bundle_id, token_val, n_time, event_type, msg_title, msg_text,
  144. uid='', channel='1', image=''):
  145. """
  146. android fcm 推送
  147. @param nickname: 设备昵称
  148. @param app_bundle_id: app包id
  149. @param token_val: 推送token
  150. @param n_time: 当前时间
  151. @param event_type: 事件类型
  152. @param msg_title: 推送标题
  153. @param msg_text: 推送内容
  154. @param uid: uid
  155. @param channel: 通道
  156. @param image: 推送图片链接
  157. @return: bool
  158. """
  159. try:
  160. serverKey = FCM_CONFIG[app_bundle_id]
  161. push_service = FCMNotification(api_key=serverKey)
  162. push_data = {'alert': msg_text, 'msg': '', 'sound': 'sound.aif', 'zpush': '1', 'image': image,
  163. 'received_at': n_time, 'event_time': n_time, 'event_type': event_type, 'nickname': nickname,
  164. 'uid': uid, 'channel': channel
  165. }
  166. if event_type in EventTypeEnumObj.DATA_PUSH_EVENT_TYPE_LIST.value:
  167. push_data['priority'] = 'high'
  168. push_data['content_available'] = True
  169. push_data['direct_boot_ok'] = True
  170. result = push_service.notify_single_device(registration_id=token_val, message_title=msg_title,
  171. message_body=msg_text, data_message=push_data,
  172. click_action='android.intent.action.VIEW',
  173. extra_kwargs={'default_sound': True,
  174. 'default_vibrate_timings': True,
  175. 'default_light_settings': True,
  176. },
  177. )
  178. TIME_LOGGER.info('uid:{}fcm推送结果:{}'.format(uid, result))
  179. return True
  180. except Exception as e:
  181. TIME_LOGGER.error('uid:{}fcm推送异常:{}'.format(uid, repr(e)))
  182. return False
  183. @staticmethod
  184. def android_fcm_push_v1(nickname, app_bundle_id, token_val, n_time, event_type, msg_title, msg_text,
  185. uid='', channel='1', image=''):
  186. """
  187. android fcm 推送
  188. @param nickname: 设备昵称
  189. @param app_bundle_id: app包id
  190. @param token_val: 推送token
  191. @param n_time: 当前时间
  192. @param event_type: 事件类型
  193. @param msg_title: 推送标题
  194. @param msg_text: 推送内容
  195. @param uid: uid
  196. @param channel: 通道
  197. @param image: 推送图片链接
  198. @return: bool
  199. """
  200. try:
  201. event_type = str(event_type)
  202. n_time = str(n_time)
  203. # 跳转类型
  204. jump_type = str(CommonService.get_jump_type(event_type))
  205. push_data = {'alert': msg_text, 'msg': '', 'sound': 'sound.aif', 'zpush': '1',
  206. 'received_at': n_time, 'event_time': n_time, 'event_type': event_type, 'nickname': nickname,
  207. 'uid': uid, 'channel': channel, 'jump_type': jump_type
  208. }
  209. if event_type in EventTypeEnumObj.DATA_PUSH_EVENT_TYPE_LIST.value:
  210. push_data['priority'] = 'high'
  211. push_data['content_available'] = True
  212. push_data['direct_boot_ok'] = True
  213. message = messaging.Message(
  214. notification=messaging.Notification(
  215. title=msg_title,
  216. body=msg_text,
  217. image=image
  218. ),
  219. data=push_data,
  220. token=token_val,
  221. )
  222. # Send a message to the device corresponding to the provided
  223. # registration token.
  224. result = messaging.send(message)
  225. LOGGER.info('fcm推送结果:{}'.format(result))
  226. return True
  227. except Exception as e:
  228. LOGGER.info('fcm推送异常:{}'.format(repr(e)))
  229. return False
  230. @staticmethod
  231. def android_jpush(nickname, app_bundle_id, token_val, n_time, event_type, msg_title, msg_text, channel=1):
  232. """
  233. android 极光 推送
  234. @param nickname: 设备昵称
  235. @param app_bundle_id: app包id
  236. @param token_val: 推送token
  237. @param n_time: 当前时间
  238. @param event_type: 事件类型
  239. @param msg_title: 推送标题
  240. @param msg_text: 推送内容
  241. @param channel: 设备通道
  242. @return: bool
  243. """
  244. try:
  245. # app_key = JPUSH_CONFIG[app_bundle_id]['Key']
  246. # master_secret = JPUSH_CONFIG[app_bundle_id]['Secret']
  247. # # 换成各自的app_key和master_secret
  248. # _jpush = jpush.JPush(app_key, master_secret)
  249. # push = _jpush.create_push()
  250. # push.audience = jpush.registration_id(token_val)
  251. # if event_type in EventTypeEnumObj.DATA_PUSH_EVENT_TYPE_LIST.value:
  252. # channel_id = '111934'
  253. # else:
  254. # channel_id = '1'
  255. # push_data = {'alert': msg_text, 'msg': '', 'sound': 'sound.aif', 'zpush': '1', 'uid': nickname,
  256. # 'received_at': n_time, 'event_time': n_time, 'event_type': event_type, 'nickname': nickname,
  257. # 'channel': channel
  258. # }
  259. # android = jpush.android(title=msg_title, big_text=msg_text, alert=msg_text, extras=push_data,
  260. # priority=1, style=1, alert_type=7, channel_id=channel_id
  261. # )
  262. # push.notification = jpush.notification(android=android)
  263. # push.platform = jpush.all_
  264. # res = push.send()
  265. # assert res.status_code == 200
  266. return True
  267. except Exception as e:
  268. LOGGER.info('极光推送异常:{}'.format(repr(e)))
  269. return False
  270. @staticmethod
  271. def jpush(nickname, app_bundle_id, token_val, n_time, event_type, msg_title, msg_text, channel=1):
  272. """
  273. android 极光 推送
  274. @param nickname: 设备昵称
  275. @param app_bundle_id: app包id
  276. @param token_val: 推送token
  277. @param n_time: 当前时间
  278. @param event_type: 事件类型
  279. @param msg_title: 推送标题
  280. @param msg_text: 推送内容
  281. @param channel: 设备通道
  282. @return: bool
  283. """
  284. try:
  285. app_key = JPUSH_CONFIG[app_bundle_id]['Key']
  286. master_secret = JPUSH_CONFIG[app_bundle_id]['Secret']
  287. # 换成各自的app_key和master_secret
  288. _jpush = jpush.JPush(app_key, master_secret)
  289. push = _jpush.create_push()
  290. push.audience = jpush.registration_id(token_val)
  291. if event_type in EventTypeEnumObj.DATA_PUSH_EVENT_TYPE_LIST.value:
  292. channel_id = '111934'
  293. else:
  294. channel_id = '1'
  295. # 跳转类型
  296. jump_type = CommonService.get_jump_type(event_type)
  297. push_data = {'alert': msg_text, 'msg': '', 'sound': 'sound.aif', 'zpush': '1', 'uid': nickname,
  298. 'received_at': n_time, 'event_time': n_time, 'event_type': event_type, 'nickname': nickname,
  299. 'channel': channel, 'jump_type': jump_type
  300. }
  301. android = jpush.android(title=msg_title, big_text=msg_text, alert=msg_text, extras=push_data,
  302. priority=1, style=1, alert_type=7, channel_id=channel_id
  303. )
  304. push.notification = jpush.notification(android=android)
  305. push.platform = jpush.all_
  306. res = push.send()
  307. assert res.status_code == 200
  308. LOGGER.info('极光推送响应:{}, 参数:{}, 令牌:{}'.format(res, push_data, token_val))
  309. return True
  310. except Exception as e:
  311. LOGGER.info('极光推送异常:{}'.format(repr(e)))
  312. return False
  313. @staticmethod
  314. def android_xmpush(channel_id, nickname, app_bundle_id, token_val, n_time, event_type, msg_title, msg_text,
  315. uid='', channel='1', image=''):
  316. """
  317. android 小米 推送
  318. @param channel_id: 通知通道
  319. @param nickname: 设备昵称
  320. @param app_bundle_id: app包id
  321. @param token_val: 推送token
  322. @param n_time: 当前时间
  323. @param event_type: 事件类型
  324. @param msg_title: 推送标题
  325. @param msg_text: 推送内容
  326. @param uid: uid
  327. @param channel: 通道
  328. @param image: 推送图片链接
  329. @return: bool
  330. """
  331. try:
  332. url = 'https://api.xmpush.xiaomi.com/v3/message/regid'
  333. app_secret = XMPUSH_CONFIG[app_bundle_id]
  334. # 跳转类型
  335. jump_type = CommonService.get_jump_type(event_type)
  336. data = {
  337. 'title': msg_title,
  338. 'description': msg_text,
  339. 'payload': 'payload',
  340. 'restricted_package_name': app_bundle_id,
  341. 'registration_id': token_val,
  342. 'extra.channel_id': channel_id,
  343. 'extra.alert': msg_text,
  344. 'extra.msg': '',
  345. 'extra.sound': 'sound.aif',
  346. 'extra.zpush': '1',
  347. 'extra.received_at': n_time,
  348. 'extra.event_time': n_time,
  349. 'extra.event_type': event_type,
  350. 'extra.nickname': nickname,
  351. 'extra.uid': uid,
  352. 'extra.channel': channel,
  353. 'extra.jump_type': jump_type
  354. }
  355. # if image:
  356. # data['extra.notification_style_type'] = 2
  357. # data['extra.notification_bigPic_uri'] = image
  358. headers = {
  359. 'Authorization': 'key={}'.format(app_secret)
  360. }
  361. response = requests.post(url, data=data, headers=headers)
  362. LOGGER.info("小米推送返回值:{}".format(response.json()))
  363. assert response.status_code == 200
  364. return True
  365. except Exception as e:
  366. LOGGER.info("小米推送异常:{}".format(repr(e)))
  367. return False
  368. @staticmethod
  369. def android_vivopush(token_val, n_time, event_type, msg_title, msg_text, app_bundle_id='', uid='', channel='1',
  370. image='', nickname='', appBundleId='', jg_token_val=''):
  371. """
  372. vivo 推送(不支持图片)
  373. @param app_bundle_id: app包名
  374. @param appBundleId: app包名
  375. @param token_val: 推送token
  376. @param jg_token_val: 极光推送token
  377. @param event_type: 事件类型
  378. @param msg_title: 推送标题
  379. @param msg_text: 推送内容
  380. @param n_time: 当前时间
  381. @param nickname: 设备昵称
  382. @param uid: uid
  383. @param image: 推送图片链接
  384. @param channel: 通道
  385. @return: bool
  386. """
  387. try:
  388. app_bundle_id = app_bundle_id if app_bundle_id != '' else appBundleId
  389. # 获取redis里面的authToken
  390. if msg_title == '':
  391. msg_title = APP_BUNDLE_DICT[app_bundle_id]
  392. app_id = VIVOPUSH_CONFIG[app_bundle_id]['ID']
  393. app_key = VIVOPUSH_CONFIG[app_bundle_id]['Key']
  394. app_secret = VIVOPUSH_CONFIG[app_bundle_id]['Secret']
  395. sender = APISender(app_secret)
  396. rec = sender.get_token(app_id, app_key)
  397. # 鉴权接口调用获得authToken
  398. sender_send = APISender(app_secret)
  399. sender_send.set_token(rec['authToken'])
  400. # 跳转类型
  401. jump_type = CommonService.get_jump_type(event_type)
  402. push_data = {'alert': msg_text, 'msg': '', 'sound': 'sound.aif', 'zpush': '1', 'image': image,
  403. 'received_at': n_time, 'event_time': n_time, 'event_type': event_type, 'nickname': nickname,
  404. 'uid': uid, 'channel': channel, 'jump_type': jump_type
  405. }
  406. # 获取唯一标识符
  407. uid_push_qs = UidPushModel.objects.filter(token_val=token_val).values('m_code')
  408. m_code = uid_push_qs[0]['m_code'] if uid_push_qs[0]['m_code'] else ''
  409. # 推送 push_mode: 推送模式 (0:正式推送;1:测试推送,默认为0)
  410. # 推送 event_type: 消息类型 (0:运营类消息,1:系统类消息。默认为 0)
  411. # 推送 skip_type: 跳转类型(1:打开 APP 首页 2:打开链接 3:自定义 4:打开 app 内指定页面)
  412. activity = 'vpushscheme://com.vivo.pushvideo/detail'
  413. message = PushMessage() \
  414. .reg_id(token_val) \
  415. .title(msg_title) \
  416. .content(msg_text) \
  417. .push_mode(0) \
  418. .notify_type(3) \
  419. .skip_type(4) \
  420. .skip_content(activity) \
  421. .request_id(m_code) \
  422. .classification(1) \
  423. .client_custom_map(**push_data) \
  424. .message_dict()
  425. rec = sender_send.send(message)
  426. LOGGER.info('vivo推送结果:{}, 设备uid:{}'.format(rec, uid))
  427. if rec['result'] == 0 and event_type in EventTypeEnumObj.DATA_PUSH_EVENT_TYPE_LIST.value:
  428. PushObject.jpush_transparent_transmission(msg_title, msg_text, app_bundle_id, jg_token_val, push_data)
  429. return True
  430. except Exception as e:
  431. LOGGER.error('vivo推送异常,uid:{},error_line:{},error_msg:{}'.
  432. format(uid, e.__traceback__.tb_lineno, repr(e)))
  433. return False
  434. @staticmethod
  435. def android_oppopush(channel_id, nickname, app_bundle_id, token_val, n_time, event_type, msg_title, msg_text,
  436. uid='', channel='1', image='', jg_token_val=''):
  437. """
  438. android oppo 推送
  439. @param channel_id: 通知通道id
  440. @param nickname: 设备昵称
  441. @param app_bundle_id: app包id
  442. @param token_val: 推送token
  443. @param jg_token_val: 推送token
  444. @param n_time: 当前时间
  445. @param event_type: 事件类型
  446. @param msg_title: 推送标题
  447. @param msg_text: 推送内容
  448. @param uid: uid
  449. @param channel: 通道
  450. @param image: 推送图片链接
  451. @return: bool
  452. """
  453. try:
  454. """
  455. android 国内oppo APP消息提醒推送
  456. """
  457. app_key = OPPOPUSH_CONFIG[app_bundle_id]['Key']
  458. master_secret = OPPOPUSH_CONFIG[app_bundle_id]['Secret']
  459. url = 'https://api.push.oppomobile.com/'
  460. now_time = str(round(time.time() * 1000))
  461. # 1、实例化一个sha256对象
  462. sha256 = hashlib.sha256()
  463. # 2、调用update方法进行加密
  464. sha256.update((app_key + now_time + master_secret).encode('utf-8'))
  465. # 3、调用hexdigest方法,获取加密结果
  466. sign = sha256.hexdigest()
  467. # 获取auth_token
  468. get_token_url = url + 'server/v1/auth'
  469. post_data = {
  470. 'app_key': app_key,
  471. 'sign': sign,
  472. 'timestamp': now_time
  473. }
  474. headers = {'Content-Type': 'application/x-www-form-urlencoded'}
  475. response = requests.post(get_token_url, data=post_data, headers=headers)
  476. result = response.json()
  477. # 发送推送
  478. push_url = url + 'server/v1/message/notification/unicast'
  479. extra_data = {'alert': msg_text, 'msg': '', 'sound': 'sound.aif', 'zpush': '1',
  480. 'received_at': n_time, 'event_time': n_time, 'event_type': event_type, 'nickname': nickname,
  481. 'uid': uid, 'channel': channel
  482. }
  483. message = {
  484. "target_type": 2,
  485. "target_value": token_val,
  486. "notification": {
  487. "title": msg_title,
  488. "content": msg_text,
  489. 'channel_id': channel_id,
  490. 'action_parameters': extra_data,
  491. 'click_action_type': 1,
  492. 'click_action_activity': OPPOPUSH_CONFIG[app_bundle_id]['click_action_activity']
  493. }
  494. }
  495. push_data = {
  496. 'auth_token': result['data']['auth_token'],
  497. 'message': json.dumps(message)
  498. }
  499. response = requests.post(push_url, data=push_data, headers=headers)
  500. LOGGER.info("oppo推送返回值:{}".format(response.json()))
  501. if response.status_code == 200 and event_type in EventTypeEnumObj.DATA_PUSH_EVENT_TYPE_LIST.value:
  502. PushObject.jpush_transparent_transmission(msg_title, msg_text, app_bundle_id, jg_token_val, extra_data)
  503. return True
  504. except Exception as e:
  505. LOGGER.info("oppo推送异常:{}".format(repr(e)))
  506. return False
  507. @staticmethod
  508. def android_meizupush(token_val, n_time, event_type, msg_title, msg_text, uid='', channel='1',
  509. app_bundle_id='', appBundleId='', nickname='', image=''):
  510. """
  511. android 魅族推送(不支持图片)
  512. @param app_bundle_id: app包名
  513. @param appBundleId: app包名
  514. @param token_val: 推送token
  515. @param event_type: 消息类型 (0:运营类消息,1:系统类消息。默认为 0)
  516. @param msg_title: 推送标题
  517. @param msg_text: 推送内容
  518. @param n_time: 当前时间
  519. @param nickname: 设备昵称
  520. @param uid: uid
  521. @param image: 推送图片链接
  522. @param channel: 通道
  523. @return: bool
  524. """
  525. try:
  526. # 获取包和AppSecret
  527. app_bundle_id = app_bundle_id if app_bundle_id != '' else appBundleId
  528. appId = MEIZUPUSH_CONFIG[app_bundle_id]['ID']
  529. appSecret = MEIZUPUSH_CONFIG[app_bundle_id]['AppSecret']
  530. url = 'https://server-api-push.meizu.com/garcia/api/server/push/varnished/pushByPushId'
  531. # 跳转类型
  532. jump_type = CommonService.get_jump_type(event_type)
  533. extra_data = {'alert': msg_text, 'msg': '', 'sound': 'sound.aif', 'zpush': '1',
  534. 'received_at': n_time, 'event_time': n_time, 'event_type': event_type, 'nickname': nickname,
  535. 'uid': uid, 'channel': channel, 'jump_type': jump_type
  536. }
  537. # 转换为json格式
  538. extra_data = json.dumps(extra_data)
  539. if msg_title == '':
  540. msg_title = APP_BUNDLE_DICT[app_bundle_id]
  541. # 拼接发送内容
  542. activity = MEIZUPUSH_CONFIG[app_bundle_id]['click_action_activity']
  543. # clickType点击动作, 0打开应用, 1打开应用页面, 2打开url页面, 3应用客户端自定义
  544. messageJson = '{"clickTypeInfo": {"activity": "%s",' \
  545. '"clickType": 1, "parameters": %s },"extra": {},' % (activity, extra_data)
  546. noticeBarInfo = ('"noticeBarInfo": {"title": "%s", "content": "%s"},' % (msg_title, msg_text))
  547. noticeExpandInfo = '"noticeExpandInfo": {"noticeExpandType": 0}, "pushTimeInfo": {"validTime": 24}}'
  548. messageJson += noticeBarInfo
  549. messageJson += noticeExpandInfo
  550. data_meizu = {
  551. 'appId': appId,
  552. 'pushIds': token_val,
  553. 'messageJson': messageJson
  554. }
  555. # 魅族MD5加密,生成密钥
  556. sign = CommonService.getMD5Sign(data=data_meizu, key=appSecret)
  557. data = {
  558. 'appId': appId,
  559. 'messageJson': messageJson,
  560. 'sign': sign,
  561. 'pushIds': token_val,
  562. }
  563. # 进行推送
  564. response = requests.post(url, data=data)
  565. LOGGER.info("魅族推送结果:{}".format(response.json()))
  566. return True
  567. except Exception as e:
  568. LOGGER.info("魅族推送异常:{}".format(repr(e)))
  569. return False
  570. @staticmethod
  571. def android_honorpush(token_val, n_time, event_type, msg_title, msg_text,
  572. uid='', channel='1', image='', app_bundle_id='', appBundleId='', channel_id='', nickname=''):
  573. """
  574. android honor 推送
  575. @param channel_id: 通知通道id
  576. @param nickname: 设备昵称
  577. @param app_bundle_id: app包id
  578. @param appBundleId: app包id
  579. @param token_val: 推送token
  580. @param n_time: 当前时间
  581. @param event_type: 事件类型
  582. @param msg_title: 推送标题
  583. @param msg_text: 推送内容
  584. @param uid: uid
  585. @param channel: 通道
  586. @param image: 推送图片链接
  587. @return: bool
  588. """
  589. app_bundle_id = appBundleId if appBundleId else app_bundle_id
  590. try:
  591. client_id = HONORPUSH_CONFIG[app_bundle_id]['client_id']
  592. client_secret = HONORPUSH_CONFIG[app_bundle_id]['client_secret']
  593. app_id = HONORPUSH_CONFIG[app_bundle_id]['app_id']
  594. get_access_token_url = 'https://iam.developer.hihonor.com/auth/token'
  595. post_data = {
  596. 'grant_type': 'client_credentials',
  597. 'client_id': client_id,
  598. 'client_secret': client_secret
  599. }
  600. headers = {'Content-Type': 'application/x-www-form-urlencoded'}
  601. access_token_response = requests.post(get_access_token_url, data=post_data, headers=headers)
  602. access_result = access_token_response.json()
  603. authorization_token = 'Bearer ' + access_result['access_token']
  604. # 发送推送
  605. push_url = 'https://push-api.cloud.hihonor.com/api/v1/{}/sendMessage'.format(app_id)
  606. headers = {'Content-Type': 'application/json', 'Authorization': authorization_token,
  607. 'timestamp': str(int(time.time()) * 1000)}
  608. # 跳转类型
  609. jump_type = CommonService.get_jump_type(event_type)
  610. extra_data = {'alert': msg_text, 'msg': '', 'sound': 'sound.aif', 'zpush': '1',
  611. 'received_at': n_time, 'event_time': n_time, 'event_type': str(event_type),
  612. 'nickname': nickname, 'uid': uid, 'channel': channel, 'title': msg_title, 'body': msg_text,
  613. 'jump_type': jump_type
  614. }
  615. # 通知推送
  616. push_data = {
  617. "android": {
  618. "notification": {
  619. "body": msg_text,
  620. "title": msg_title,
  621. "importance": "NORMAL",
  622. "clickAction": {
  623. "type": 3,
  624. }
  625. },
  626. "targetUserType": 0,
  627. "data": json.dumps(extra_data)
  628. },
  629. "token": [token_val]
  630. }
  631. LOGGER.info("uid:{},时间:{},荣耀推送发送内容:{}".format(uid, n_time, push_data))
  632. response = requests.post(push_url, json=push_data, headers=headers)
  633. LOGGER.info("uid:{},时间:{},荣耀推送通知返回值:{}".format(uid, n_time, response.json()))
  634. # 一键通话透传推送
  635. if int(event_type) in EventTypeEnumObj.DATA_PUSH_EVENT_TYPE_LIST.value:
  636. push_data = {
  637. "data": json.dumps(extra_data),
  638. "token": [token_val]
  639. }
  640. response = requests.post(push_url, json=push_data, headers=headers)
  641. LOGGER.info("uid:{},时间:{},荣耀透传推送返回值:{}".format(uid, n_time, response.json()))
  642. return True
  643. except Exception as e:
  644. LOGGER.info("荣耀推送异常:error_line:{},error_msg:{}".format(e.__traceback__.tb_lineno, repr(e)))
  645. return False
  646. @staticmethod
  647. def jpush_transparent_transmission(msg_title, msg_text, app_bundle_id, token_val, extra_data):
  648. """
  649. android 极光透传
  650. @param msg_title: 推送标题
  651. @param msg_text: 推送内容
  652. @param token_val: 推送token
  653. @param app_bundle_id: app包id
  654. @param extra_data: 额外数据
  655. @return: None
  656. """
  657. try:
  658. app_key = JPUSH_CONFIG[app_bundle_id]['Key']
  659. master_secret = JPUSH_CONFIG[app_bundle_id]['Secret']
  660. # 换成各自的app_key和master_secret
  661. _jpush = jpush.JPush(app_key, master_secret)
  662. push = _jpush.create_push()
  663. push.audience = jpush.registration_id(token_val)
  664. push.message = jpush.message(msg_content=msg_text, title=msg_title, extras=extra_data)
  665. push.platform = jpush.all_
  666. res = push.send()
  667. LOGGER.info('极光透传,结果:{},参数:{}'.format(res, extra_data))
  668. except Exception as e:
  669. LOGGER.info('jpush_transparent_transmission极光透传异常:errLine:{}, errMsg:{}, 参数:{}'.format(
  670. e.__traceback__.tb_lineno, repr(e), extra_data))