Optimizely 连接器

通过 Tajo 将 Optimizely Feature Experimentation 连接到 Brevo,同步实验结果,按功能标志细分目标活动,并用 A/B 测试数据和受众洞察丰富营销自动化。

概览

属性
平台Optimizely
类别实验(自定义)
设置复杂度中等
官方集成
同步数据实验、受众、事件、功能标志
认证方式个人访问令牌 / OAuth 2.0

功能

  • 实验同步 - 将 A/B 测试变体分配推送到 Brevo 联系人属性
  • 受众定向 - 使用 Optimizely 受众进行 Brevo 活动细分
  • 转化跟踪 - 追踪 Optimizely 事件并映射到 Brevo 事件追踪
  • 功能标志同步 - 按已启用的功能标志细分联系人
  • 结果报告 - 同步实验结果,用于实验后营销活动分析
  • 多项目支持 - 将多个 Optimizely 项目连接到单个 Tajo 实例

前提条件

开始之前,请确保您已具备:

  1. Optimizely Feature Experimentation 账户
  2. 来自 Optimizely 应用设置 的个人访问令牌
  3. 您的 Optimizely 环境 SDK 密钥
  4. 具有 API 访问权限的 Brevo 账户
  5. 具有连接器权限的 Tajo 账户

认证

个人访问令牌

Terminal window
# Generate at https://app.optimizely.com/v2/accountsettings/tokens
export OPTIMIZELY_ACCESS_TOKEN=your_personal_access_token
export OPTIMIZELY_SDK_KEY=your_sdk_key
export TAJO_API_KEY=your_tajo_api_key
export BREVO_API_KEY=your_brevo_api_key
// All REST API requests use Bearer token auth
const headers = {
'Authorization': `Bearer ${process.env.OPTIMIZELY_ACCESS_TOKEN}`,
'Content-Type': 'application/json'
};

SDK 认证

// For feature flag evaluation, use the SDK
const optimizelySDK = require('@optimizely/optimizely-sdk');
const optimizelyClient = optimizelySDK.createInstance({
sdkKey: process.env.OPTIMIZELY_SDK_KEY,
datafileOptions: {
autoUpdate: true,
updateInterval: 60000 // 1 minute
}
});
await optimizelyClient.onReady();

配置

基础设置

connectors:
optimizely:
enabled: true
access_token: "${OPTIMIZELY_ACCESS_TOKEN}"
sdk_key: "${OPTIMIZELY_SDK_KEY}"
project_id: "12345678"
sync:
experiments: true
audiences: true
events: true
feature_flags: true
schedule: "0 */2 * * *" # Every 2 hours
mapping:
experiment_variation: EXPERIMENT_VARIATION
feature_flags: ENABLED_FEATURES
audience_segments: OPT_SEGMENTS

字段映射

field_mapping:
user_id: email
experiment_key: EXPERIMENT_NAME
variation_key: VARIATION_NAME
feature_key: FEATURE_FLAG
enabled: FEATURE_ENABLED
audience_name: AUDIENCE_SEGMENT
decision_timestamp: EXPERIMENT_DATE

API 端点

端点方法描述
https://api.optimizely.com/v2/projectsGET列出项目
https://api.optimizely.com/v2/experimentsGET列出实验
https://api.optimizely.com/v2/experiments/{id}GET获取实验详情
https://api.optimizely.com/v2/experiments/{id}/resultsGET获取实验结果
https://api.optimizely.com/v2/featuresGET列出功能标志
https://api.optimizely.com/v2/features/{id}GET获取功能标志
https://api.optimizely.com/v2/audiencesGET列出受众
https://api.optimizely.com/v2/eventsGET列出追踪事件
https://logx.optimizely.com/v1/eventsPOST追踪事件(SDK 端点)

代码示例

初始化连接器

import { TajoClient } from '@tajo/sdk';
const tajo = new TajoClient({
apiKey: process.env.TAJO_API_KEY,
brevoApiKey: process.env.BREVO_API_KEY
});
await tajo.connectors.connect('optimizely', {
accessToken: process.env.OPTIMIZELY_ACCESS_TOKEN,
sdkKey: process.env.OPTIMIZELY_SDK_KEY,
projectId: '12345678'
});

将实验决策同步到 Brevo

// Track experiment decisions and sync to Brevo
const optimizelyClient = optimizelySDK.createInstance({
sdkKey: process.env.OPTIMIZELY_SDK_KEY
});
await optimizelyClient.onReady();
// Register a decision notification listener
optimizelyClient.notificationCenter.addNotificationListener(
optimizelySDK.enums.NOTIFICATION_TYPES.DECISION,
async (decisionObject) => {
const { type, userId, attributes, decisionInfo } = decisionObject;
if (type === 'feature' || type === 'ab-test') {
const email = attributes.email;
if (email) {
await tajo.contacts.update(email, {
attributes: {
EXPERIMENT_NAME: decisionInfo.experimentKey || decisionInfo.featureKey,
VARIATION_NAME: decisionInfo.variationKey,
FEATURE_ENABLED: decisionInfo.featureEnabled || false,
EXPERIMENT_DATE: new Date().toISOString()
}
});
}
}
}
);

同步实验结果

// Fetch experiment results and sync winning segments
const resultsResponse = await fetch(
`https://api.optimizely.com/v2/experiments/${experimentId}/results`,
{
headers: {
'Authorization': `Bearer ${process.env.OPTIMIZELY_ACCESS_TOKEN}`
}
}
);
const results = await resultsResponse.json();
// Process variations and update contact segments
for (const variation of results.metrics) {
const isWinner = variation.is_improvement && variation.statistical_significance >= 0.95;
if (isWinner) {
// Create a Brevo segment for users in the winning variation
console.log(`Winning variation: ${variation.variation_name}`);
}
}

基于功能标志的细分

// Evaluate feature flags for user segmentation
async function syncFeatureFlags(userEmail, userId) {
const features = ['new_checkout', 'loyalty_program', 'ai_recommendations'];
const enabledFeatures = [];
for (const feature of features) {
const user = optimizelyClient.createUserContext(userId, {
email: userEmail
});
const decision = user.decide(feature);
if (decision.enabled) {
enabledFeatures.push(feature);
}
}
await tajo.contacts.update(userEmail, {
attributes: {
ENABLED_FEATURES: enabledFeatures.join(', '),
FEATURE_FLAGS_SYNCED: new Date().toISOString()
}
});
}

速率限制

端点限制说明
REST API50 请求/分钟每个人访问令牌
结果 API10 请求/分钟延迟较高,查询较重
SDK 事件分发每批 10,000 个事件通过 SDK 事件处理器
数据文件 CDN无限制带自动更新的缓存

结果 API 延迟

实验结果 API 处理大型数据集,响应可能需要 30 秒以上。使用异步轮询或缓存以避免阻塞应用程序。

故障排除

问题原因解决方案
401 Unauthorized令牌过期/无效重新生成个人访问令牌
SDK 未就绪数据文件未加载等待 onReady() Promise 解析
未记录决策未注册通知在做出决策前注册监听器
功能标志陈旧数据文件缓存设置 updateInterval 自动刷新
结果缺失实验未启动验证实验状态为”running”

调试模式

connectors:
optimizely:
debug: true
log_level: verbose
log_decisions: true
log_events: true

最佳实践

  1. 使用 SDK 进行决策 - SDK 用于实时标志评估,REST API 用于管理
  2. 实施事件批处理 - 批量 SDK 事件以减少网络开销
  3. 缓存数据文件 - 以适当间隔启用自动更新
  4. 同步获胜变体 - 实验结束后,更新联系人细分
  5. 使用属性进行定向 - 传递邮箱和用户属性以进行受众匹配
  6. 监控实验状态 - 只同步正在运行或已结束的实验数据

安全

  • 个人访问令牌 - REST API 的 Bearer 令牌认证
  • SDK 密钥隔离 - 每个环境(开发、测试、生产)使用独立 SDK 密钥
  • 服务端评估 - 服务器端评估功能标志以防止暴露
  • 令牌轮换 - 定期轮换个人访问令牌
  • 最小权限 - 不需要写入权限时使用只读令牌
  • 加密传输 - 所有 API 和 SDK 通信使用 TLS 1.2+

相关资源

Subscribe to updates

developer-docs

Drop your email or phone number — we'll send you what matters next.

auto-detect
AI 助手

你好!关于文档有任何问题都可以问我。