企业微信能自动加好友并拉群吗:官方 API 能力边界与架构方案
结论先放在前面
截至 2026-06-06,企业微信官方 API 不能完整实现“企业后台自动把商铺业主和普通用户加为好友,然后主动把他们拉进群”这件事。
一个容易混淆的边界是:如果“自动加好友”指的是用户扫码、点击获客链接或点击小程序按钮之后,企业成员侧自动通过验证,那么官方能力可以覆盖一部分,skip_verify、渠道 state、添加客户事件、欢迎语接口都能参与编排。如果“自动加好友”指企业后台拿手机号、openid、unionid 或业务系统里的用户 ID,直接向对方发起好友申请,官方客户联系 API 没有这个能力。
“主动拉群”也类似。官方 API 可以创建客户群“加入群聊”的二维码或小程序按钮,用户扫码或点击后进入客户群;也可以在新客户欢迎语里发送入群入口。但官方文档没有提供服务端接口,让企业把某个 external_userid 静默拉进客户群。客户群群发也不是直发接口,而是创建群发任务,仍然需要成员确认后才会发送。
所以,合规可落地的方案不是“后台替用户完成好友和入群动作”,而是“用户主动触发建联,系统自动识别渠道、分配跟进人、发送欢迎语、发放入群入口,并通过回调确认是否入群”。
[PATTERN] 对外部用户关系类 API,要先判断官方把动作主语放在谁身上。企微客户联系 API 的主语大多是“客户主动添加、客户主动入群、成员确认发送”,不是“服务端替客户完成社交动作”。
诉求拆开后有三层
这个需求可以拆成三层能力:
| 层级 | 业务想要的动作 | 官方 API 的真实能力 |
|---|---|---|
| 建联 | 自动加商铺业主和普通用户为好友 | 生成“联系我”二维码、小程序按钮或获客链接;客户主动扫码、点击后添加企业成员 |
| 触达 | 新客户添加后主动发消息 | 收到添加客户事件后,20 秒内用 welcome_code 发送一次欢迎语 |
| 入群 | 主动把客户拉进客户群 | 生成“加入群聊”二维码或小程序按钮;客户主动扫码、点击后进入客户群 |
架构设计应该围绕这三层做,而不是把“加好友”和“拉群”当成两个可以由后台直接执行的命令。
官方能力边界
1. “联系我”能生成建联入口,不能后台发起好友申请
企业微信的“客户联系「联系我」管理”文档写得很清楚:企业可以配置成员的“联系我”二维码或小程序按钮,客户通过扫描二维码或点击按钮获取成员联系方式,并主动联系成员。接口 externalcontact/add_contact_way 的返回值包含 config_id 和二维码链接;请求参数里有 skip_verify 和 state。
这说明官方允许企业自动生成大量渠道化入口,例如一个商铺业主注册链接、一个普通用户活动二维码、一个门店海报二维码。state 可以承载渠道标识,后续在客户详情或事件回调里取回。skip_verify=true 可以让客户发起添加后不再等人工通过。
但这个接口的动作仍然是“生成入口”。它没有“向某个微信用户发送好友申请”的参数,也没有把手机号、openid、unionid 转成好友申请目标的流程。官方返回的是二维码或按钮配置,不是好友关系创建结果。
2. 获客链接是更适合线上投放的建联入口
“获客链接管理”提供 customer_acquisition/create_link、get、update_link、delete_link 等接口。创建成功后返回 link_id 和 url,还可以设置 range.user_list、range.department_list、skip_verify、priority_option 等参数。
获客链接更适合 App、短信、H5、公众号菜单、活动页这类线上入口。官方还支持把获客链接转换成 weixin://biz/ww/profile/... scheme,并在链接后拼接 customer_channel=STATE。通过该参数进入的客户,可以在获客客户列表或客户详情里的 state 字段中识别渠道。
获客链接仍然不是“后台主动添加客户”。它把建联动作包装成更顺滑的用户入口。
3. 添加客户事件是自动化承接的核心触发器
“事件格式”文档里的添加外部联系人事件包含这些关键字段:
1 | |
UserID 是接待客户的企业成员,ExternalUserID 是客户在企业微信客户联系体系里的外部联系人 ID,State 可以识别客户从哪个“联系我”或获客链接进入,WelcomeCode 则用于发送新客户欢迎语。
这一步之后,系统才真正拥有可用于客户联系 API 的 external_userid。在用户没有主动建联之前,业务系统里的手机号、App 用户 ID、公众号 openid 都不能直接等价成企微客户 ID。
4. 欢迎语可以自动发,但窗口很短
“发送新客户欢迎语”接口 externalcontact/send_welcome_msg 是这个链路里最接近“自动触达”的能力。企业收到添加客户事件后,可以用 welcome_code 通过成员向新客户发送欢迎语,欢迎语可以包含文本和附件,附件支持图片、链接、小程序、视频等类型。
限制也很硬:官方文档说明该接口只能在收到相关事件后 20 秒内调用,且只可调用一次。如果管理端已经给相关成员配置了可用欢迎语,事件不会返回 welcome_code。如果多个应用同时拿到 welcome_code,只有最先调用的应用能发送成功,后续调用会遇到 41096 或 41051 这类错误。
欢迎语适合承接“加好友后立刻发入群入口”的场景,不适合做后续任意时刻的自动私信系统。
5. “加入群聊”能生成入群入口,不能替客户入群
“客户群「加入群聊」管理”提供 externalcontact/groupchat/add_join_way。企业可以生成客户群二维码或小程序按钮,客户通过扫码或点击按钮加入指定客户群。接口支持 state,也支持 auto_create_room。当群满后,企微可以按 room_base_name 和 room_base_id 自动创建后续群。
这已经足够支撑大部分自动入群引导:不同城市、不同门店、不同活动、不同用户类型可以对应不同入群方式;群满后自动续建群,群成员详情里还能看到通过该入群方式带来的 state。
但它仍然要求客户扫码或点击。接口参数是 chat_id_list、scene、state、auto_create_room,不是 external_userid。官方没有提供“把指定客户直接拉入指定客户群”的服务端 API。
6. 企业群发也不是无确认直发
“创建企业群发”接口 externalcontact/add_msg_template 可以创建发送给客户或客户群的群发任务。官方文档明确写到:调用该接口不会直接发送消息给客户或客户群,需要成员确认后才会执行发送。
这条限制对架构设计很关键。群发接口不能用来绕过“欢迎语只有一次”的限制,也不能用来做“后台自动反复催客户入群”。它适合生成成员待确认的群发任务,适合运营动作,不适合首日建联自动化的主链路。
7. 客户列表和客户详情用于同步,不用于建联
externalcontact/list 可以获取指定成员添加的客户列表,externalcontact/get 可以根据 external_userid 拉取客户详情。客户详情里会返回客户基础信息、跟进成员信息、添加来源 add_way、渠道 state,在满足条件时还能拿到微信 unionid。
unionid 的作用是把企业微信外部联系人与公众号、小程序用户做身份关联。它不是添加好友的凭证。能看到 unionid,表示这位客户已经进入客户联系体系,并且企业完成了微信开发者 ID 绑定;它不意味着企业可以拿 unionid 反向发起好友申请。
[PATTERN] 身份关联字段和动作授权字段不能混用。unionid、external_userid、state 解决“这个人是谁、从哪里来”,不解决“能否替这个人完成社交动作”。
能力矩阵
| 诉求 | 官方 API 能否实现 | 可用能力 | 关键限制 |
|---|---|---|---|
| 给每个商铺生成专属加好友入口 | 可以 | “联系我”、获客链接、state 或 customer_channel |
用户仍需扫码或点击 |
| 用户点击后自动通过好友验证 | 可以 | skip_verify=true |
由用户先发起添加 |
| 后台按手机号主动发好友申请 | 不支持 | 无官方服务端接口 | 手机号只可能成为线下或成员端添加线索 |
| 添加好友后自动发第一条消息 | 可以 | 添加客户事件、welcome_code、欢迎语接口 |
20 秒内、仅一次、可能因管理端欢迎语配置而没有 welcome_code |
| 自动给客户分配不同入群入口 | 可以 | 规则引擎、客户群 add_join_way、欢迎语链接/图片 |
客户仍需扫码或点击 |
| 后台直接把客户拉进客户群 | 不支持 | 无官方服务端接口 | 入群动作由客户完成 |
| 群满后自动建新群 | 可以 | auto_create_room、room_base_name、room_base_id |
依赖“加入群聊”配置和已有群入口 |
| 后续批量提醒客户入群 | 受限 | add_msg_template 创建群发任务 |
成员确认后才发送,且有接收上限 |
推荐架构:用户主动触发的自动化入群
合规架构应把“主动”放在业务编排层,而不是企微社交动作层。系统主动生成入口、主动识别渠道、主动发欢迎语、主动记录状态;客户主动添加成员、主动进入客户群。
sequenceDiagram
participant C as 商铺业主/普通用户
participant Entry as H5/小程序/海报入口
participant WeCom as 企业微信客户联系
participant Callback as 回调服务
participant Rule as 分群规则引擎
participant Group as 客户群入口服务
participant CRM as 客户与群关系库
Entry->>WeCom: 创建获客链接或「联系我」二维码
WeCom-->>Entry: 返回 url/qr_code/config_id
C->>Entry: 点击或扫码
C->>WeCom: 主动添加企业成员
WeCom->>Callback: add_external_contact + State + WelcomeCode
Callback->>CRM: 幂等记录 external_userid、userid、state
Callback->>WeCom: 拉取客户详情
Callback->>Rule: 根据 state、角色、门店、城市分群
Rule->>Group: 获取或创建「加入群聊」配置
Group-->>Callback: 入群二维码或小程序按钮
Callback->>WeCom: 20 秒内发送欢迎语
C->>WeCom: 扫码或点击加入客户群
WeCom->>Callback: change_external_chat / add_member
Callback->>CRM: 更新入群状态
入口层:一个业务场景一个短渠道码
商铺业主和普通用户不要共用同一个二维码。入口层至少拆出三类:
| 入口类型 | 推荐载体 | 渠道参数 |
|---|---|---|
| 商铺业主入驻 | 获客链接或小程序按钮 | role=owner 对应的短 token |
| 普通用户活动 | 获客链接、活动页按钮、海报二维码 | role=user 对应的短 token |
| 线下门店物料 | “联系我”二维码 | state 对应门店和物料 token |
企微“联系我”的 state 不超过 30 个字符,“加入群聊”的 state 也不超过 30 个 UTF-8 字符;获客链接的 customer_channel 不超过 64 字节。不要把完整 JSON 塞进去。更稳的做法是生成短 token,例如 O9K3D2,在业务库里映射到完整上下文:
1 | |
回调层:20 秒窗口要用同步快路径
添加客户事件到达后,欢迎语发送窗口只有 20 秒。回调服务不适合先做复杂画像、远程风控、跨系统同步,再慢慢发送欢迎语。推荐拆成快慢两条路径:
| 路径 | 动作 | 时限 |
|---|---|---|
| 快路径 | 验签解密、幂等落库、按 state 查规则、拿入群入口、发送欢迎语 |
20 秒内 |
| 慢路径 | 客户详情补全、标签同步、CRM 合并、运营分析、异常重试 | 事件后异步 |
欢迎语发送结果要记录 welcome_code、错误码、重试次数和最终状态。41096 表示可能已有其他应用正在发送,可短暂重试;41051 表示客户已经开始聊天或欢迎语已成功下发,应该停止重试。
分群层:先准备种子群,再让企微自动续群
客户群“加入群聊”配置需要 chat_id_list。业务系统不能凭空创建一个任意客户群并把客户塞进去。可行做法是:
- 每个业务分群预先准备种子客户群,例如“业主-上海-默认群”“用户-杭州-活动 A 群”。
- 获取这些客户群的
chat_id,写入分群规则。 - 调用
groupchat/add_join_way生成入群二维码或小程序按钮。 - 开启
auto_create_room=1,配置room_base_name和room_base_id,让群满后自动续建。 - 通过客户群变更事件和客户群详情接口同步成员入群状态。
这种设计可以实现“系统自动给客户发正确的入群入口”,不能改写成“系统直接拉客户进群”。
消息层:欢迎语是主链路,群发是运营链路
新客户添加后的第一条入群引导,应该走 send_welcome_msg。欢迎语内容可以包含:
| 客户类型 | 欢迎语内容 | 入群入口 |
|---|---|---|
| 商铺业主 | 入驻进度、认证材料、运营经理说明 | 业主服务群二维码或小程序按钮 |
| 普通用户 | 活动说明、权益说明、社群规则 | 用户活动群二维码或小程序按钮 |
后续提醒不要设计成服务端任意私信。add_msg_template 创建的是群发任务,需要成员确认。它可以作为运营后台里的“待确认群发”,例如每天提醒客户经理处理未入群客户;不能当成完全自动化的催加入群通道。
数据层:状态机比布尔字段更可靠
客户从入口到入群至少经历这些状态:
1 | |
其中 ENTRY_CLICKED_OR_SCANNED 未必总能从企微侧拿到,取决于入口形态;但 CONTACT_ADDED 和 GROUP_JOINED 可以通过企微回调确认。状态机里要允许缺口,不要假设每个客户都会完整走完。
核心表可以这样设计:
| 表 | 关键字段 | 用途 |
|---|---|---|
wecom_entry |
entry_id、type、config_id/link_id、state_token、url/qr_code |
管理建联入口 |
wecom_contact_relation |
corp_id、external_userid、userid、state_token、add_way |
记录客户与成员关系 |
wecom_join_way |
route_key、config_id、chat_id_list、qr_code、state_token |
管理入群入口 |
wecom_welcome_attempt |
welcome_code_hash、external_userid、status、errcode |
记录欢迎语发送 |
wecom_group_membership |
chat_id、external_userid、join_scene、state |
记录入群结果 |
幂等键不能只用 welcome_code。更稳的做法是用 corp_id + userid + external_userid + change_type 约束客户关系,再把每次事件原文存入事件表,便于排查重复回调和竞态。
实施清单
第一步,开通和校验客户联系能力。企业成员必须配置客户联系功能,自建应用要被配置到客户联系“可调用接口的应用”范围内。第三方、代开发、营销获客应用还要按官方权限开通客户基础信息、建联客户信息、给客户发送欢迎语、配置加入群聊二维码等权限。
第二步,为商铺业主和普通用户分别创建获客入口。线上入口优先用获客链接,线下海报优先用“联系我”二维码。所有入口使用短 state_token,不要把业务参数明文铺在链接里。
第三步,搭建回调服务。回调服务负责接收客户联系事件,处理 add_external_contact、add_half_external_contact、change_external_chat 等事件。添加客户事件到达后,立即根据 State 路由客户类型。
第四步,准备客户群路由。每个业务 route 至少绑定一个种子群,提前拿到 chat_id,再调用 groupchat/add_join_way 创建入群方式。需要承接大量用户时开启自动建群。
第五步,发送欢迎语。欢迎语里放入群入口和必要说明,发送过程走 20 秒内快路径。欢迎语失败后不要盲目重发,要按错误码进入人工跟进或运营任务。
第六步,同步客户和群状态。通过客户列表、客户详情、客户群详情和客户群变更事件,把客户是否添加、是否入群、来自哪个入口、由哪个成员跟进写回 CRM 或业务库。
第七步,设置人工兜底。没有 welcome_code、欢迎语失败、客户未入群、客户被分错群,都应该进入运营后台的待办列表,而不是尝试用非官方方式补动作。
风险和合规边界
这个场景天然接近平台反滥用边界。系统设计至少要守住四条线。
第一,必须有明确的用户动作和目的告知。入口页、活动页、海报文案要说明添加企业微信后的用途,以及是否会发送入群邀请。
第二,不要用脚本、外挂、个人微信协议或客户端模拟来补官方 API 的缺口。企微官方 API 没有给的“主动加好友”和“直接拉群”,通常不是漏做,而是风控和用户体验边界。
第三,敏感身份不要靠昵称判断。商铺业主身份应该来自入驻表单、门店认证、合同或业务库绑定,普通用户身份来自活动报名或账号体系。企微客户详情只能作为补充信息。
第四,保留退出和人工处理路径。客户不扫码、不入群、删除成员、退出客户群,都应该是合法状态。业务系统可以提醒运营人员处理,不能把客户困在自动化链路里。
最终方案判断
如果目标是“官方 API 合规实现零人工建联承接”,可以做。推荐方案是:
1 | |
如果目标是“企业后台不经过用户动作,自动添加对方好友,并把对方直接拉进群”,官方文档不支持。架构方案应该早一点承认这个边界,把自动化做在入口、路由、欢迎语、状态同步和运营兜底上。



