LogoutPushController.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. # @Author : peng
  2. # @File : LogoutPushController.py
  3. # @Time : 2024年7月9日17:22:19
  4. import json
  5. import threading
  6. import time
  7. import requests
  8. from django.http import HttpResponse
  9. from django.views import View
  10. from Model.models import UidPushModel
  11. from Object.ResponseObject import ResponseObject
  12. from Service.PushService import PushObject
  13. from AnsjerPush.config import XM_PUSH_CHANNEL_ID, HONORPUSH_CONFIG
  14. from Service.HuaweiPushService.push_admin import messaging
  15. from AnsjerPush.config import LOGGER
  16. class LogoutPushView(View):
  17. def get(self, request, *args, **kwargs):
  18. request.encoding = 'utf-8'
  19. operation = kwargs.get('operation')
  20. return self.validation(request.GET, operation)
  21. def post(self, request, *args, **kwargs):
  22. request.encoding = 'utf-8'
  23. operation = kwargs.get('operation')
  24. return self.validation(request.POST, operation)
  25. def validation(self, request_dict, operation):
  26. response = ResponseObject()
  27. if operation == 'push': # 强制退出推送
  28. return self.logout_push(request_dict, response)
  29. @staticmethod
  30. def logout_push(request_dict, response):
  31. push_token = request_dict.get('push_token', None)
  32. user_id = request_dict.get('user_id', None)
  33. if not all([push_token, user_id]):
  34. return response.json(444)
  35. try:
  36. uid_push_qs = UidPushModel.objects.filter(userID=user_id).exclude(token_val=push_token).values(
  37. 'token_val', 'appBundleId', 'push_type', 'jg_token_val').distinct()
  38. if not uid_push_qs.exists():
  39. return response.json(173)
  40. push_thread = threading.Thread(target=LogoutPushView.thread_logout_push, args=(uid_push_qs, user_id,))
  41. push_thread.start()
  42. return response.json(0)
  43. except Exception as e:
  44. return HttpResponse(repr(e), status=500)
  45. @staticmethod
  46. def thread_logout_push(qs, user_id):
  47. title = '强制登出'
  48. content = '强制登出'
  49. now_time = int(time.time())
  50. for push_item in qs:
  51. kwargs = {
  52. 'nickname': user_id,
  53. 'app_bundle_id': push_item['appBundleId'],
  54. 'token_val': push_item['token_val'],
  55. 'n_time': now_time,
  56. 'event_type': '',
  57. 'msg_title': title,
  58. 'msg_text': content,
  59. }
  60. if push_item['push_type'] == 0: # 苹果
  61. PushObject.ios_apns_push(**kwargs)
  62. elif push_item['push_type'] == 1: # 谷歌
  63. PushObject.android_fcm_push_v1(**kwargs)
  64. elif push_item['push_type'] == 2: # 极光
  65. PushObject.jpush_transparent_transmission(title, content, push_item['appBundleId'],
  66. push_item['token_val'], kwargs)
  67. elif push_item['push_type'] == 3: # 华为
  68. LogoutPushView.huawei_transparent_transmission(user_id=user_id, **kwargs)
  69. elif push_item['push_type'] == 4: # 小米
  70. channel_id = XM_PUSH_CHANNEL_ID['device_reminder']
  71. PushObject.android_xmpush(channel_id=channel_id, **kwargs)
  72. elif push_item['push_type'] in [5, 6]: # vivo, oppo
  73. kwargs['token_val'] = push_item['jg_token_val']
  74. PushObject.jpush_transparent_transmission(title, content, push_item['appBundleId'],
  75. push_item['jg_token_val'], kwargs)
  76. elif push_item['push_type'] == 7: # 魅族
  77. PushObject.android_meizupush(**kwargs)
  78. elif push_item['push_type'] == 8: # 荣耀
  79. LogoutPushView.honor_transparent_transmission(**kwargs)
  80. @staticmethod
  81. def huawei_transparent_transmission(nickname, app_bundle_id, token_val, n_time, event_type, msg_title,
  82. msg_text, user_id):
  83. """
  84. 发送透传推送
  85. @param nickname:
  86. @param app_bundle_id:
  87. @param event_type:
  88. @param n_time:
  89. @param token_val:
  90. @param msg_title:
  91. @param msg_text:
  92. @param user_id:
  93. @return: None
  94. """
  95. data = {
  96. 'nickname': nickname, 'event_type': event_type, 'event_time': n_time, 'msg_title': msg_title,
  97. 'msg_text': msg_text
  98. }
  99. data = json.dumps(data)
  100. android = messaging.AndroidConfig(
  101. collapse_key=-1,
  102. urgency=messaging.AndroidConfig.HIGH_PRIORITY,
  103. ttl='10000s',
  104. bi_tag='the_sample_bi_tag_for_receipt_service'
  105. )
  106. message = messaging.Message(
  107. data=data,
  108. android=android,
  109. token=[token_val]
  110. )
  111. try:
  112. import certifi
  113. response = messaging.send_message(message, verify_peer=certifi.where())
  114. LOGGER.info('{}退出登录,华为透传推送响应: {}'.format(user_id, json.dumps(vars(response))))
  115. assert (response.code == '80000000')
  116. except Exception as e:
  117. LOGGER.info('退出登录,华为透传推送异常: {}'.format(repr(e)))
  118. @staticmethod
  119. def honor_transparent_transmission(token_val, n_time, event_type, msg_title, msg_text, app_bundle_id, nickname=''):
  120. """
  121. android honor 推送
  122. @param nickname: 设备昵称
  123. @param app_bundle_id: app包id
  124. @param token_val: 推送token
  125. @param n_time: 当前时间
  126. @param event_type: 事件类型
  127. @param msg_title: 推送标题
  128. @param msg_text: 推送内容
  129. @return: bool
  130. """
  131. try:
  132. client_id = HONORPUSH_CONFIG[app_bundle_id]['client_id']
  133. client_secret = HONORPUSH_CONFIG[app_bundle_id]['client_secret']
  134. app_id = HONORPUSH_CONFIG[app_bundle_id]['app_id']
  135. get_access_token_url = 'https://iam.developer.hihonor.com/auth/token'
  136. post_data = {
  137. 'grant_type': 'client_credentials',
  138. 'client_id': client_id,
  139. 'client_secret': client_secret
  140. }
  141. headers = {'Content-Type': 'application/x-www-form-urlencoded'}
  142. access_token_response = requests.post(get_access_token_url, data=post_data, headers=headers)
  143. access_result = access_token_response.json()
  144. authorization_token = 'Bearer ' + access_result['access_token']
  145. # 发送推送
  146. push_url = 'https://push-api.cloud.hihonor.com/api/v1/{}/sendMessage'.format(app_id)
  147. headers = {'Content-Type': 'application/json', 'Authorization': authorization_token,
  148. 'timestamp': str(int(time.time()) * 1000)}
  149. extra_data = {'alert': 'Motion', 'msg': '', 'sound': 'sound.aif', 'zpush': '1',
  150. 'received_at': n_time, 'event_time': n_time, 'event_type': str(event_type),
  151. 'nickname': nickname, 'title': msg_title, 'body': msg_text}
  152. # 透传推送
  153. push_data = {
  154. "data": json.dumps(extra_data),
  155. "token": [token_val]
  156. }
  157. response = requests.post(push_url, json=push_data, headers=headers)
  158. LOGGER.info("用户:{},时间:{},荣耀透传推送返回值:{}".format(nickname, n_time, response.json()))
  159. return True
  160. except Exception as e:
  161. LOGGER.info("荣耀推送异常:error_line:{},error_msg:{}".format(e.__traceback__.tb_lineno, repr(e)))
  162. return False