更新
This commit is contained in:
@@ -14,6 +14,15 @@ use think\facade\Log;
|
||||
* 企业微信「客户联系」事件回调(接收事件服务器)
|
||||
*
|
||||
* @see https://developer.work.weixin.qq.com/document/path/92130
|
||||
*
|
||||
* ⚠️ 关于"员工↔客户消息内容"接收:
|
||||
* 企业微信 **不会** 通过本回调推送客户与员工之间真实的聊天消息内容,
|
||||
* 这里只处理"添加 / 编辑 / 删除客户"等业务事件(change_external_contact 变体)。
|
||||
* 实时消息接收走「会话内容存档」独立通道:
|
||||
* - 命令: php think qywx:sync-msg-archive
|
||||
* - 服务: app\common\service\wechat\QywxMsgArchiveService
|
||||
* - SDK: app\common\service\wechat\WeComFinanceSdkClient (FFI 调 libWeWorkFinanceSdk_C.so)
|
||||
* 配置项:pay.wechat_work.msgaudit_*。
|
||||
*/
|
||||
class QywxExternalContactCallbackController extends BaseApiController
|
||||
{
|
||||
@@ -23,12 +32,16 @@ class QywxExternalContactCallbackController extends BaseApiController
|
||||
public function notify()
|
||||
{
|
||||
$corpId = (string) config('pay.wechat_work.corp_id', '');
|
||||
$secret = (string) config('pay.wechat_work.external_pay_secret', '');
|
||||
$customerSecret = (string) config('pay.wechat_work.customer_contact_secret', '');
|
||||
$payContactSecret = (string) config('pay.wechat_work.external_pay_secret', '');
|
||||
// 客户联系回调验签需用「接收事件服务器」所属应用的 Secret,优先使用 customer_contact_secret,
|
||||
// 缺省回退到 external_pay_secret 保持向后兼容(同一应用同时具备两类权限的旧部署可继续工作)。
|
||||
$secret = $customerSecret !== '' ? $customerSecret : $payContactSecret;
|
||||
$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');
|
||||
Log::error('qywx external contact callback: 缺少配置 corp_id / customer_contact_secret(或 external_pay_secret) / contact_callback_token / contact_callback_aes_key');
|
||||
|
||||
return response('config error', 503, ['Content-Type' => 'text/plain; charset=utf-8']);
|
||||
}
|
||||
@@ -84,14 +97,27 @@ class QywxExternalContactCallbackController extends BaseApiController
|
||||
{
|
||||
$changeType = (string) ($message['ChangeType'] ?? '');
|
||||
$extId = trim((string) ($message['ExternalUserID'] ?? $message['ExternalUserId'] ?? ''));
|
||||
$userId = trim((string) ($message['UserID'] ?? $message['UserId'] ?? ''));
|
||||
$state = (string) ($message['State'] ?? '');
|
||||
$welcomeCode = (string) ($message['WelcomeCode'] ?? '');
|
||||
$failReason = (string) ($message['FailReason'] ?? '');
|
||||
|
||||
if ($extId === '') {
|
||||
Log::info('qywx external contact callback: 无 ExternalUserID', ['ChangeType' => $changeType]);
|
||||
Log::info(sprintf('qywx external contact callback: 无 ExternalUserID type=%s user=%s', $changeType, $userId));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Log::info('qywx external contact callback', ['ChangeType' => $changeType, 'ExternalUserID' => $extId]);
|
||||
// 关键字段直接拼到消息里,便于在 ThinkPHP file 日志格式下一眼定位 ChangeType 分布
|
||||
Log::info(sprintf(
|
||||
'qywx external contact callback type=%s user=%s ext=%s state=%s welcome=%s fail=%s',
|
||||
$changeType !== '' ? $changeType : '-',
|
||||
$userId !== '' ? $userId : '-',
|
||||
$extId,
|
||||
$state !== '' ? $state : '-',
|
||||
$welcomeCode !== '' ? '***' : '-',
|
||||
$failReason !== '' ? $failReason : '-'
|
||||
));
|
||||
|
||||
if ($changeType === 'del_external_contact') {
|
||||
CustomerLogic::softDeleteExternalContactRow($extId);
|
||||
@@ -99,7 +125,15 @@ class QywxExternalContactCallbackController extends BaseApiController
|
||||
return;
|
||||
}
|
||||
|
||||
// 其余变更(添加/编辑/删跟进人等):以 get 详情为准 UPSERT,避免遗漏未枚举的 ChangeType
|
||||
if ($changeType === 'add_half_external_contact') {
|
||||
// 半客户:客户尚未通过验证,/externalcontact/get 通常返回 84061「客户尚未通过」之类,
|
||||
// 这里只 log 不写库,避免产生 noise;客户通过后会再触发 add_external_contact 事件再走 UPSERT。
|
||||
Log::info(sprintf('qywx external contact callback: half add,跳过落库 ext=%s user=%s', $extId, $userId));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 其余变更(添加/编辑/删跟进人/转接成功/标签变化等):以 get 详情为准 UPSERT,避免遗漏未枚举的 ChangeType
|
||||
CustomerLogic::upsertSingleExternalContactFromApi($extId);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user