# 企业微信获客助手配置
管理端菜单:`一诊 / 企业微信获客助手`
该功能使用当前企业的内部自建应用配置,不使用服务商第三方应用,也不需要 SuiteID、suite_ticket、永久授权码或企业扫码安装。
系统直接复用 `server/.env` 已有配置:
```ini
[work_wechat]
CORP_ID = "当前企业 CorpID"
AGENT_ID = "内部自建应用 AgentID"
CUSTOMER_ACQUISITION_SECRET = "获客助手可调用应用的 Secret"
[app]
HOST = "https://公开访问域名"
```
兼容已有项目:没有 `CUSTOMER_ACQUISITION_SECRET` 时,会依次回退读取 `AGENT_SECRET`、`SECRET`。如果现有 `SECRET` 就是获客助手中配置的“可调用应用”Secret,无需重复配置。
企业微信管理后台还需完成三项外部配置:开通获客助手、将该内部应用设置为获客助手可调用应用、将接口服务器公网 IP 加入可信 IP。页面“验证获客助手 API”会通过只读列表接口检查这些条件。
## 官方 API 对接范围
按[企业微信获客链接管理文档](https://developer.work.weixin.qq.com/document/path/97297)完成以下五个接口:
- 获取获客链接列表 `list_link`
- 获取获客链接详情 `get`
- 创建获客链接 `create_link`
- 更新获客链接 `update_link`
- 删除获客链接 `delete_link`
当前管理端按“一个分流方案对应一个官方获客链接”管理。删除方案时先调用企业微信 `delete_link` 永久删除关联的官方链接,成功后再软删除本地方案、成员和链接记录;如果企业微信删除失败,本地方案会保留并返回错误,避免两端状态不一致。官方链接删除后无法恢复,已投放 URL 会失效,历史本地客户归因记录仍保留。
获客成员来自后台管理员的 `work_wechat_userid`。管理员可管理全量;组长、医助等账号只返回 `DataScopeService` 当前角色与部门范围内的成员。同步远端链接时,非全量账号只导入 `range.user_list` 与其可见成员有交集的数据;企业微信部门 ID 尚未建立本地映射时按安全原则隐藏,不会越权放行。
`list_link` 只返回当前获客助手可调用应用通过 API 创建的官方链接。后台历史手工粘贴的 `work.weixin.qq.com/ca/...` 链接,以及其他应用创建的链接,不会出现在当前应用的同步列表中,也无法仅凭 URL 反查为官方 `link_id`。需要官方客户、统计和消息归因时,应在本页面创建分流方案并选择获客成员。
创建分流方案时必须选择一名或多名医助。一个方案只创建一条企业微信官方链接,当前全部可用医助会同时写入该链接的 `range.user_list`,由企业微信在打开、添加阶段执行官方多人路由。成员可配置启用状态、每日上限和有效时间,系统按实际获客回调累计数量。
批量修改方案支持按员工统一上线或下线。操作只影响所选方案中已经存在的员工规则,不会把员工自动加入其他方案;下线操作如果会令任一方案没有当前可用的上线员工,则整批在写入前拒绝。员工上下线需与其他方案配置分开保存;状态保存与同步意图在同一事务内提交,每个受影响方案只重算一次成员范围,并进入企业微信后台同步队列。
企业微信 `range.user_list` 只接受成员 userid 列表,不提供逐成员权重字段,因此本站不再展示或执行 2:1:1 一类权重规则。官方多人路由的实际承接还会受到成员可服务状态、客户已有好友关系等企业微信规则影响,不能承诺每次刷新严格随机或短期样本绝对平均。
系统只使用企业微信获客助手生成的链接:
```text
https://work.weixin.qq.com/ca/xxxxxxxx
```
“联系我”、客户群、自有网页或其他外部链接均会被拒绝;已有的非获客助手历史链接不会作为方案主链接。Secret 与 access_token 不会返回到浏览器,也不会写入接口错误日志。
可复制的主链接会追加分流方案渠道参数,结构如下:
```text
https://work.weixin.qq.com/ca/xxxxxxxx?customer_channel=zyt_pool:123
```
其中 `customer_channel` 是本站写入的自定义渠道值,格式为 `zyt_pool:分流方案ID`;它与示例中的 `qywx_ca:...` 作用相同,但命名空间和数值由各系统自行定义。
## 回调统计与成员范围维护
部署时必须执行:
```text
server/sql/1.9.20260824/upgrade_qywx_promotion_member_dispatch.sql
```
并在企业微信后台把“API 接收消息”配置为:
```text
https://你的域名/api/qywx/external-contact/notify
```
回调优先使用 `change_external_contact/add_external_contact` 事件中的 `State`、`UserID` 和 `ExternalUserID`。`State` 来自主链接的 `customer_channel=zyt_pool:方案ID`,因此可以定位方案及实际承接医助;获客会话回调会通过 `ChatKey → get_chat_info` 作为补偿。方案和客户组合使用唯一幂等键,同一实际获客不会因重复回调或后续更换跟进成员而重复计数。
创建或编辑方案时,系统把所有已启用、已生效且未达到今日上限的成员一次写入同一个官方链接。禁用、尚未生效、已过期或达到今日上限的成员会从官方范围移出;跨日或重新进入有效期后会自动加入。`qywx:sync-promotion-ranges` 每分钟重算全部方案并重试失败同步,管理端修改成员规则时也会立即尝试同步。
每日数量属于回调驱动的近实时软上限,并非点击前的强事务:多个客户在企微回调或 `update_link` 生效前并发访问时,可能出现少量超量;所有成员都达到上限时,企业微信不允许把 `range.user_list` 更新为空,系统会标记“无可用成员”并保留最后一次有效范围。因此该上限用于自动退出后续官方路由,不承诺并发场景下绝对零超量。
如果需要为点击 IP 生成不可逆服务端哈希,可在 `[qywx_promotion]` 下额外设置独立的 `CREDENTIAL_KEY`。
公开 JS 示例:
```html
添加企业微信
```
旧的 `/api/qywx-promotion/go/分流方案KEY` 地址继续保留,兼容已经投放的安装代码;新建方案、管理端复制链接和新版浮窗均直接打开官方获客链接。
## 公开浮窗
每个分流方案可选择是否由同一段公开 JS 自动挂载客服浮窗。关闭浮窗时,已有的
`data-wecom-promotion`、`.wecom-promotion-link[data-pool]` 和
`window.WecomPromotion[KEY].open()` 手动触发方式仍然可用。
浮窗配置保存在分流方案的 `widget_config_json` 中。当前配置版本为 `v=1`,支持:
- 模板:`bubble`、`pill`、`card`、`message`、`edge`、`bar`
- 位置:`bottom-right`、`bottom-left`
- 标题、副标题、按钮文案和 `#RRGGBB` 主题色
- 16-160 像素底部距离、移动端展示开关和浮窗总开关
公开脚本仅下发经过白名单校验的展示配置和当前方案的单个官方目标链接,不下发历史链接池或 Secret。模板
由脚本内置,管理端文案通过 DOM `textContent` 写入,不接受自定义 HTML、CSS 或脚本。
损坏配置、未知版本和非法枚举会按关闭浮窗处理。
脚本会暴露以下运行时方法:
```js
window.WecomPromotion['分流方案KEY'].open()
window.WecomPromotion['分流方案KEY'].show()
window.WecomPromotion['分流方案KEY'].hide()
window.WecomPromotion['分流方案KEY'].destroy()
```
公开脚本缓存 60 秒,因此浮窗样式、开关或官方目标链接更新最多延迟约 60 秒。新版浮窗直接打开企业微信官方链接,不再经过本站逐次 302;已经复制到外部的官方链接也不会因本地关闭方案而失效。管理端安装代码优先使用 `[app] HOST`,请在生产环境配置唯一的 HTTPS 公开域名。
接入站点若启用了严格 CSP,需要允许脚本域名,并给安装 `
```
旧 `/go` 兼容入口记录点击来源时,只保存页面的 origin 与 pathname,不包含查询参数或 fragment。推广页路径中也不应放置手机号、患者 ID、重置令牌等敏感信息。
用户始终看到同一个企业微信官方获客链接。本站只维护该链接的可用成员集合,实际多人分流由企业微信完成;回调负责记录实际承接结果,并在成员达到上限后更新集合。