更新
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\adminapi\logic\qywx\CustomerLogic;
|
||||
use EasyWeChat\Kernel\Exceptions\BadRequestException;
|
||||
use EasyWeChat\Work\Application;
|
||||
use EasyWeChat\Work\Message;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 企业微信「客户联系」事件回调(接收事件服务器)
|
||||
*
|
||||
* @see https://developer.work.weixin.qq.com/document/path/92130
|
||||
*/
|
||||
class QywxExternalContactCallbackController extends BaseApiController
|
||||
{
|
||||
/** 免登录:企微服务器回调 */
|
||||
public array $notNeedLogin = ['notify'];
|
||||
|
||||
public function notify()
|
||||
{
|
||||
$corpId = (string) config('pay.wechat_work.corp_id', '');
|
||||
$secret = (string) config('pay.wechat_work.external_pay_secret', '');
|
||||
$token = (string) config('pay.wechat_work.contact_callback_token', '');
|
||||
$aesKey = (string) config('pay.wechat_work.contact_callback_aes_key', '');
|
||||
|
||||
if ($corpId === '' || $secret === '' || $token === '' || $aesKey === '') {
|
||||
Log::error('qywx external contact callback: 缺少配置 corp_id / external_pay_secret / contact_callback_token / contact_callback_aes_key');
|
||||
|
||||
return response('config error', 503, ['Content-Type' => 'text/plain; charset=utf-8']);
|
||||
}
|
||||
|
||||
try {
|
||||
$app = new Application([
|
||||
'corp_id' => $corpId,
|
||||
'secret' => $secret,
|
||||
'token' => $token,
|
||||
'aes_key' => $aesKey,
|
||||
]);
|
||||
$server = $app->getServer();
|
||||
|
||||
$server->addEventListener('change_external_contact', function (Message $message, \Closure $next) {
|
||||
try {
|
||||
$this->handleChangeExternalContact($message);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('qywx external contact callback: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
]);
|
||||
}
|
||||
|
||||
return $next($message);
|
||||
});
|
||||
|
||||
$psr = $server->serve();
|
||||
$body = $psr->getBody();
|
||||
$body->rewind();
|
||||
$content = $body->getContents();
|
||||
|
||||
$headers = [];
|
||||
$contentType = $psr->getHeaderLine('Content-Type');
|
||||
if ($contentType !== '') {
|
||||
$headers['Content-Type'] = $contentType;
|
||||
}
|
||||
|
||||
return response($content, 200, $headers);
|
||||
} catch (BadRequestException $e) {
|
||||
Log::warning('qywx external contact callback: bad request ' . $e->getMessage());
|
||||
|
||||
return response('bad request', 400, ['Content-Type' => 'text/plain; charset=utf-8']);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('qywx external contact callback: serve failed ' . $e->getMessage(), ['exception' => $e]);
|
||||
|
||||
return response('error', 500, ['Content-Type' => 'text/plain; charset=utf-8']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Message $message
|
||||
*/
|
||||
private function handleChangeExternalContact($message): void
|
||||
{
|
||||
$changeType = (string) ($message['ChangeType'] ?? '');
|
||||
$extId = trim((string) ($message['ExternalUserID'] ?? $message['ExternalUserId'] ?? ''));
|
||||
|
||||
if ($extId === '') {
|
||||
Log::info('qywx external contact callback: 无 ExternalUserID', ['ChangeType' => $changeType]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Log::info('qywx external contact callback', ['ChangeType' => $changeType, 'ExternalUserID' => $extId]);
|
||||
|
||||
if ($changeType === 'del_external_contact') {
|
||||
CustomerLogic::softDeleteExternalContactRow($extId);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 其余变更(添加/编辑/删跟进人等):以 get 详情为准 UPSERT,避免遗漏未枚举的 ChangeType
|
||||
CustomerLogic::upsertSingleExternalContactFromApi($extId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user