LikeShop 企业微信客服二开:消息同步、客户标签打通与社群引流

一、原生客服的真实形态:一个"跳转链接",不是一套会话体系

LikeShop 原生的在线客服配置里,service_type 区分"人工客服"和"在线客服",online_type 支持"第三方 H5 客服",并通过 h5_url 字段挂载外部客服页面。这意味着商城侧的"企业客服"入口,本质上是一个跳转动作:用户点击客服按钮,跳到企业客服的 H5 链接或小程序路径,会话发生在企业微信侧,商城系统不感知消息内容、保存会话记录、不关联用户身份。

LikeShop v3.5.1 确实新增了"企业微信客服"能力,官方定位是"打通商城与企业微信之间的服务链路,方便客户咨询、售后沟通以及长期运营"。但从二开视角看,这个"打通"停留在入口层面------消息没有回流、标签没有同步、订单信息没有透传、社群引流没有自动化。用户在企微客服里说的话,商城后台看不到;客服在企微侧看到的只是一个昵称,不知道对方买过什么、客单价多少、是不是高价值客户。

二开要做的,是把这三条断掉的链路接上:消息同步 让商城客服工作台能收发企微客服消息,标签打通 让企微侧的客户画像带上商城的会员等级和消费标签,社群引流 让客服会话结束或订单完成后能自动引导用户人群。核心策略是不修改 LikeShop 原生客服的跳转逻辑,企微客服域独立建表、独立回调服务,通过 unionid / 手机号 做身份映射,通过事件监听在订单和客服会话的扩展点注入同步动作。

二、总体架构:回调服务 + 身份映射 + 三条同步链路

企微客服的消息模型是回调触发 + 主动拉取 :企微服务器将 kf_msg_or_event 事件推送到企业指定的回调 URL,企业收到回调后,用事件中的 Token 调用 sync_msg 接口拉取具体消息内容。回复消息则走 send_msg 接口,但有一个关键约束:只有当客户处于"新接入待处理"或"由智能助手接待"状态时才能发送,且客户主动发消息后的 48 小时内最多发 5 条。人工接待状态下无法通过 API 发送消息。

这个约束决定了架构的基本形状:消息同步是"拉"为主、"推"为辅。回调只负责"有新消息了"的通知,真正的消息内容靠 sync_msg 按 cursor 增量拉取。商城的客服工作台如果需要回复,必须确保企微客服账号处于 API 可管理的接待状态,或者把回复动作引导到企微侧的人工接待。

整体架构分四层:回调接入层 接收 kf_msg_or_event 事件并验签;消息拉取层 调用 sync_msg 增量拉取消息、落库、推送给商城客服工作台;身份映射层 维护 unionid ↔ external_userid ↔ LikeShop user_id 的映射关系;标签与引流层在订单事件和客服会话事件触发时,调用企微标签接口和群活码接口完成同步与引导。

三、消息同步:回调 → 拉取 → 落库 → 工作台

3.1 回调接入与验签

企微客服的回调 URL 接收 XML 格式的事件推送,核心字段是 Event = kf_msg_or_event、Token(10分钟内有效,用于 sync_msg 校验)和 OpenkfId(哪个客服账号有新消息)。回调处理必须快速响应,不能在里面直接调 sync_msg 拉全最消息------拉取可能耗时,回调超时会导致企微重试。正确的做法是:回调验签通过后,把 Token 和 OpenkfId 推入队列,立即返回成功;队列消费者再执行拉取

复制代码
php
// 回调入口:验签 + 入队,不做重活
public function callback()
{
$xml = file_get_contents('php://input');
$data = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
if ((string)$data->Event !== 'kf_msg_or_event') {
    return 'success';
}
Queue::push(KfSyncJob::class, [
    'token'    => (string)$data->Token,
    'open_kfid'=> (string)$data->OpenKfId,
]);
return 'success';
}

3.2 增量拉取与游标管理

sync_msg 的 cursor 是增量拉取的关键。每个客服账号(open_kfid)需要独立维护游标,第一次拉取不传 cursor,之后每次用上一次返回的 next_cursor。Token 不传时接口有严格的频率限制,传入回调带来的 token 可以放宽频率,但 token 只有 10 分钟有效期,所以拉取必须在回调后尽快执行。

消费落库的表需要保留 msgid 做幂等,send_time 做排序,origin 区分消息来源(客户发送/系统事件/接待状态变更):

sql

复制代码
CREATE TABLE `ls_wecom_kf_msg` (
  `id` int UNSIGNED NOT NULL AUTO_INCREMENT,
  `msgid` varchar(64) NOT NULL COMMENT '企微消息ID',
  `open_kfid` varchar(64) NOT NULL COMMENT '客服账号ID',
  `external_userid` varchar(64) NOT NULL COMMENT '企微外部联系人ID',
  `like_user_id` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '映射的LikeShop用户ID,0为未映射',
  `direction` tinyint NOT NULL COMMENT '方向:1-客户发送,2-企业发送',
  `msg_type` varchar(20) NOT NULL COMMENT '消息类型:text/image/voice/video/file/menu/event',
  `content` text COMMENT '消息内容',
  `send_time` int UNSIGNED NOT NULL COMMENT '发送时间',
  `create_time` int UNSIGNED NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_msgid` (`msgid`),
  KEY `idx_external_time` (`external_userid`, `send_time`),
  KEY `idx_like_user` (`like_user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企微客服消息表';

uk_msgid 唯一约束是幂等的底线------企微回调可能重投,sync_msg 也可能因游标回退重复拉取,唯一约束保证同一条消息不会重复落库。

3.3 消息推送到商城客服工作台

商城客服工作台如果需要实时看到企微客服的消息,落库后还需要一次推送 :通过 WebSocket 或轮询把新消息推给当前在线的客服坐席。这里的关键设计是消息归属------一条企微消息应该出现在哪个客服的会话列表里?如果 external_userid 已经映射到 LikeShop 用户,就按用户维度归属;如果未映射,按 open_kfid 归属到公共待接入池。

回复的边界要明确:商城工作台发起的回复,如果走 send_msg,必须校验当前会话状态是否允许 API 发送(service_state 是否为待处理或智能助手接待),且 48 小时 / 5 条的限制要作为硬校验。人工接待中的会话,回复动作应该引导到企微侧,而不是在商城工作台调用 send_msg 硬发。

四、身份映射:标签打通的前提

4.1 为什么 external_userid 不能直接当用户 ID

企业微信给每个外部联系人的 external_userid 是"本企业视角下"的编号 ,同一个微信用户在不同企业的 external_userid 不同。这意味着商城侧的 user_id 和企微侧的 external_userid 之间不能直接划等号,必须做一次映射。可用的锚点有三个 unionid(最稳定,但需要小程序和企微绑定同一开放平台主体)、手机号 (最通用,但依赖用户授权和填写)、自定义字段(灵活性高,但需要用户主动留资)。

推荐的映射策略是unionid 优先、手机号兜底、未匹配不强行归属。商城小程序和企微客服绑定到同一开放平台后,unionid 可以作为桥梁:商城侧拿到用户的 unionid,企微侧通过客户详情接口拿到 external_userid 对应的 unionid,两者相等即建立映射。如果 unionid 缺失(如 H5 场景),用下单手机号做二次匹配,但必须标记"匹配存疑",不能因为手机号相同就默认是同一人。

sql

复制代码
CREATE TABLE `ls_wecom_user_map` (
  `id` int UNSIGNED NOT NULL AUTO_INCREMENT,
  `like_user_id` int UNSIGNED NOT NULL COMMENT 'LikeShop用户ID',
  `external_userid` varchar(64) NOT NULL DEFAULT '' COMMENT '企微外部联系人ID',
  `unionid` varchar(64) NOT NULL DEFAULT '' COMMENT '微信unionid',
  `match_type` tinyint NOT NULL DEFAULT 1 COMMENT '匹配方式:1-unionid,2-手机号,3-手动',
  `match_status` tinyint NOT NULL DEFAULT 1 COMMENT '匹配状态:1-已匹配,2-存疑',
  `create_time` int UNSIGNED NOT NULL DEFAULT 0,
  `update_time` int UNSIGNED NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_like_user` (`like_user_id`),
  KEY `idx_external_userid` (`external_userid`),
  KEY `idx_unionid` (`unionid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='LikeShop用户与企微客户映射表';

4.2 标签同步:必须"先拉后写"

企微的客户标签更新接口 label/updateLabel 是覆盖式更新,不是追加。如果先大量标签 A,再调一次只传B,A 会被覆盖掉。正确的做法是"先拉后写":先调 contact/getuserProfileDetall 获取当前标签列表,合并新增标签后,再统一提交全量标签 ID。

标签体系需要分层设计,避免把"事实"和"运营分群"混在一起:

事实标签由商城数据字段写入企微:会员等级(普通/白银/黄金)、消费分层(首购/复购/高客单)、品类偏好(美妆/数码)、生命周期(新客/活跃/沉默)。这些标签的规则是确定的,订单支付、退款、会员升级等事件触发后异步同步。

运营分群不直接写入企微标签,而是在商城侧或 SCRM 侧按多条件动态圈选(如"近 30 天首购、未退款、未复购、已加企微"),避免标签数量爆炸。

标签同步的触发点包括:订单支付成功 (写入首购标签、消费分层标签)、订单完成 (更新复购标签)、退款完成 (移除首购权益标签、写入售后关注标签)、会员等级变更(更新等级标签)。每次同步前先拉取企微侧当前标签,合并后写回,并记录同步日志用于排查覆盖问题。

五、社群引流:从"会话结束"到"入群"

5.1 群活码的接入方式

企业微信提供"加入群聊"接口 groupchat/add_join_way,企业可以生成并配置群二维码或小程序按钮,客户扫码即可加入指定的客户群。群活码的核心价值是自动分流和满勤切换 ;一个活码关联多个群,按顺序分配客户至未满群,群满自动建新群。该接口目前仅支持企业自建应用调用,服务商代开发应用已不再支持。

LikeShop 二开中,群活码的落地方式有两种:

方式一:客服会话内自动推送。当客服会话满足触发条件(如用户主动询问"有群吗"、售后问题解决后、会话即将超时),通过 send_msg 发送群活码的图片或小程序卡片。但要注意 send_msg 的 48 小时/ 5 条限制,群活码推送必须计入条数预算,不能和普通回复抢额度。

方式二:欢迎语自动附带。企微客服支持"发送新客户欢迎语"接口,可以在用户首次接入时自动发送欢迎语,欢迎语中附带群活码链接或小程序按钮。这是最自然的引流时机------用户刚发起咨询,注意力在客服身上,入群动作的转化率最高。

5.2 引流的分层策略

不是所有用户都值得拉群。引流应该按客户价值分层:

高价值客户 (高客单、高频复购、会员等级高)引导进入专属服务群 ,群内有专属客服,强调服务而非促销。普通新客引导进入福利群/活动群,群活码按渠道打标,用于后续的促销触达。售后问题用户在问题解决后引导入群,群标签标记"售后已解决",避免在群内重复触发售后流程。

群活码的 state 参数可以携带渠道标识,客户扫码入群后,企微回调会带回 state,商城侧据此记录"该用户从哪个渠道入群",用于后续的引流效果归因。

六、后台配置与开发注意事项

6.1 后台配置清单

配置项 类型 说明
企微客服总开关 开关 关闭后商城客服入口回退到原生 H5 跳转
企微企业 ID / 客服 Secret 文本 自建应用凭证,用于获取 access_token
客服账号 open_kfid 多选 需要接入的企微客服账号
回调 URL 文本 企微后台配置的回调地址,需公网可访问
标签同步开关 开关 订单事件是否自动同步标签到企微
标签映射规则 配置 商城标签与企微标签 ID 的对应关系
群活码 ID 文本 引流用的群活码 ID
欢迎语群活码 开关 首次接入欢迎语是否附带群活码
引流触发条件 多选 会话结束 / 售后完成 / 首单完成等

6.2 开发注意事项

回调必须快速响应,拉取必须异步。kf_msg_or_event 回调的超时会导致企微重试,重试又会产生新的 token,如果同步拉取耗时过长,游标管理会混乱。回调只做验签和入队,sync_msg 在队列中执行。

token 的 10 分钟有效期是硬约束。回调带来的 token 只在 10 分钟内有效,队列消费如果延迟超过 10 分钟,sync_msg 会退化为无 token 调用,触发频率限制。队列的超时和重试策略必须考虑这个时间窗口。

标签同步的"先拉后写"不能省。updateLabel 的覆盖语义是企微客服二开中最容易踩坑。跳过拉取直接写入,会把客服在企微侧手动打的标签全部冲掉,而且这种错误在测试环境很难发现(测试时标签少),上线后才会暴露。

send_msg 的会话状态和频率限制必须前置校验。人工接待状态下调用报 95018,48 小时外或超过 5 条也会失败。工作台的发送按钮应该在调用前检查 service_state 和剩余额度,而不是等接口报错再提示。

兼容性。新增的企微消息表、映射表、标签同步日志表独立于 LikeShop 原生的 ls_user 和客服配置表。原生 h5_url 跳转链路保留,作为企微客服不可用时的降级方案。企微客服的接入通过独立的回调路由和队列消费者实现,不修改 SettingsService 的原生配置逻辑。标签同步和社群引流作为可选开关,关闭时完全不影响原生客服功能。

相关推荐
极客互动API1 天前
【极客互动】企业微信外部群聊机器人开发实战与效果验证
微信·机器人·企业微信·企微scrm·企业微信api·企微外部联系人
金融Tech趋势派4 天前
企业微信SCRM多少钱一年?2026收费标准拆解与预算自算表
大数据·企业微信
weixin_493503674 天前
商协会系统对接企业微信:通讯录同步实战
企业微信
天空属于哈夫克34 天前
企业微信 API 二次开发与 AI 结合:如何设计智能消息处理流程
人工智能·企业微信
随性而行3604 天前
企业微信 Webhook 接收不到消息?网络连通性、URL 签名验签与 API 返回错误码排查指南
java·网络·人工智能·后端·微信·企业微信
ManageEngineITSM5 天前
ITSM系统如何与企业微信、钉钉、飞书集成?提升工单处理效率的方法
java·大数据·开发语言·钉钉·企业微信·变更管理
天空属于哈夫克36 天前
企业微信API二次开发 赋能私域运营自动化
运维·自动化·企业微信
天空属于哈夫克36 天前
企业微信 RPA 自动化开发实践:打通客户管理与业务任务处理流程
机器人·自动化·企业微信·rpa
杨婷1236 天前
2026 企微会话存档服务商怎么挑,合规稳定优先看什么
企业微信