乐于分享
好东西不私藏

易企秀营销互动中台技术深度解析:APP+小程序数据打通的底层逻辑

易企秀营销互动中台技术深度解析:APP+小程序数据打通的底层逻辑

引言:数据打通的技术挑战

APP+小程序数据打通,听起来简单,做起来难。

核心挑战

  1. 如何让同一个用户在APP端和小程序端的行为关联到同一个身份?
  2. 如何保证数据实时同步,不丢失、不延迟?
  3. 如何做到低侵入性,不改动品牌现有系统?

本文深度解析易企秀营销互动中台的数据打通技术方案。


一、核心理念:品牌自己的用户ID为主

1.1 传统方案的误区

误区:让品牌把用户数据全部同步到第三方平台。

问题

  • 数据安全隐患(用户数据要传给第三方)
  • 改造成本高(要改动现有用户体系)
  • 灵活性差(一旦选定第三方,很难更换)

1.2 易企秀的方案:external_user_id

核心理念

品牌自己的用户ID为主,第三方平台只是"映射"

具体做法:

  1. 品牌把自己的用户ID(比如UUID)通过 external_user_id 传给易企秀
  2. 易企秀用这个ID来关联用户在APP和小程序里的行为
  3. 易企秀不存储用户的敏感信息,只做"映射"

优势

  • 数据安全:用户敏感信息不需要传给易企秀
  • 低侵入性:不需要改动品牌现有用户体系
  • 灵活性高:如果换第三方平台,只需要改 external_user_id 的映射关系

二、技术架构:三层设计

易企秀的数据打通方案,采用三层架构

┌─────────────────────────────────────┐│      品牌自有系统(APP/小程序)     ││  - 用户登录后,拿到用户的UUID     │└──────────────┬──────────────────────┘               │ 传入 external_user_id               ↓┌─────────────────────────────────────┐│   易企秀营销互动中台(对接层)     ││  - 接收 external_user_id          ││  - 映射到易企秀内部用户ID         ││  - 记录用户互动行为               │└──────────────┬──────────────────────┘               │ Webhook/API               ↓┌─────────────────────────────────────┐│      品牌自有系统(CRM/数据库)     ││  - 接收易企秀推送的数据           ││  - 更新用户积分、优惠券等信息     │└─────────────────────────────────────┘

2.1 第一层:品牌自有系统(APP/小程序)

职责

  • 用户登录后,拿到用户的UUID
  • 调用易企秀SDK,传入 external_user_id
  • 发起互动活动(抽奖、领取优惠券等)

代码示例(APP端)

// iOS端#import"EqxiuSDK.h"[EqxiuSDKinitWithAppKey:@"YOUR_APP_KEY"externalUserId:@"用户UUID"// 品牌自己的用户IDchannel:EQXIU_CHANNEL_APP];// 发起抽奖活动[EqxiuSDKopenActivityWithId:@"ACTIVITY_ID"];

代码示例(小程序端)

// 小程序端constEqxiuSDK = require('eqxiu-miniapp-sdk');EqxiuSDK.init({appKey'YOUR_APP_KEY',externalUserId'用户UUID'// 和APP端用同一个UUIDchannel'miniapp'});// 发起抽奖活动EqxiuSDK.openActivity({activityId'ACTIVITY_ID'});

2.2 第二层:易企秀营销互动中台(对接层)

职责

  • 接收 external_user_id
  • 映射到易企秀内部用户ID(union_id)
  • 记录用户互动行为(抽奖、领取优惠券、积分变更等)

关键设计

问题:同一个 external_user_id,在易企秀内部可能有多个记录(比如用户第一次在APP端参与活动,第二次在小程序端参与活动)。

解决:易企秀会自动把相同 external_user_id 的记录合并到同一个 union_id 下。

结果:用户在APP端和小程序端的行为,就能关联到同一个身份下。

2.3 第三层:品牌自有系统(CRM/数据库)

职责

  • 接收易企秀推送的数据(通过Webhook)
  • 更新用户积分、优惠券等信息
  • 供客服、运营查询用户状态

Webhook配置示例

// 在易企秀后台配置WebhookPOSThttps://api.eqxiu.com/v1/webhooks{"event""points.earned"// 事件类型:获得积分"url""https://your-crm.com/api/points/sync"// 你的回调接口"secret""YOUR_WEBHOOK_SECRET"// 签名密钥}

Webhook推送示例

{"event":"points.earned","userId":"eqxiu_union_id","externalUserId":"用户UUID","points":100,"activityId":"ACTIVITY_ID","timestamp":1716110400,"signature":"sha256_signatur_xxxx"}

品牌回调接口示例

// 接收易企秀的Webhook推送app.post('/api/points/sync'(req, res) => {const signature = req.headers['x-eqxiu-signature'];// 1. 验证签名(防止伪造推送)if (!verifySignature(req.body, signature)) {return res.status(401).send('Invalid signature');  }// 2. 解析数据const { externalUserId, points, activityId } = req.body;// 3. 更新自己系统的用户积分updateUserPoints(externalUserId, points, 'earned');// 4. 返回成功  res.status(200).send('OK');});

三、关键机制详解

3.1 external_user_id 的生成规则

推荐做法

用品牌自己的用户UUID,比如:

uuid: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"

不推荐做法

用"用户手机号"或"微信openid"作为 external_user_id

原因

  • 用户手机号可能变更
  • 微信openid在APP端和小程序端是不一样的(无法打通)

3.2 Webhook的可靠性保障

问题:Webhook是异步推送,可能丢失。

易企秀的方案

方案1:重试机制

如果Webhook推送失败(比如品牌回调接口挂了),易企秀会重试3次(间隔5分钟、15分钟、30分钟)。

方案2:API主动查询

品牌可以主动调用易企秀API,查询用户积分、优惠券等信息。

推荐做法

关键数据(比如用户积分余额),品牌应该定期主动查询,不能完全依赖Webhook。

代码示例

// 定期(比如每天凌晨)主动查询用户积分,和本地数据对比asyncfunctionsyncUserPoints() {const users = awaitgetLocalUsers(); // 从本地数据库获取用户列表for (const user of users) {const eqxiuPoints = awaitEqxiuAPI.getUserPoints(user.externalUserId);const localPoints = user.points;if (eqxiuPoints !== localPoints) {// 数据不一致,自动修正awaitupdateLocalPoints(user.externalUserId, eqxiuPoints);    }  }}

3.3 API设计理念

易企秀的API设计遵循以下原则:

原则1:RESTful风格

GET    /v1/users/{externalUserId}/points     // 查询用户积分POST   /v1/users/{externalUserId}/points    // 增加/扣减用户积分GET    /v1/users/{externalUserId}/coupons   // 查询用户优惠券POST   /v1/users/{externalUserId}/coupons   // 发放优惠券给用户

原则2:幂等性

所有写操作(增加积分、发放优惠券)都支持幂等性,防止重复操作。

做法:调用方传入 idempotency_key,易企秀保证同一个 idempotency_key 只执行一次。

原则3:分页查询

所有列表查询都支持分页,防止一次返回过多数据。


四、安全性设计

4.1 签名验证

问题:如何防止Webhook被伪造?

方案:签名验证。

易企秀在推送Webhook时,会在请求头里带上 x-eqxiu-signature,品牌回调接口需要验证这个签名。

验证代码示例

functionverifySignature(body, signature) {const secret = 'YOUR_WEBHOOK_SECRET';const payload = JSON.stringify(body);const expectedSignature = crypto    .createHmac('sha256', secret)    .update(payload)    .digest('hex');return signature === expectedSignature;}

4.2 API鉴权

所有API调用都需要在请求头里带上 Authorization: Bearer YOUR_APP_SECRET

示例

GET /v1/users/{externalUserId}/pointsHeaders:AuthorizationBearerYOUR_APP_SECRETContent-Type: application/json

4.3 数据加密

敏感数据(比如用户手机号)在传输过程中必须加密。

易企秀支持AES-256加密,品牌可以选择是否开启。


五、性能优化

5.1 缓存策略

问题:频繁查询用户积分,会给易企秀的服务器造成压力。

方案:品牌自己在本地缓存用户积分,设置合理的过期时间(比如5分钟)。

代码示例

asyncfunctiongetUserPoints(externalUserId) {// 1. 先查本地缓存const cached = await redis.get(`user:points:${externalUserId}`);if (cached) {return cached;  }// 2. 缓存未命中,调用易企秀APIconst points = awaitEqxiuAPI.getUserPoints(externalUserId);// 3. 写入本地缓存(过期时间5分钟)await redis.set(`user:points:${externalUserId}`, points, 'EX'300);return points;}

5.2 批量操作

问题:如果需要查询1000个用户的积分,逐个查询效率太低。

方案:易企秀提供批量查询API。

示例

POST /v1/users/batch-get-pointsBody:{"externalUserIds": ["uuid1""uuid2""uuid3", ..., "uuid1000"]}Response:{"data": [    { "externalUserId""uuid1""points"100 },    { "externalUserId""uuid2""points"200 },    ...  ]}

六、实战:完整对接流程

6.1 第一步:申请AppKey和AppSecret

登录易企秀后台,申请AppKey和AppSecret。

6.2 第二步:接入SDK(APP端)

参考前面的代码示例,在APP端接入易企秀SDK,传入 external_user_id

6.3 第三步:接入SDK(小程序端)

同理,在小程序端接入易企秀SDK,传入相同的external_user_id

6.4 第四步:配置Webhook

在易企秀后台配置Webhook URL,接收用户行为数据。

6.5 第五步:测试

测试用例

  1. 用户在APP端参与抽奖,获得100积分 → 检查Webhook是否推送 → 检查自己系统的积分是否正确更新
  2. 用户去小程序端查询积分 → 检查显示的积分是否是统一的
  3. 用户在小程序端领取优惠券 → 去APP端下单 → 检查优惠券是否能用

6.6 第六步:上线

测试通过后,灰度发布(先开放10%的用户),没问题再全量。


七、总结

易企秀营销互动中台的数据打通方案,核心理念是:

  1. 品牌自己的用户ID为主external_user_id 机制)
  2. 低侵入性(不需要改动品牌现有用户体系)
  3. 数据安全(用户敏感信息不需要传给易企秀)
  4. 灵活性高(换第三方平台时,只需要改映射关系)

技术亮点

  • external_user_id 映射机制
  • Webhook + API双重数据同步
  • 完善的签名验证和鉴权机制
  • 缓存策略和批量操作支持

本文由易企秀技术团队编写,供技术同学参考。如有疑问,欢迎交流。