# 企业微信通讯录配置项使用逻辑与回调域名替代方案 Spec ## Why 现网企业微信通讯录/客户联系能力依赖“接收事件服务器”回调地址(如 `https://shop.douba.top/api/work/serve`)来接收成员/部门/客户等变更事件。实际部署中可能遇到企业微信后台无法填写或无法通过校验(域名限制、HTTPS 证书、网络可达性、网关/WAF 等)导致无法上线。 本 Spec 的目标是: - 梳理后端企业微信通讯录相关配置项在代码中的读取、组装与使用路径,便于定位配置错误。 - 给出当企业微信侧无法配置项目域名时的可行替代配置方式(运维/网络层方案 + 业务层降级方案)。 - (可选增强)提供独立的“企业微信回调地址”配置项,仅用于展示与复制,避免必须修改全站 `site_url`。 ## Current Behavior(现状) ### 1) 回调路由入口 - 企业微信回调入口固定为 `/api/work/serve`,路由映射到 `app\controller\api\v1\wechat\Wechat::work()`,最终调用 `crmeb\services\wechat\Work::serve()`。 - 后台配置表单中“服务器地址”字段为只读展示:`sys_config('site_url') . '/api/work/serve'`。 ### 2) 配置项来源与组装 企业微信配置通过两层组装后交给 EasyWeChat: - **基础配置**(用于验签/解密/加密回复):`corp_id`、`token`、`aes_key` - 映射到系统配置键:`wechat_work_corpid`、`wechat_work_token`、`wechat_work_aes_key` - **应用配置**(用于调用不同能力 API):按类型注入 `secret` / `agent_id` - 通讯录同步:`wechat_work_address_secret` - 客户联系:`wechat_work_user_secret` - 自建应用:`wechat_work_build_agent_id` + `wechat_work_build_secret` ### 3) 回调验签与事件处理 - `Work::serve()` 调用 EasyWeChat Work Server 完成 URL 校验与消息解密;解密后消息交给 `app\listener\wechat\WorkListener` 分发。 - `WorkListener` 处理的关键事件包含: - 通讯录事件:`change_contact`(成员/部门增删改) - 客户事件:`change_external_contact` - 客户群事件:`change_external_chat` - 客户标签事件:`change_external_tag` ## Problems(常见问题) - 直接在浏览器访问回调 URL 或用普通 HTTP 客户端随意请求,会触发 EasyWeChat 的解析失败,出现 `Failed to decode request contents.`;这不代表系统异常,只是请求不是企业微信回调协议(缺少 `echostr/msg_signature` 或正文不是企业微信 XML/加密格式)。 - 企业微信后台“接收事件服务器”校验失败,常见原因: - URL 不可公网访问(内网/防火墙/白名单/运营商限制) - HTTPS 证书链不完整/过期/不被信任 - 反向代理/WAF 改写了 query/body(导致 `msg_signature` 校验失败) - 回调域名无法在企业微信侧配置(企业侧安全策略或域名限制) ## What Changes(拟新增/调整) ### A. 文档化与定位指引(必做) - 输出一份“配置项—代码使用点—故障排查清单”的说明(本 Spec + checklist)。 - 明确哪些配置影响“回调校验”,哪些配置只影响“API 调用”。 ### B. 回调域名替代方案(不改代码即可落地) - 允许使用“可在企业微信侧配置的域名/网关”作为回调入口,通过透明转发(反向代理/网关/隧道)转发到实际项目的 `/api/work/serve`。 - 允许在无法接入回调时,使用后台已有的“同步企业微信成员”能力做业务降级(非实时)。 ### C. 可选增强:增加独立的回调地址配置项(需要改代码) 新增系统配置键(示例):`wechat_work_callback_url` - 用途:仅用于后台表单展示/复制,默认值仍为 `site_url . '/api/work/serve'`。 - 不改变实际回调逻辑(仍然由路由 `/api/work/serve` 接收);目的是让运维能把“实际对外可用的回调域名”记录在系统里,减少误配。 ## Requirements ### Requirement 1: 配置项可追溯 系统 SHALL 明确以下配置项的用途与作用范围: - `wechat_work_corpid` / `wechat_work_token` / `wechat_work_aes_key`:影响回调验签解密与企业微信身份 - `wechat_work_address_secret`:影响通讯录同步相关 API(拉部门、拉成员等) - `wechat_work_user_secret`:影响客户联系相关 API - `wechat_work_build_agent_id` + `wechat_work_build_secret`:影响自建应用相关 API ### Requirement 2: 当域名无法配置时可替代接入 在企业微信后台无法配置项目域名时,运维 SHALL 能选择以下一种方式完成回调接入: - 方案 A:配置一个企业微信可接受的域名作为回调入口,并反向代理透明转发到本项目 `/api/work/serve` - 方案 B:无法接入回调时,使用后台“同步企业微信成员”接口进行人工/定时全量同步作为降级(承认非实时) ### Requirement 3(可选): 回调地址可配置展示 系统 SHOULD 提供 `wechat_work_callback_url` 配置项用于展示与复制,默认回退到 `site_url . '/api/work/serve'`。 ## Impact(影响面) ### 不改代码即可采用 - 仅影响运维部署方式与企业微信后台填写的回调 URL。 ### 若做可选增强 - 影响后台“企业微信配置”表单展示字段。