Woopra Data Layer Setup | OpsBlu Docs

Woopra Data Layer Setup

How to configure data layer variables and user properties for Woopra. Covers data preparation, custom properties, event enrichment, and integration with.

Overview

Woopra's data layer allows you to enrich your analytics with user properties, account information, and custom attributes. Proper data layer setup enables powerful segmentation, personalization, and user journey analysis.

User Identification

Basic User Identification

Identify users with their core properties:

woopra.identify({
  email: 'user@example.com',
  name: 'John Doe',
  company: 'Acme Inc',
  plan: 'enterprise'
});

Complete User Profile

Include comprehensive user data for deeper insights:

woopra.identify({
  // Required identifiers
  email: 'user@example.com',
  id: 'user_12345',

  // Personal information
  name: 'John Doe',
  firstName: 'John',
  lastName: 'Doe',
  phone: '+1-555-0123',

  // Company information
  company: 'Acme Inc',
  companySize: '50-200',
  industry: 'Technology',

  // Account details
  plan: 'enterprise',
  mrr: 299,
  signupDate: '2024-01-15',
  trialEndsAt: '2024-02-15',

  // Custom properties
  referralSource: 'google_ads',
  campaignId: 'summer_2024',
  isVip: true,
  lifetimeValue: 3588
});

Visitor Properties

Setting Individual Properties

Set properties one at a time:

woopra.identify('email', 'user@example.com')
      .identify('name', 'John Doe')
      .identify('plan', 'pro')
      .push();

Updating User Properties

Update properties as users progress through your app:

// User upgrades plan
woopra.identify({
  plan: 'enterprise',
  upgradedAt: Date.now(),
  previousPlan: 'pro'
});

// User completes onboarding
woopra.identify({
  onboardingCompleted: true,
  onboardingCompletedAt: Date.now(),
  onboardingStepsCompleted: 5
});

// User reaches milestone
woopra.identify({
  projectsCreated: 10,
  teamMembers: 5,
  storageUsed: 2.5,  // GB
  lastActiveAt: Date.now()
});

Property Types and Naming

Supported Data Types

Woopra supports various property types:

woopra.identify({
  // Strings
  email: 'user@example.com',
  plan: 'enterprise',
  status: 'active',

  // Numbers
  age: 32,
  mrr: 299.99,
  loginCount: 47,

  // Booleans
  isActive: true,
  hasCompletedOnboarding: false,
  isEmailVerified: true,

  // Dates (use timestamps or ISO strings)
  createdAt: Date.now(),
  lastLoginAt: '2024-01-15T10:30:00Z',

  // Arrays (as comma-separated strings)
  interests: 'analytics,marketing,sales',
  features: 'export,api,integrations'
});

Property Naming Conventions

Use consistent, descriptive property names:

// Good - consistent camelCase
woopra.identify({
  firstName: 'John',
  lastName: 'Doe',
  signupDate: '2024-01-15',
  isEmailVerified: true
});

// Avoid - inconsistent naming
woopra.identify({
  first_name: 'John',
  LastName: 'Doe',
  signup_date: '2024-01-15',
  email_verified: true
});

Account-Level Properties

B2B Account Tracking

Track both user and account (company) properties:

woopra.identify({
  // User properties
  email: 'john@acme.com',
  name: 'John Doe',
  role: 'Admin',
  userId: 'user_12345',

  // Account properties
  accountId: 'acct_789',
  accountName: 'Acme Inc',
  accountPlan: 'Enterprise',
  accountMrr: 999,
  accountSeats: 25,
  accountIndustry: 'Technology',
  accountCreatedAt: '2023-06-01'
});

Multi-Tenant Applications

Handle users across multiple accounts:

// User switches between accounts
function switchAccount(accountId) {
  const account = getAccountData(accountId);

  woopra.identify({
    currentAccountId: accountId,
    currentAccountName: account.name,
    currentAccountPlan: account.plan,
    accountSwitchedAt: Date.now()
  });

  woopra.track('account_switched', {
    from_account: previousAccountId,
    to_account: accountId
  });
}

Conditional Properties

Dynamic Property Setting

Set properties based on user state or behavior:

// Identify based on user type
if (user.isLoggedIn) {
  woopra.identify({
    email: user.email,
    name: user.name,
    userId: user.id,
    userType: 'authenticated',
    sessionCount: user.sessionCount
  });
} else {
  woopra.identify({
    userType: 'anonymous',
    sessionCount: 1
  });
}

// Identify based on subscription status
const subscriptionStatus = user.subscription.active ? 'active' : 'inactive';
woopra.identify({
  subscriptionStatus: subscriptionStatus,
  subscriptionTier: user.subscription.tier,
  billingCycle: user.subscription.billingCycle
});

Calculated Properties

Include computed values:

// Calculate engagement metrics
const daysSinceSignup = Math.floor((Date.now() - user.signupDate) / (1000 * 60 * 60 * 24));
const avgSessionDuration = user.totalSessionTime / user.sessionCount;

woopra.identify({
  daysSinceSignup: daysSinceSignup,
  averageSessionDuration: Math.round(avgSessionDuration),
  engagementScore: calculateEngagementScore(user),
  lifetimeValue: user.totalRevenue,
  churnRisk: user.lastLoginDays > 30 ? 'high' : 'low'
});

Best Practices

Identify Early and Often

Identify users as soon as possible:

// On page load (if user is logged in)
document.addEventListener('DOMContentLoaded', function() {
  if (currentUser) {
    woopra.identify({
      email: currentUser.email,
      name: currentUser.name,
      id: currentUser.id
    });
    woopra.track();
  }
});

// After login
function handleLogin(userData) {
  woopra.identify({
    email: userData.email,
    name: userData.name,
    id: userData.id,
    loginAt: Date.now()
  });

  woopra.track('login');
}

Keep Properties Updated

Update properties when they change:

// User updates profile
function updateProfile(newData) {
  // Update in your database
  saveUserProfile(newData);

  // Update in Woopra
  woopra.identify({
    name: newData.name,
    phone: newData.phone,
    profileUpdatedAt: Date.now()
  });

  woopra.track('profile_updated', {
    fields_changed: Object.keys(newData).join(',')
  });
}

Use Consistent Identifiers

Always use the same identifier for a user:

// Good - consistent ID across sessions and devices
woopra.identify({
  id: user.id,           // Your internal user ID
  email: user.email      // Backup identifier
});

// Avoid - different IDs in different contexts
// Session 1: woopra.identify({ id: user.sessionId });
// Session 2: woopra.identify({ id: user.email });

Common Use Cases

E-commerce User Data

woopra.identify({
  email: 'customer@example.com',
  customerId: 'CUST_12345',

  // Purchase history
  totalOrders: 23,
  totalSpent: 2847.50,
  averageOrderValue: 123.80,
  lastPurchaseDate: '2024-01-10',

  // Preferences
  favoriteCategory: 'Electronics',
  newsletterSubscribed: true,
  smsOptIn: false,

  // Loyalty
  loyaltyTier: 'Gold',
  loyaltyPoints: 4500,
  referralCount: 3
});

SaaS User Data

woopra.identify({
  email: 'user@startup.com',
  userId: 'user_789',

  // Subscription
  plan: 'professional',
  mrr: 99,
  billingCycle: 'monthly',
  nextBillingDate: '2024-02-01',
  trialUser: false,

  // Usage metrics
  projectsCreated: 12,
  apiCallsThisMonth: 45000,
  storageUsed: 8.5,  // GB
  teamSize: 8,
  lastActiveDate: '2024-01-15',

  // Feature adoption
  featuresUsed: 'api,export,integrations,webhooks',
  advancedFeaturesEnabled: true,
  integrationsConnected: 4
});

Content Platform User Data

woopra.identify({
  email: 'reader@example.com',
  userId: 'user_456',

  // Engagement
  articlesRead: 127,
  commentsPosted: 15,
  articlesBookmarked: 23,
  shareCount: 8,
  lastVisitDate: '2024-01-14',

  // Preferences
  topicsFollowed: 'technology,business,science',
  authorsFollowed: 'author_1,author_5,author_12',
  emailFrequency: 'weekly',

  // Subscription
  subscriptionType: 'premium',
  memberSince: '2023-03-15',
  autoRenewal: true
});

Server-Side Identification

Identify Users from Backend

Send user properties from your server:

import requests

def identify_woopra_user(user_data):
    """Identify user in Woopra from server-side"""

    url = "https://www.woopra.com/track/identify/"

    # Build visitor properties (prefixed with cv_)
    params = {
        'host': 'example.com',
        'cv_email': user_data['email'],
        'cv_name': user_data['name'],
        'cv_id': user_data['id'],
        'cv_plan': user_data['plan'],
        'cv_mrr': user_data['mrr'],
        'cv_signupDate': user_data['signup_date']
    }

    response = requests.post(url, data=params)
    return response.status_code == 200

# Usage
identify_woopra_user({
    'email': 'user@example.com',
    'name': 'John Doe',
    'id': 'user_12345',
    'plan': 'enterprise',
    'mrr': 299,
    'signup_date': '2024-01-15'
})

Sync User Data Periodically

Keep Woopra updated with latest user data:

def sync_user_to_woopra(user_id):
    """Sync user data from database to Woopra"""

    # Get latest user data from database
    user = get_user_from_db(user_id)

    # Calculate metrics
    lifetime_value = calculate_lifetime_value(user)
    engagement_score = calculate_engagement_score(user)

    # Send to Woopra
    identify_woopra_user({
        'email': user.email,
        'id': user.id,
        'name': user.name,
        'plan': user.subscription.plan,
        'mrr': user.subscription.mrr,
        'lifetime_value': lifetime_value,
        'engagement_score': engagement_score,
        'last_synced': datetime.now().isoformat()
    })

Troubleshooting

Properties Not Appearing

If properties aren't showing in Woopra:

// Enable debug mode to see what's being sent
woopra.config({ debug: true });

woopra.identify({
  email: 'test@example.com',
  testProperty: 'value'
});

// Check browser console for debug output

Property Values Not Updating

Ensure you're calling identify() with updated values:

// This updates the property
woopra.identify({ plan: 'enterprise' });

// Track an event to ensure data is sent
woopra.track('plan_upgraded');

Reserved Property Names

Avoid using Woopra's reserved property names:

// Avoid these property names
// - cookie
// - host
// - timeout
// - idle_timeout

// Use custom names instead
woopra.identify({
  customCookie: 'value',  // Instead of 'cookie'
  hostName: 'example',    // Instead of 'host'
});