Optimizely-koppling
Anslut Optimizely Feature Experimentation till Brevo via Tajo för att synka experimentresultat, rikta kampanjer efter feature flag-segment och berika marknadsautomationer med A/B-testdata och målgruppsinsikter.
Översikt
| Egenskap | Värde |
|---|---|
| Plattform | Optimizely |
| Kategori | Experimentation (Anpassad) |
| Installationskomplexitet | Medel |
| Officiell integration | Nej |
| Data som synkas | Experiment, målgrupper, händelser, feature flags |
| Autentiseringsmetod | Personal Access Token / OAuth 2.0 |
Funktioner
- Experimentsynkronisering - Skicka A/B-testvariationstilldelningar till Brevo-kontaktattribut
- Målgruppsmålning - Använd Optimizely-målgrupper för Brevo-kampanjsegmentering
- Konverteringsspårning - Spåra Optimizely-händelser och mappa till Brevo-händelsespårning
- Feature flag-synkronisering - Segmentera kontakter efter aktiverade feature flags
- Resultatrapportering - Synka experimentresultat för efteranalysmarknadsföringskampanjer
- Stöd för flera projekt - Anslut flera Optimizely-projekt till en enskild Tajo-instans
Förutsättningar
Innan du börjar, se till att du har:
- Ett Optimizely Feature Experimentation-konto
- En Personal Access Token från Optimizely App Settings
- En SDK-nyckel för din Optimizely-miljö
- Ett Brevo-konto med API-åtkomst
- Ett Tajo-konto med kopplingsbehörigheter
Autentisering
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-autentisering
// 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();Konfiguration
Grundinställning
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_SEGMENTSFältmappning
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 | Metod | Beskrivning |
|---|---|---|
https://api.optimizely.com/v2/projects | GET | Lista projekt |
https://api.optimizely.com/v2/experiments | GET | Lista experiment |
https://api.optimizely.com/v2/experiments/{id} | GET | Hämta experimentdetaljer |
https://api.optimizely.com/v2/experiments/{id}/results | GET | Hämta experimentresultat |
https://api.optimizely.com/v2/features | GET | Lista feature flags |
https://api.optimizely.com/v2/features/{id} | GET | Hämta feature flag |
https://api.optimizely.com/v2/audiences | GET | Lista målgrupper |
https://api.optimizely.com/v2/events | GET | Lista spårade händelser |
https://logx.optimizely.com/v1/events | POST | Spåra händelser (SDK-endpoint) |
Kodexempel
Initiera kopplingen
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'});Synka experimentbeslut till 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() } }); } } });Synka experimentresultat
// 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}`); }}Segmentering baserat på feature flag
// 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() } });}Hastighetsbegränsningar
| Endpoint | Gräns | Anteckningar |
|---|---|---|
| REST API | 50 förfrågningar/min | Per personal access token |
| Results API | 10 förfrågningar/min | Högre latens, tyngre frågor |
| SDK Event Dispatch | 10 000 händelser/batch | Via SDK-händelseprocessor |
| Datafile CDN | Obegränsat | Cachat med autouppdateringar |
Latens för Results API
Experiment Results API behandlar stora dataset och kan ta 30+ sekunder att svara. Använd asynkron polling eller cachning för att undvika att blockera din applikation.
Felsökning
| Problem | Orsak | Lösning |
|---|---|---|
| 401 Unauthorized | Token utgången/ogiltig | Återgenerera Personal Access Token |
| SDK ej redo | Datafilen ej laddad | Vänta på att onReady()-löftet löses |
| Inga beslut loggade | Notifiering ej registrerad | Registrera lyssnare innan beslut fattas |
| Inaktuella feature flags | Datafilcache | Sätt updateInterval för autouppdatering |
| Saknade resultat | Experiment ej startat | Verifiera att experimentstatus är “running” |
Felsökningsläge
connectors: optimizely: debug: true log_level: verbose log_decisions: true log_events: trueBästa praxis
- Använd SDK för beslut - Använd SDK för flagutvärdering i realtid, REST API för hantering
- Implementera händelsebatchning - Batcha SDK-händelser för att minska nätverksoverhead
- Cacha datafilen - Aktivera autouppdatering med lämpliga intervall
- Synka vinnande variationer - Efter att experiment avslutats, uppdatera kontaktsegment
- Använd attribut för målning - Skicka e-post och användarattribut för målgruppsmatchning
- Övervaka experimentstatus - Synka endast data från pågående eller avslutade experiment
Säkerhet
- Personal Access Tokens - Bearer-tokenautentisering för REST API
- SDK-nyckelisolering - Separata SDK-nycklar per miljö (dev, staging, prod)
- Utvärdering på serversidan - Utvärdera feature flags på serversidan för att förhindra exponering
- Tokenrotation - Rotera Personal Access Tokens regelbundet
- Minimala behörigheter - Använd skrivskyddade tokens när skrivåtkomst inte behövs
- Krypterad transport - TLS 1.2+ för all API- och SDK-kommunikation