Optimizely-connector
Verbind Optimizely Feature Experimentation met Brevo via Tajo om experimentresultaten te synchroniseren, campagnes te targeten op feature flag-segmenten en marketingautomatiseringen te verrijken met A/B-testdata en audience-inzichten.
Overzicht
| Eigenschap | Waarde |
|---|---|
| Platform | Optimizely |
| Categorie | Experimentation (Custom) |
| Setupcomplexiteit | Gemiddeld |
| Officiële integratie | Nee |
| Gesynchroniseerde data | Experiments, Audiences, Events, Feature Flags |
| Auth-methode | Personal Access Token / OAuth 2.0 |
Functies
- Experimentsynchronisatie - Push A/B-testvariatie-toewijzingen naar Brevo-contactattributen
- Audience-targeting - Gebruik Optimizely-audiences voor Brevo-campagnesegmentatie
- Conversion tracking - Volg Optimizely-events en map ze naar Brevo-eventtracking
- Feature flag-synchronisatie - Segmenteer contacten op basis van geactiveerde feature flags
- Resultaatrapportage - Synchroniseer experimentresultaten voor marketingcampagnes na analyse
- Multi-projectondersteuning - Verbind meerdere Optimizely-projecten aan één Tajo-instantie
Vereisten
Voordat je begint, zorg dat je beschikt over:
- Een Optimizely Feature Experimentation-account
- Een Personal Access Token via Optimizely App Settings
- Een SDK key voor je Optimizely-environment
- Een Brevo-account met API-toegang
- Een Tajo-account met connector-rechten
Authenticatie
Personal Access Token
# Generate at https://app.optimizely.com/v2/accountsettings/tokensexport 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// All REST API requests use Bearer token authconst headers = { 'Authorization': `Bearer ${process.env.OPTIMIZELY_ACCESS_TOKEN}`, 'Content-Type': 'application/json'};SDK-authenticatie
// For feature flag evaluation, use the SDKconst 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();Configuratie
Basisinstelling
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_SEGMENTSVeldmapping
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-endpoints
| Endpoint | Method | Beschrijving |
|---|---|---|
https://api.optimizely.com/v2/projects | GET | Projecten opvragen |
https://api.optimizely.com/v2/experiments | GET | Experimenten opvragen |
https://api.optimizely.com/v2/experiments/{id} | GET | Experimentdetails ophalen |
https://api.optimizely.com/v2/experiments/{id}/results | GET | Experimentresultaten ophalen |
https://api.optimizely.com/v2/features | GET | Feature flags opvragen |
https://api.optimizely.com/v2/features/{id} | GET | Feature flag ophalen |
https://api.optimizely.com/v2/audiences | GET | Audiences opvragen |
https://api.optimizely.com/v2/events | GET | Getrackte events opvragen |
https://logx.optimizely.com/v1/events | POST | Events tracken (SDK-endpoint) |
Codevoorbeelden
Connector initialiseren
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'});Experiment-decisions synchroniseren naar Brevo
// Track experiment decisions and sync to Brevoconst optimizelyClient = optimizelySDK.createInstance({ sdkKey: process.env.OPTIMIZELY_SDK_KEY});
await optimizelyClient.onReady();
// Register a decision notification listeneroptimizelyClient.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() } }); } } });Experimentresultaten synchroniseren
// Fetch experiment results and sync winning segmentsconst 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 segmentsfor (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}`); }}Feature flag-gebaseerde segmentatie
// Evaluate feature flags for user segmentationasync 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() } });}Rate limits
| Endpoint | Limiet | Opmerkingen |
|---|---|---|
| REST API | 50 req/min | Per personal access token |
| Results API | 10 req/min | Hogere latency, zwaardere queries |
| SDK Event Dispatch | 10.000 events/batch | Via SDK event processor |
| Datafile CDN | Onbeperkt | Gecached met auto-updates |
Latency van Results API
De Experiment Results API verwerkt grote datasets en kan 30+ seconden nodig hebben om te reageren. Gebruik async polling of caching om je applicatie niet te blokkeren.
Probleemoplossing
| Probleem | Oorzaak | Oplossing |
|---|---|---|
| 401 Unauthorized | Token verlopen/ongeldig | Regenereer Personal Access Token |
| SDK niet ready | Datafile niet geladen | Wacht tot de onReady()-promise resolved |
| Geen decisions gelogd | Notification niet geregistreerd | Registreer listener voordat decisions worden gemaakt |
| Stale feature flags | Datafile-cache | Stel updateInterval in voor auto-refresh |
| Resultaten ontbreken | Experiment niet gestart | Verifieer dat experimentstatus “running” is |
Debugmodus
connectors: optimizely: debug: true log_level: verbose log_decisions: true log_events: trueBest practices
- Gebruik de SDK voor decisions - Gebruik de SDK voor realtime flag-evaluatie, REST API voor management
- Implementeer event-batching - Batch SDK-events om netwerkoverhead te beperken
- Cache de datafile - Schakel auto-update in met passende intervallen
- Synchroniseer winnende variaties - Update contactsegmenten nadat experimenten afgesloten zijn
- Gebruik attributes voor targeting - Geef email en gebruikersattributen door voor audience-matching
- Monitor experimentstatus - Synchroniseer alleen data van lopende of afgesloten experimenten
Beveiliging
- Personal Access Tokens - Bearer-token-authenticatie voor REST API
- SDK key-isolatie - Aparte SDK keys per environment (dev, staging, prod)
- Server-side evaluatie - Evalueer feature flags server-side om blootstelling te voorkomen
- Tokenrotatie - Roteer Personal Access Tokens regelmatig
- Minimale rechten - Gebruik read-only tokens wanneer geen schrijftoegang nodig is
- Versleuteld transport - TLS 1.2+ voor alle API- en SDK-communicatie