基于企微API与数据中台,构建用户分层与沉默用户召回体系

摘要

教育机构私域池中积累了大量的"沉默用户"------试听后未转化、加好友后未互动、领资料后未激活。如何低成本唤醒这些用户,是提升整体ROI的关键。本文提出基于企业微信API与数据中台对接的用户分层与自动化召回方案。通过RFM模型对用户进行分层,针对不同层级的沉默用户设计差异化的召回策略,利用脚本实现定时扫描、条件判断与批量触达,将沉睡用户激活率提升30%以上。

一、问题背景:沉默用户是"沉睡的金矿"还是"永远的成本"?

从技术运营视角看,私域用户池是一个典型的数据资产,但大多数机构的资产利用率极低:

  1. 沉默用户占比高:教育行业的典型数据是,试听用户中最终只有5%-10%转化为付费学员,剩余90%以上的用户成为"沉默用户"------他们躺在好友列表里,既不删除也不互动。这些用户占用了员工的好友额度,却没有产生价值。

  2. 缺乏分层运营:很多机构对所有沉默用户"一视同仁",定期群发同样的广告话术。结果是用户越来越反感,删除率上升,转化率却毫无起色。

  3. 召回成本高:人工筛选沉默用户并逐一私聊,耗时耗力且效果难以衡量。运营人员更愿意跟进新流入的活跃用户,导致沉默用户被"遗忘"。

  4. 官方API无用户分层能力:企业微信API虽然支持标签,但无法自动计算RFM(最近互动时间、互动频率、互动价值)等指标,也无法根据用户活跃度自动触发召回流程。

二、技术方案:构建"RFM分层+自动化召回"的沉默用户激活引擎

核心思路是将沉默用户按照价值-沉睡度矩阵分层,针对不同层级设计差异化的召回策略。

🏗️ 方案架构

用户行为数据(消息/互动/点击/购买) → RFM计算引擎 → 分层标签同步 → 召回策略执行

  1. 数据采集:持续收集用户与企微的互动数据,包括:

    • 最后一次消息时间(私聊/群聊)

    • 互动频率(周活跃天数)

    • 互动价值(是否点击链接、是否咨询、是否购买)

  2. RFM计算:定时任务(每日凌晨)扫描所有用户,计算RFM分值,将用户划分为:

    • 高价值活跃用户:近期有互动,有购买记录

    • 潜力用户:近期有互动,无购买记录

    • 轻度沉睡:30天内无互动,但有过购买或深度互动

    • 深度沉睡:90天内无互动

    • 濒临流失:180天内无互动

  3. 标签同步:将分层结果通过企微API写入用户标签,供销售查看。

  4. 召回策略:根据分层自动触发不同的召回SOP:

    • 轻度沉睡:发送行业干货+限时福利

    • 深度沉睡:发送问卷调研+大额优惠券

    • 濒临流失:发送"告别信"+最后机会

⚙️ 技术选型对比

|-----------|------------------|------------|-----------|-------------|
| 方案 | 原理 | 优点 | 缺点 | 适用场景 |
| 自研RFM引擎 | 定时任务扫描数据库计算 | 灵活可控,可定制模型 | 开发成本高 | 有数据团队的中大型机构 |
| CDP用户数据平台 | 集成第三方CDP,自动计算 | 功能强大,开箱即用 | 成本高,数据需迁移 | 预算充足的机构 |
| 企微标签手动分层 | 运营手动打标签 | 简单直接 | 无法规模化,滞后 | 小规模机构 |
| 企销宝RFM模块 | 基于iPad协议自动分析互动行为 | 无需开发,自动分层 | 需合规使用 | 追求快速落地的机构 |

本文采用自研RFM引擎+企微API的方案,平衡成本与灵活性。

三、实现步骤:从数据采集到自动化召回的全流程

步骤1:环境准备
  • 账号:企业微信已认证主体、MySQL/ClickHouse(存储用户行为数据)、定时任务调度器(Cron/Celery Beat)。

  • 工具:Python数据分析库(Pandas/NumPy)、Redis(缓存计算结果)。

  • 配置要求:需要能够访问企微API获取用户列表和聊天记录(需开通会话存档功能)。

步骤2:功能配置 ------ RFM模型设计与计算

核心逻辑:将用户行为量化为三个维度,加权计算得出用户价值分。

配置步骤:

  1. 定义RFM指标:

    |-----------|----------|------------------------------------------|------|
    | 维度 | 指标 | 计算方式 | 分值范围 |
    | R(最近互动时间) | 距离今天的天数 | 1-30天=5分,31-60天=3分,61-90天=1分,>90天=0分 | 0-5 |
    | F(互动频率) | 近30天互动天数 | >15天=5分,10-14天=4分,5-9天=3分,1-4天=2分,0天=0分 | 0-5 |
    | M(互动价值) | 是否购买/咨询 | 购买过=5分,咨询过但未买=3分,仅点击链接=1分,无价值互动=0分 | 0-5 |

  2. RFM计算脚本:

    python

    复制代码
    # rfm_calculator.py - 每日凌晨执行
    import pandas as pd
    import pymysql
    from datetime import datetime, timedelta
    
    def calculate_rfm():
        """计算所有用户的RFM分值"""
        
        # 1. 从数据库获取用户互动数据
        conn = pymysql.connect(host='localhost', user='root', password='xxx', database='wecom')
        
        # 获取所有外部联系人
        users = pd.read_sql("SELECT external_userid, create_time FROM users", conn)
        
        # 获取近180天的互动记录
        interactions = pd.read_sql("""
            SELECT external_userid, 
                   MAX(interact_time) as last_interact,
                   COUNT(DISTINCT DATE(interact_time)) as active_days,
                   MAX(CASE WHEN action_type = 'purchase' THEN 1 ELSE 0 END) as has_purchased,
                   MAX(CASE WHEN action_type = 'consult' THEN 1 ELSE 0 END) as has_consulted,
                   MAX(CASE WHEN action_type = 'click' THEN 1 ELSE 0 END) as has_clicked
            FROM user_actions
            WHERE interact_time >= DATE_SUB(NOW(), INTERVAL 180 DAY)
            GROUP BY external_userid
        """, conn)
        
        conn.close()
        
        # 2. 合并数据并计算RFM
        now = datetime.now()
        result = []
        
        for _, user in users.iterrows():
            external_userid = user['external_userid']
            
            # 查找该用户的互动记录
            user_interactions = interactions[interactions['external_userid'] == external_userid]
            
            if len(user_interactions) == 0:
                # 无任何互动
                r_score = 0
                f_score = 0
                m_score = 0
                level = '深度沉睡'
            else:
                row = user_interactions.iloc[0]
                
                # 计算R值
                last_interact = row['last_interact']
                days_since = (now - last_interact).days
                if days_since <= 30:
                    r_score = 5
                elif days_since <= 60:
                    r_score = 3
                elif days_since <= 90:
                    r_score = 1
                else:
                    r_score = 0
                
                # 计算F值
                active_days = row['active_days']
                if active_days >= 15:
                    f_score = 5
                elif active_days >= 10:
                    f_score = 4
                elif active_days >= 5:
                    f_score = 3
                elif active_days >= 1:
                    f_score = 2
                else:
                    f_score = 0
                
                # 计算M值
                if row['has_purchased'] == 1:
                    m_score = 5
                elif row['has_consulted'] == 1:
                    m_score = 3
                elif row['has_clicked'] == 1:
                    m_score = 1
                else:
                    m_score = 0
                
                # 根据RFM总分和分布确定层级
                total_score = r_score + f_score + m_score
                
                if total_score >= 12 and r_score >= 3:
                    level = '高价值活跃'
                elif total_score >= 8 and r_score >= 3:
                    level = '潜力用户'
                elif total_score >= 5 or r_score >= 3:
                    level = '轻度沉睡'
                elif total_score >= 2 or r_score >= 1:
                    level = '深度沉睡'
                else:
                    level = '濒临流失'
            
            result.append({
                'external_userid': external_userid,
                'r_score': r_score,
                'f_score': f_score,
                'm_score': m_score,
                'total_score': r_score + f_score + m_score,
                'level': level,
                'calc_date': now.date()
            })
        
        # 3. 保存计算结果
        df_result = pd.DataFrame(result)
        df_result.to_sql('user_rfm', conn, if_exists='replace', index=False)
        
        return df_result
    
    if __name__ == '__main__':
        calculate_rfm()
  3. 同步分层标签到企微:

python

复制代码
# sync_tags.py - 将分层结果同步到企微标签
def sync_rfm_tags():
    """将RFM分层结果同步为企微标签"""
    
    # 获取最新RFM计算结果
    conn = pymysql.connect(...)
    df = pd.read_sql("SELECT external_userid, level FROM user_rfm WHERE calc_date = CURDATE()", conn)
    conn.close()
    
    # 获取企微access_token
    token = get_access_token()
    
    # 为每个层级创建或获取标签ID
    level_tags = {}
    for level in df['level'].unique():
        tag_id = get_or_create_tag(token, "用户分层", level)
        level_tags[level] = tag_id
    
    # 批量打标签(注意企微API限制每次最多100个用户)
    batch_size = 100
    for i in range(0, len(df), batch_size):
        batch = df.iloc[i:i+batch_size]
        
        # 按层级分组,每组调用一次打标接口
        for level, group in batch.groupby('level'):
            external_userids = group['external_userid'].tolist()
            
            # 调用企微API打标签
            url = f"https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch_tag?access_token={token}"
            payload = {
                "tag_id": [level_tags[level]],
                "external_userid_list": external_userids
            }
            
            requests.post(url, json=payload)
            time.sleep(0.5)  # 避免触发频率限制
步骤3:代码实现 ------ 分层召回策略

python

复制代码
# recall_strategy.py - 分层召回策略执行
from datetime import datetime, timedelta
import random

class RecallEngine:
    """沉默用户召回引擎"""
    
    def __init__(self):
        self.executor = ActionExecutor()
    
    def run_recall(self):
        """执行召回任务(每日执行)"""
        
        # 获取不同层级的沉默用户
        conn = pymysql.connect(...)
        
        # 轻度沉睡:30天内无互动,但有过购买或深度互动
        mild_sleepers = pd.read_sql("""
            SELECT u.external_userid, u.level, r.last_interact, r.has_purchased
            FROM user_rfm r
            JOIN users u ON r.external_userid = u.external_userid
            WHERE r.level = '轻度沉睡' 
              AND DATE(u.last_recall) < DATE_SUB(CURDATE(), INTERVAL 30 DAY)
            LIMIT 500
        """, conn)
        
        # 深度沉睡:90天内无互动
        deep_sleepers = pd.read_sql("""
            SELECT u.external_userid, u.level
            FROM user_rfm r
            JOIN users u ON r.external_userid = u.external_userid
            WHERE r.level = '深度沉睡'
              AND DATE(u.last_recall) < DATE_SUB(CURDATE(), INTERVAL 60 DAY)
            LIMIT 300
        """, conn)
        
        # 濒临流失:180天内无互动
        losing_sleepers = pd.read_sql("""
            SELECT u.external_userid, u.level
            FROM user_rfm r
            JOIN users u ON r.external_userid = u.external_userid
            WHERE r.level = '濒临流失'
              AND DATE(u.last_recall) < DATE_SUB(CURDATE(), INTERVAL 90 DAY)
            LIMIT 200
        """, conn)
        
        conn.close()
        
        # 执行召回
        self._recall_mild(mild_sleepers)
        self._recall_deep(deep_sleepers)
        self._recall_losing(losing_sleepers)
    
    def _recall_mild(self, users):
        """轻度沉睡召回策略:发送行业干货+限时福利"""
        for _, user in users.iterrows():
            # 根据用户历史偏好选择内容
            if user.get('has_purchased'):
                # 曾购买过:推送进阶课程
                content = f"【专属福利】好久不见!您之前学习的课程现在出了进阶版,限时8折优惠。点击查看:https://yourdomain.com/advanced"
            else:
                # 未购买:推送行业报告
                content = f"【干货分享】我们整理了《2026教育行业趋势报告》,内含10个成功案例,回复"报告"免费领取!"
            
            # 发送消息
            self.executor.send_message({
                'user_id': user['external_userid'],
                'action': {'content': content}
            })
            
            # 更新召回记录
            self._update_recall_record(user['external_userid'], 'mild')
            time.sleep(1)  # 控制发送频率
    
    def _recall_deep(self, users):
        """深度沉睡召回策略:发送问卷调研+大额优惠券"""
        for _, user in users.iterrows():
            # 先发问卷
            content = f"【调研有礼】为了给您提供更好的服务,邀请您填写1分钟问卷,填写后领取100元课程优惠券!点击填写:https://yourdomain.com/survey"
            self.executor.send_message({
                'user_id': user['external_userid'],
                'action': {'content': content}
            })
            
            # 3天后若用户填写了问卷,自动发放优惠券(需监听问卷填写事件)
            # 这部分通过SOP规则实现
            
            self._update_recall_record(user['external_userid'], 'deep')
            time.sleep(1)
    
    def _recall_losing(self, users):
        """濒临流失召回策略:发送"告别信"+最后机会"""
        for _, user in users.iterrows():
            # 情感化召回
            content = f"【最后提醒】我们注意到您很久没来了,如果您不再需要我们的服务,请忽略这条消息。如果还想继续学习,回复"1"领取专属回归礼包(内含200元优惠券+精品课程)"
            
            self.executor.send_message({
                'user_id': user['external_userid'],
                'action': {'content': content}
            })
            
            self._update_recall_record(user['external_userid'], 'losing')
            time.sleep(1)
    
    def _update_recall_record(self, external_userid, recall_type):
        """更新召回记录"""
        conn = pymysql.connect(...)
        cursor = conn.cursor()
        cursor.execute("""
            UPDATE users 
            SET last_recall = NOW(), recall_count = recall_count + 1, last_recall_type = %s
            WHERE external_userid = %s
        """, (recall_type, external_userid))
        conn.commit()
        conn.close()

运行效果说明:

  • 每日凌晨,系统自动计算所有用户的RFM分值,并同步分层标签。

  • 轻度沉睡用户收到行业干货,若回复"报告"则自动推送资料并打上"已响应"标签。

  • 深度沉睡用户收到问卷链接,填写后自动发放优惠券。

  • 濒临流失用户收到情感化召回消息,回复"1"后触发优惠券发放。

  • 所有召回记录存入数据库,可统计各层级的响应率和转化率。

四、最佳实践与踩坑经验

  1. ⚠️ 召回频率控制:过度召回会加速用户流失。建议:

    • 同一用户每30天最多进入1次召回流程

    • 用户对召回无响应(如未回复、未点击)超过3次,自动标记为"无效用户",停止召回

    • 用户明确表示"不要再发了"(如回复"退订"),自动加入黑名单

  2. 性能优化:RFM计算可能涉及全量扫描,当用户量达到10万+时,直接查询数据库可能很慢。建议:

    • 使用ClickHouse或Elasticsearch存储行为数据

    • 计算结果缓存到Redis,供快速查询

    • 采用增量计算:只重新计算有新增行为的用户

  3. 💡 踩坑经验:关于会话存档:要获取用户最后一次互动时间,最准确的方式是通过企微的会话存档功能。但该功能需要额外付费且配置复杂。替代方案是记录通过API发送消息的日志和用户点击行为的日志,虽然无法覆盖用户主动发起的会话,但已足够用于RFM计算。

  4. 召回内容个性化:召回消息的打开率与内容相关度成正比。建议结合用户的历史行为(如浏览过的课程、下载过的资料)进行个性化推荐。例如,用户曾下载过"Python入门"资料,召回时可推送"Python进阶课程"的信息。

  5. A/B测试:对同一层级用户,可设计多种召回方案进行A/B测试,持续优化话术和优惠力度。例如,轻度沉睡用户分别测试"干货内容"vs"直接优惠券",看哪种转化率更高。

五、工具推荐:企销宝如何增强用户分层与召回能力

尽管自研RFM引擎能够实现基础的用户分层,但在实际运营中存在两个痛点:

  • 数据维度有限:仅靠API记录的消息发送和点击日志,无法全面反映用户活跃度(如用户是否阅读了朋友圈、是否在群内潜水)。

  • 缺乏自动化触达工具:召回消息需要个性化内容,且需要监控用户响应,自研开发量大。

企销宝通过iPad协议和RPA能力,提供了更全面的解决方案:

  • 技术优势:企销宝能够模拟人工浏览朋友圈,抓取用户的点赞、评论行为,补充RFM计算的数据维度。同时支持自动化朋友圈互动,对沉默用户的朋友圈进行点赞评论,实现"软触达"。

  • 智能召回SOP:企销宝内置沉默用户召回模板,可设置多轮召回策略:

    • 第一轮:朋友圈点赞互动(低成本触达)

    • 第二轮:私聊发送干货(中度触达)

    • 第三轮:发送优惠券(强刺激)

    • 第四轮:人工介入(若用户有响应)

      全程自动化执行,根据用户响应动态调整策略。

  • 适合场景:适用于大规模私域池(10万+用户)的精细化运营。通过企销宝的自动化分层召回,将沉默用户激活成本降低80%,同时避免人工操作的繁琐和遗漏。


下一篇预告:我们将深入探讨如何利用企微API与数据可视化工具,构建私域运营的数据监控与ROI分析体系,解决"做了没效果"的难题。敬请期待!

相关推荐
YMWM_2 小时前
jetson thor上的显存
人工智能·jetson thor
LY智网强哥2 小时前
GEO和SEO有什么区别?先做谁、怎么配合、各看什么指标
人工智能·产品运营
咚咚王者2 小时前
人工智能之语言领域 自然语言处理 第二十一章 综合实战项目
人工智能·自然语言处理
天空属于哈夫克32 小时前
释放双手:企业微信 RPA 协议级自动化深度集成方案
自动化·企业微信·rpa
张张123y2 小时前
AI大模型应用面试:深度学习知识点汇总与面试指导
人工智能·深度学习·面试
rosmis2 小时前
复杂工程拆解:自顶向下设计,自底向上实现
人工智能·python·机器人·自动化·自动驾驶·硬件工程·制造
hughnz2 小时前
斯伦贝谢成功的创新策略
人工智能·能源·钻井
m0_612591972 小时前
尚航科技 IDC 服务综合实力对比分析
人工智能·科技
柯儿的天空2 小时前
2026年AI技术突破与产业落地全景:从GPT-5到多模态智能体的新纪元
人工智能·gpt·microsoft·开源·aigc·ai编程·ai写作