Optimizely コネクタ
Tajo を介して Optimizely Feature Experimentation を Brevo に接続し、実験結果を同期し、機能フラグセグメントでキャンペーンをターゲティングし、A/B テストデータとオーディエンスインサイトでマーケティング自動化を強化します。
概要
| プロパティ | 値 |
|---|---|
| プラットフォーム | Optimizely |
| カテゴリ | 実験(カスタム) |
| セットアップの複雑さ | 中 |
| 公式統合 | いいえ |
| 同期データ | 実験、オーディエンス、イベント、機能フラグ |
| 認証方式 | Personal Access Token / OAuth 2.0 |
機能
- 実験の同期 - A/B テストのバリエーション割り当てを Brevo 連絡先属性にプッシュ
- オーディエンスターゲティング - Brevo キャンペーンのセグメンテーションに Optimizely オーディエンスを使用
- コンバージョントラッキング - Optimizely イベントをトラッキングして Brevo イベントトラッキングにマッピング
- 機能フラグの同期 - 有効化された機能フラグで連絡先をセグメント化
- 結果レポート - 事後分析マーケティングキャンペーン用に実験結果を同期
- マルチプロジェクトサポート - 複数の Optimizely プロジェクトを単一の Tajo インスタンスに接続
前提条件
開始する前に、以下を準備してください。
- Optimizely Feature Experimentation アカウント
- Optimizely App Settings からの Personal Access Token
- Optimizely 環境の SDK キー
- API アクセス可能な Brevo アカウント
- コネクタ権限を持つ Tajo アカウント
認証
Personal Access Token
# https://app.optimizely.com/v2/accountsettings/tokens で生成export OPTIMIZELY_ACCESS_TOKEN=your_personal_access_tokenexport OPTIMIZELY_SDK_KEY=your_sdk_keyexport TAJO_API_KEY=your_tajo_api_keyexport BREVO_API_KEY=your_brevo_api_key// すべての REST API リクエストは Bearer トークン認証を使用const headers = { 'Authorization': `Bearer ${process.env.OPTIMIZELY_ACCESS_TOKEN}`, 'Content-Type': 'application/json'};SDK 認証
// 機能フラグ評価には SDK を使用const optimizelySDK = require('@optimizely/optimizely-sdk');
const optimizelyClient = optimizelySDK.createInstance({ sdkKey: process.env.OPTIMIZELY_SDK_KEY, datafileOptions: { autoUpdate: true, updateInterval: 60000 // 1 分 }});
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 * * *" # 2 時間ごと
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_DATEAPI エンドポイント
| エンドポイント | メソッド | 説明 |
|---|---|---|
https://api.optimizely.com/v2/projects | GET | プロジェクトを一覧取得 |
https://api.optimizely.com/v2/experiments | GET | 実験を一覧取得 |
https://api.optimizely.com/v2/experiments/{id} | GET | 実験詳細を取得 |
https://api.optimizely.com/v2/experiments/{id}/results | GET | 実験結果を取得 |
https://api.optimizely.com/v2/features | GET | 機能フラグを一覧取得 |
https://api.optimizely.com/v2/features/{id} | GET | 機能フラグを取得 |
https://api.optimizely.com/v2/audiences | GET | オーディエンスを一覧取得 |
https://api.optimizely.com/v2/events | GET | トラッキングされたイベントを一覧取得 |
https://logx.optimizely.com/v1/events | POST | イベントをトラッキング(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 に同期
// 実験の意思決定をトラッキングして Brevo に同期const optimizelyClient = optimizelySDK.createInstance({ sdkKey: process.env.OPTIMIZELY_SDK_KEY});
await optimizelyClient.onReady();
// 意思決定通知リスナーを登録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() } }); } } });実験結果の同期
// 実験結果を取得して勝ちセグメントを同期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();
// バリエーションを処理して連絡先セグメントを更新for (const variation of results.metrics) { const isWinner = variation.is_improvement && variation.statistical_significance >= 0.95;
if (isWinner) { // 勝ちバリエーションのユーザー用 Brevo セグメントを作成 console.log(`Winning variation: ${variation.variation_name}`); }}機能フラグベースのセグメンテーション
// ユーザーセグメンテーションのために機能フラグを評価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 API | 50 req/分 | Personal Access Token 単位 |
| Results API | 10 req/分 | 高レイテンシ、重いクエリ |
| SDK イベントディスパッチ | 10,000 イベント/バッチ | SDK イベントプロセッサ経由 |
| Datafile CDN | 無制限 | 自動更新でキャッシュ |
Results API のレイテンシ
Experiment Results API は大量のデータセットを処理するため、応答に 30 秒以上かかる場合があります。アプリケーションのブロックを避けるため、非同期ポーリングまたはキャッシングを使用してください。
トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
| 401 Unauthorized | トークン期限切れ/無効 | Personal Access Token を再生成 |
| SDK 未準備 | Datafile がロードされていない | onReady() プロミスの解決を待つ |
| 意思決定がログに記録されない | 通知が登録されていない | 意思決定を行う前にリスナーを登録 |
| 古い機能フラグ | Datafile のキャッシュ | 自動更新のため updateInterval を設定 |
| 結果の欠落 | 実験が開始されていない | 実験ステータスが「running」であることを確認 |
デバッグモード
connectors: optimizely: debug: true log_level: verbose log_decisions: true log_events: trueベストプラクティス
- 意思決定には SDK を使用する - リアルタイムのフラグ評価には SDK を、管理には REST API を使用
- イベントのバッチ処理を実装する - ネットワークオーバーヘッドを削減するため SDK イベントをバッチ処理
- Datafile をキャッシュする - 適切な間隔で自動更新を有効化
- 勝ちバリエーションを同期する - 実験終了後、連絡先セグメントを更新
- ターゲティングに属性を使用する - オーディエンスマッチングのためにメールとユーザー属性を渡す
- 実験ステータスを監視する - 実行中または終了した実験からのみデータを同期
セキュリティ
- Personal Access Tokens - REST API 用の Bearer トークン認証
- SDK キーの分離 - 環境ごとに個別の SDK キー(dev、staging、prod)
- サーバーサイド評価 - 機能フラグをサーバーサイドで評価して公開を防止
- トークンのローテーション - Personal Access Token を定期的にローテーション
- 最小限の権限 - 書き込みアクセスが不要な場合は読み取り専用トークンを使用
- 暗号化された通信 - すべての API および SDK 通信に TLS 1.2 以上