JPushService.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. <?php
  2. namespace App\Services;
  3. use Illuminate\Support\Facades\Log;
  4. use JPush\Client;
  5. use PHPUnit\Util\Exception;
  6. class JPushService
  7. {
  8. protected static $client = null;
  9. //推送类型
  10. const PUSH_TYPE_ALL = 1;
  11. const PUSH_TYPE_TAG = 2;
  12. const PUSH_TYPE_ALIAS = 3;
  13. const PUSH_TYPE_REG_ID = 4;
  14. const JG_YJDL_POST_URL = 'https://api.verification.jpush.cn/v1/web/loginTokenVerify';
  15. private function __construct()
  16. {
  17. }
  18. private function __clone()
  19. {
  20. }
  21. /**
  22. * 获取实例
  23. */
  24. public static function getInstance()
  25. {
  26. if (!self::$client) {
  27. self::$client = new Client(config('jpush.app_key'), config('jpush.master_secret'), null);
  28. }
  29. return self::$client;
  30. }
  31. /**
  32. * 给android或ios推送消息
  33. */
  34. public static function pushNotify($params)
  35. {
  36. //推送平台
  37. $platform = $params['platform'] ?? 'all';
  38. //推送标题
  39. $title = $params['title'] ?? '';
  40. //推送内容
  41. $content = $params['content'] ?? '';
  42. //通知栏样式ID
  43. $builder_id = $params['builder_id'] ?? 0;
  44. //附加字段
  45. $extras = $params['extras'] ?? '';
  46. //推送类型
  47. $type = $params['type'] ?? '';
  48. //推送目标(注册ID)
  49. $reg_id = $params['reg_id'] ?? '';
  50. //推送目标(标签)
  51. $tag = $params['tag'] ?? '';
  52. //推送目标(别名)
  53. $alias = $params['alias'] ?? '';
  54. $large_icon = $params['image'] ?? '';
  55. try {
  56. $push = self::getInstance()->push();
  57. //设置平台
  58. $push->setPlatform($platform);
  59. switch ($type) {
  60. case self::PUSH_TYPE_ALL:
  61. $push->addAllAudience();
  62. break;
  63. case self::PUSH_TYPE_TAG:
  64. $push->addTag($tag);
  65. break;
  66. case self::PUSH_TYPE_ALIAS:
  67. $push->addAlias($alias);
  68. break;
  69. case self::PUSH_TYPE_REG_ID:
  70. $push->addRegistrationId($reg_id);
  71. break;
  72. }
  73. $push->androidNotification($content, [
  74. 'title' => $title,
  75. 'builder_id' => $builder_id,
  76. 'extras' => $extras,
  77. 'large_icon' => $large_icon
  78. ])->iosNotification($content, [
  79. 'sound' => 'sound',
  80. 'badge' => '+1',
  81. 'extras' => $extras,
  82. // 'large_icon' => $params['image']
  83. ])->options([
  84. 'apns_production' => config('jpush.apns_production', true),
  85. //表示离线消息保留时长(秒)
  86. 'time_to_live' => 86400,
  87. ]);
  88. $response = $push->send();
  89. if ($response['http_code'] != 200) {
  90. Log::channel('jpush')->error(json_encode($response, JSON_UNESCAPED_UNICODE));
  91. }
  92. return $response;
  93. } catch (\Throwable $e) {
  94. Log::channel('jpush')->error(json_encode([
  95. 'file' => $e->getFile(),
  96. 'line' => $e->getLine(),
  97. 'message' => $e->getMessage(),
  98. 'params' => $params,
  99. ], JSON_UNESCAPED_UNICODE));
  100. }
  101. }
  102. /**
  103. * 获取指定设备的别名和标签
  104. */
  105. public static function getDevices($reg_id)
  106. {
  107. $response = self::getInstance()->device()->getDevices($reg_id);
  108. if ($response['http_code'] == 200) {
  109. return $response['body'];
  110. }
  111. return [];
  112. }
  113. /**
  114. * 给指定设备添加标签
  115. */
  116. public static function addTags($reg_id, $tags = [])
  117. {
  118. $response = self::getInstance()->device()->addTags($reg_id, $tags);
  119. if ($response['http_code'] == 200) {
  120. return true;
  121. }
  122. return false;
  123. }
  124. /**
  125. * 清空指定设备的标签
  126. */
  127. public static function clearTags($reg_id)
  128. {
  129. $response = self::getInstance()->device()->clearTags($reg_id);
  130. if ($response['http_code'] == 200) {
  131. return true;
  132. }
  133. return false;
  134. }
  135. /**
  136. * 清空指定设备的标签
  137. */
  138. public static function removeTags($reg_id, $tags = [])
  139. {
  140. $response = self::getInstance()->device()->removeTags($reg_id, $tags);
  141. if ($response['http_code'] == 200) {
  142. return true;
  143. }
  144. return false;
  145. }
  146. /**
  147. * 更新指定设备的别名
  148. */
  149. public static function updateAlias($reg_id, $alias)
  150. {
  151. $response = self::getInstance()->device()->updateAlias($reg_id, $alias);
  152. if ($response['http_code'] == 200) {
  153. return true;
  154. }
  155. return false;
  156. }
  157. /**
  158. * jgOpensslPrivateDecrypt($encrypted) (加密) 手机号码解密获取手机号
  159. * @param $encrypted string (加密) 手机号码
  160. * @param
  161. *
  162. * @return string 手机号|false
  163. * err:错误信息
  164. *
  165. */
  166. public static function jgOpensslPrivateDecrypt($encrypted){
  167. $prefix = '-----BEGIN RSA PRIVATE KEY-----';
  168. $suffix = '-----END RSA PRIVATE KEY-----';
  169. $result = '';
  170. $prikey = config('jpush.jg_yjdl_private_rsa');
  171. $key = $prefix . "\n" . $prikey . "\n" . $suffix;//拼接换行符
  172. $r = openssl_private_decrypt(base64_decode($encrypted), $result, openssl_pkey_get_private($key));
  173. if($r){
  174. return $result;
  175. }else{
  176. return false;
  177. throw new Exception("解密失败");
  178. }
  179. }
  180. /**
  181. * jgLoginTokenVerify($token) 提交loginToken,验证后返回手机号码(加密)
  182. * @param $token string 认证SDK获取到的loginToken
  183. * @param $exId 开发者自定义的id,非必填
  184. *
  185. * @return array 手机号
  186. * err:错误信息
  187. *
  188. */
  189. public static function jgLoginTokenVerify($token,$exId)
  190. {
  191. $host = self::JG_YJDL_POST_URL;
  192. $method = "POST";
  193. // $appcode = VERIFY_APPCODE;
  194. $headers = array();
  195. array_push($headers, "Authorization: Basic " .base64_encode(config('jpush.app_key').':'.config('jpush.master_secret')));
  196. //根据API的要求,定义相对应的Content-Type
  197. array_push($headers, "Content-Type".":"."application/json");
  198. $data = json_encode(["loginToken"=>$token,"exId"=>$exId]);
  199. $curl = curl_init();
  200. curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
  201. curl_setopt($curl, CURLOPT_URL, $host);
  202. curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  203. curl_setopt($curl, CURLOPT_FAILONERROR, false);
  204. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  205. curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
  206. //设定返回信息中是否包含响应信息头,启用时会将头文件的信息作为数据流输出,true 表示输出信息头, false表示不输出信息头
  207. //如果需要将字符串转成json,请将 CURLOPT_HEADER 设置成 false
  208. curl_setopt($curl, CURLOPT_HEADER, false);
  209. $ret = curl_exec($curl);
  210. $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  211. // file_put_contents(PATH_USER_JG_LOGIN_LOG.date('Y-m-d').'.log', date('Y-m-d H:i:s').$ret.PHP_EOL,FILE_APPEND);//写入文件 常量需要自己在定义
  212. $ret = json_decode($ret,true);
  213. if ($ret['code'] == 8000) {
  214. // if($ret['exID']!=$exId){
  215. // throw new Exception("exID 返回与发送不一致");
  216. // }
  217. } else {
  218. //throw new Exception($ret['code'].":请重试");
  219. throw new Exception($ret['code'].':'.$ret['content']);
  220. }
  221. return $ret;
  222. }
  223. //通过别名发送:
  224. //JPushService::pushNotify([
  225. //'title' => '测试',
  226. //'content' => '测试',
  227. //'alias' => 'user_id_' . $user_id,
  228. //'extras' => $extras,
  229. //'type' => JPushService::PUSH_TYPE_ALIAS,
  230. //]);
  231. }