| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- <?php
- namespace App\Channels;
- use App\Channels\Components\WeChat;
- use Cache;
- use Helpers;
- use Http;
- use Illuminate\Http\Request;
- use Illuminate\Notifications\Notification;
- use Log;
- use Str;
- class WeChatChannel
- {
- private $access_token;
- public function __construct()
- {
- $this->access_token = $this->getAccessToken();
- }
- private function getAccessToken()
- {
- if (Cache::has('wechat_access_token')) {
- $access_token = Cache::get('wechat_access_token');
- } else {
- // https://work.weixin.qq.com/api/doc/90000/90135/91039
- $response = Http::get('https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid='.sysConfig('wechat_cid').'&corpsecret='.sysConfig('wechat_secret'));
- if ($response->ok() && isset($response->json()['access_token'])) {
- $access_token = $response->json()['access_token'];
- Cache::put('wechat_access_token', $response->json()['access_token'], 7200); // 2小时
- } else {
- Log::critical('Wechat消息推送异常:获取access_token失败!'.PHP_EOL.'携带访问参数:'.$response->body());
- abort(400);
- }
- }
- return $access_token ?? null;
- }
- public function send($notifiable, Notification $notification)
- { // route('message.show', ['type' => 'markdownMsg', 'msgId' => ''])
- $message = $notification->toCustom($notifiable);
- if (! $this->access_token) {
- $this->access_token = $this->getAccessToken();
- }
- $url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token='.$this->access_token;
- if (isset($message['button'])) { // 按钮交互型
- // https://work.weixin.qq.com/api/doc/90000/90135/90236#%E6%8C%89%E9%92%AE%E4%BA%A4%E4%BA%92%E5%9E%8B
- $body = [
- 'touser' => '@all',
- 'msgtype' => 'template_card',
- 'agentid' => sysConfig('wechat_aid'),
- 'template_card' => [
- 'card_type' => 'button_interaction',
- 'main_title' => ['title' => $message['title']],
- 'horizontal_content_list' => $message['body'],
- 'task_id' => time().Str::random(),
- 'button_list' => [
- [
- 'type' => 1,
- 'text' => '否 決',
- 'style' => 3,
- 'url' => $message['button'][0],
- ],
- [
- 'type' => 1,
- 'text' => '确 认',
- 'style' => 1,
- 'url' => $message['button'][1],
- ],
- ],
- ],
- ];
- } elseif (isset($message['url_type'])) { // 文本卡片
- $msgId = Str::uuid(); // 生成对公消息查询URL
- $body = [
- 'touser' => '@all',
- 'agentid' => sysConfig('wechat_aid'),
- 'msgtype' => 'textcard',
- 'textcard' => [
- 'title' => $message['title'],
- 'description' => '请点击下方按钮【查看详情】',
- 'url' => route('message.show', ['type' => $message['url_type'], $msgId]),
- 'btntxt' => '查看详情',
- ],
- ];
- } else { // 文本消息
- $body = [
- 'touser' => '@all',
- 'agentid' => sysConfig('wechat_aid'),
- 'msgtype' => 'text',
- 'text' => ['content' => $message['content']],
- 'duplicate_check_interval' => 600,
- ];
- }
- $response = Http::timeout(15)->withBody(json_encode($body, JSON_UNESCAPED_UNICODE), 'application/json; charset=utf-8')->post($url);
- // 发送成功
- if ($response->ok()) {
- $ret = $response->json();
- if (! $ret['errcode'] && $ret['errmsg'] === 'ok') {
- Helpers::addNotificationLog($message['title'], $message['content'] ?? var_export($message['body'], true), 5, 1, null, $msgId ?? null);
- return $ret;
- }
- // 发送失败
- Helpers::addNotificationLog($message['title'], $message['content'] ?? var_export($message['body'], true), 5, -1, $ret ? $ret['errmsg'] : '未知');
- return false;
- }
- // 发送错误
- Log::critical('Wechat消息推送异常:'.var_export($response, true));
- return false;
- }
- public function verify(Request $request)
- {
- $errCode = (new WeChat())->VerifyURL($request->input('msg_signature'), $request->input('timestamp'), $request->input('nonce'), $request->input('echostr'), $sEchoStr);
- if ($errCode === 0) {
- exit($sEchoStr);
- }
- Log::critical('Wechat互动消息推送异常:'.var_export($errCode, true));
- }
- }
|