PushService.py 27 KB

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