123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- <?php
- namespace App\Jobs\WechatPlatform;
- use App\Service\Util\Support\Trace\TraceContext;
- use App\Service\WechatPlatform\GZHSendKFMessageService;
- use App\Service\WechatPlatform\WechatPlatform;
- use EasyWeChat\OfficialAccount\Application;
- use Illuminate\Bus\Queueable;
- use Illuminate\Contracts\Queue\ShouldBeUnique;
- use Illuminate\Contracts\Queue\ShouldQueue;
- use Illuminate\Foundation\Bus\Dispatchable;
- use Illuminate\Queue\InteractsWithQueue;
- use Illuminate\Queue\SerializesModels;
- use Illuminate\Support\Facades\DB;
- class GZHSendKFMessage implements ShouldQueue
- {
- use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
- /**
- * @var
- * <pre>
- * [
- * 'gzhId' => $gzhId, // wechat_authorization_infos.id
- * 'messageId' => $item->id, // wechat_kf_messages.id
- * 'traceInfo' => $traceContext->getTraceInfo() // traceInfo
- * ]
- * </pre>
- */
- private $info;
- /**
- * @var TraceContext
- */
- private $traceContext;
- /**
- * Create a new job instance.
- */
- public function __construct($info)
- {
- $this->info = $info;
- }
- /**
- * Execute the job.
- */
- public function handle(): void
- {
- $this->traceContext = TraceContext::newFromParent($this->info['traceInfo']);
- myLog('KFMessageSend')->info('公众号开始发送客服消息', [
- 'info' => $this->info,
- 'traceInfo' => $this->traceContext->getTraceInfo(),
- ]);
- $gzh = $this->getGZH();
- if(!$gzh) return;
- $message = $this->getMessage();
- if(!$message) return;
- $messageContent = collect(\json_decode($message->message_content, true));
- $messageStr = $messageContent->pluck('text')->join("\n");
- $officialAccount = $this->getOfficialAccount($gzh);
- if(false === $officialAccount) return;
- if($this->info['isTest'] ?? false) {
- $openid = $this->info['openid'] ?? '';
- if(!$openid) {
- myLog('KFMessageSend')->error('测试回传没有openid', [
- 'info' => $this->info
- ]);
- }
- GZHSendKFMessageService::sendText($officialAccount, $openid, $messageStr, $this->traceContext);
- } else {
- $next_openid = '';
- $loop = 1;
- while (true) {
- if($loop++ > 10000) {
- break;
- }
- if(1 == $message->u_type) {
- $info = $this->getUserOpenids($officialAccount, $next_openid);
- foreach ($info['openid'] as $opid){
- GZHSendKFMessageService::sendText($officialAccount, $opid, $messageStr, $this->traceContext);
- }
- $next_openid = $info['next_openid'];
- if(!$next_openid) {
- break;
- }
- } elseif (2 == $message->u_type) {
- // todo, 从人群包中获取.
- }
- }
- }
- }
- private function getMessage() {
- $message = DB::table('wechat_kf_messages')
- ->where('id', $this->info['messageId'])
- ->first();
- if(!$message) {
- myLog('KFMessageSend')->error('消息不存在', [
- 'info' => $this->info,
- 'traceInfo' => $this->traceContext->getTraceInfo(),
- ]);
- return false;
- }
- if(1 != $message->message_type) {
- myLog('KFMessageSend')->error('不支持的消息类型', [
- 'info' => $this->info,
- 'traceInfo' => $this->traceContext->getTraceInfo(),
- ]);
- return false;
- }
- return $message;
- }
- /**
- *
- * @param $officialAccount Application
- */
- private function getUserOpenids($officialAccount, $next_openid) {
- $result = $officialAccount->getClient()
- ->get('cgi-bin/user/get', [
- 'query' => [
- 'next_openid' => $next_openid,
- ]
- ])->toArray();
- if(0 != ($result['errcode'] ?? 0)) {
- return false;
- }
- return $result;
- }
- /**
- * 获取公众号调用对象
- * @param $gzh
- * @return \EasyWeChat\OfficialAccount\Application
- * @throws \EasyWeChat\Kernel\Exceptions\BadResponseException
- * @throws \EasyWeChat\Kernel\Exceptions\HttpException
- * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
- * @throws \Psr\SimpleCache\InvalidArgumentException
- * @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
- * @throws \Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface
- * @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
- * @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
- * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
- */
- private function getOfficialAccount($gzh) {
- try{
- return WechatPlatform::buildApplication($gzh)
- ->getOfficialAccountWithRefreshToken($gzh->authorizer_appid, $gzh->authorizer_refresh_token);
- } catch (\Throwable $exception) {
- myLog('KFMessageSend')->error('获取公众号调用对象失败', [
- 'exceptionMessage' => $exception->getMessage(),
- 'traceInfo' => $this->traceContext->getTraceInfo()
- ]);
- return false;
- }
- }
- private function getGZH() {
- $gzh = DB::table('wechat_authorization_infos as a')
- ->join('wechat_open_platform_infos as b', 'a.component_appid', 'b.app_id')
- ->where([
- ['a.id', '=', $this->info['gzhId']],
- ['a.is_enabled', '=', 1],
- ['b.is_enabled', '=', 1]
- ])->select('a.authorizer_appid', 'a.authorizer_refresh_token', 'b.app_id', 'b.secret', 'b.token', 'b.aes_key')
- ->first();
- if(!$gzh) {
- myLog('KFMessageSend')->error('公众号不可用', [
- 'traceInfo' => $this->traceContext->getTraceInfo(),
- ]);
- }
- return $gzh;
- }
- }
|