WxEventPush.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. <?php
  2. namespace app\api\controller;
  3. use DOMDocument;
  4. use wx\offiaccount\Event;
  5. use wx\offiaccount\msg\ResponseMsg;
  6. use app\model\Employee;
  7. use think\facade\Cache;
  8. /**
  9. * 微信事件接受类
  10. */
  11. class WxEventPush
  12. {
  13. public function index()
  14. {
  15. $signature = $_GET['signature'];
  16. $timestamp = $_GET['timestamp'];
  17. $nonce = $_GET['nonce'];
  18. $token = config('app.official_token');
  19. $encodingAesKey = config('app.official_encodingAesKey');
  20. $appId = config('app.official_appid');
  21. $eventObj = new Event($token, $encodingAesKey, $appId);
  22. // token验证
  23. if (isset($_GET["echostr"])) {
  24. if ($eventObj->checkToken($token, $signature, $timestamp, $nonce)) {
  25. echo $_GET["echostr"];
  26. exit;
  27. }
  28. }
  29. // // 消息体加密
  30. $msgSignature = $_GET['msg_signature'];
  31. // 推送消息内容获取
  32. $postXml = file_get_contents('php://input');
  33. $rs = $eventObj->decryptMsg($msgSignature, $timestamp, $nonce, $postXml, $msg);
  34. if ($rs !== 0) {
  35. echo 'success';
  36. trace('消息内容解析失败:' . $postXml, "error");
  37. exit;
  38. }
  39. $xml = new DOMDocument();
  40. $xml->loadXML($msg);
  41. $msgType = $xml->getElementsByTagName('MsgType')->item(0)->nodeValue;
  42. $rs = null;
  43. switch ($msgType) {
  44. case "event":
  45. $event = $xml->getElementsByTagName('Event')->item(0)->nodeValue;
  46. $event = strtolower($event);
  47. $method = $event . 'Event';
  48. // 接受事件推送
  49. if (method_exists($this, $method)) {
  50. $rs = $this->$method($xml);
  51. }
  52. break;
  53. default:
  54. // 接受消息推送
  55. $rs = $this->$msgType($xml);
  56. break;
  57. }
  58. if ($rs === null) {
  59. echo 'success';
  60. exit;
  61. } else {
  62. echo $rs;
  63. exit;
  64. }
  65. }
  66. /**
  67. * 订阅(关注公众号或扫码关注公众号)
  68. */
  69. private function subscribeEvent($xml)
  70. {
  71. $fromUserName = $xml->getElementsByTagName('FromUserName')->item(0)->nodeValue;
  72. $toUserName = $xml->getElementsByTagName('ToUserName')->item(0)->nodeValue;
  73. // 获取key值
  74. // $key = $xml->getElementsByTagName('EventKey')->item(0)->nodeValue;
  75. // 更新用户信息
  76. $this->setUserInfo($fromUserName);
  77. // if ($key == '') { // 如果是用户关注公众号
  78. $textData = [
  79. 'ToUserName' => $fromUserName,
  80. 'FromUserName' => $toUserName,
  81. 'MsgType' => 'text',
  82. 'Content' => 'Hello![握手]
  83. 欢迎加入志远装饰大家庭!
  84. ①找客户→数十种裂变工具[强]
  85. ②聊客户→各维度沟通方案[强]
  86. ③签客户→定制化签单工具[强]
  87. ④跟客户→云CRM精准跟客[强]
  88. 通过小程序,我们为您提供一套完整的装企营销获客管理体系。[爱心][爱心][爱心]'
  89. ];
  90. $msg = new ResponseMsg();
  91. return $msg->responseText($textData);
  92. // } else { // 如果是识别二维码
  93. // // 用户绑定公司
  94. // list($keyName, $method, $val) = explode('_', $key);
  95. // if (method_exists($this, $method)) {
  96. // return $this->$method($val, $toUserName, $fromUserName);
  97. // }
  98. // }
  99. }
  100. /**
  101. * 取消订阅
  102. */
  103. private function unsubscribeEvent($xml)
  104. {
  105. $openid = $xml->getElementsByTagName('FromUserName')->item(0)->nodeValue;
  106. // 更新用户是否关注公众号
  107. Employee::where([['official_openid', '=', $openid]])->update(['official_openid'=>'']);
  108. }
  109. /**
  110. * 用户已关注时的事件推送(扫二维码)
  111. */
  112. private function scanEvent($xml)
  113. {
  114. $fromUserName = $xml->getElementsByTagName('FromUserName')->item(0)->nodeValue;
  115. $toUserName = $xml->getElementsByTagName('ToUserName')->item(0)->nodeValue;
  116. // 消息发送对象
  117. $key = $xml->getElementsByTagName('EventKey')->item(0)->nodeValue;
  118. // 是否是通过扫员工二维码绑定
  119. list($method, $val) = explode('_', $key);
  120. if (method_exists($this, $method)) {
  121. return $this->$method($val, $toUserName, $fromUserName);
  122. }
  123. }
  124. /**
  125. * 上报地理位置事件
  126. */
  127. private function locationEvent($xml)
  128. {
  129. $fromUserName = $xml->getElementsByTagName('FromUserName')->item(0)->nodeValue;
  130. $lat = $xml->getElementsByTagName('Latitude')->item(0)->nodeValue;
  131. $lng = $xml->getElementsByTagName('Longitude')->item(0)->nodeValue;
  132. // 更新用户是否关注公众号
  133. }
  134. /**
  135. * 点击菜单拉取消息时的事件推送
  136. */
  137. private function clickEvent($xml)
  138. {
  139. $fromUserName = $xml->getElementsByTagName('FromUserName')->item(0)->nodeValue;
  140. $toUserName = $xml->getElementsByTagName('ToUserName')->item(0)->nodeValue;
  141. // 消息发送对象
  142. $method = $xml->getElementsByTagName('EventKey')->item(0)->nodeValue;
  143. return $this->$method($toUserName, $fromUserName);
  144. }
  145. /**
  146. * 点击菜单跳转链接时的事件推送
  147. */
  148. private function viewEvent($xml)
  149. {
  150. }
  151. /**
  152. * 模板消息发送事件
  153. */
  154. private function templatesendjobfinish($xml){
  155. $fromUserName = $xml->getElementsByTagName('FromUserName')->item(0)->nodeValue;
  156. $status = $xml->getElementsByTagName('Statuss')->item(0)->nodeValue;
  157. trace('fromUserName:'.$fromUserName,'debug');
  158. trace('status:'.$status,'debug');
  159. }
  160. /**
  161. * 文本消息
  162. */
  163. private function text($xml)
  164. {
  165. }
  166. /**
  167. * 语音消息
  168. */
  169. private function voice($xml)
  170. {
  171. }
  172. /**
  173. * 视频消息
  174. */
  175. private function video($xml)
  176. {
  177. }
  178. /**
  179. * 小视频消息
  180. */
  181. private function shortvideo($xml)
  182. {
  183. }
  184. /**
  185. * 地理位置消息
  186. */
  187. private function location($xml)
  188. {
  189. }
  190. /**
  191. * 获取用户信息
  192. */
  193. private function setUserInfo($openid)
  194. {
  195. // 通过openid获取微信信息和unionid
  196. if (!$accessToken = Cache::get('zqxg_offi_access_token')) {
  197. $accessToken = getAccessToken(config('app.official_appid'), config('app.official_secret'));
  198. Cache::set('zqxg_offi_access_token', $accessToken, 7100);
  199. }
  200. $getUserInfoUrl = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token=' . $accessToken . '&openid=' . $openid . '&lang=zh_CN';
  201. $data = curl($getUserInfoUrl);
  202. $data = json_decode($data, true);
  203. if (isset($data['errcode']) || empty($data['openid'])) {
  204. trace('消息内容解析失败:' . json_encode($data), "error");
  205. return null;
  206. }
  207. // 更新official_openid
  208. Employee::where([['unionid', '=', $data['unionid']]])->update(['official_openid'=>$openid]);
  209. }
  210. }