releva_sdk 0.0.29
releva_sdk: ^0.0.29 copied to clipboard
Releva.ai SDK for Flutter apps
This package offers an easy way to integrate Releva's AI-powered e-commerce personalization platform into your mobile app built on Flutter.
Features #
๐ฏ E-commerce Personalization #
- Product Recommendations: AI-powered product suggestions with real-time personalization
- Dynamic Content: Personalized banners and content blocks based on user behavior
- Advanced Filtering: Complex product filtering with nested AND/OR logic, price ranges, custom fields
- Smart Search: Search tracking with result optimization and recommendation integration
๐ฑ Mobile Tracking & Analytics #
- Automatic Screen Tracking: NavigatorObserver for seamless route/screen tracking
- E-commerce Events: Product views, cart changes, checkout tracking, search analytics
- Custom Events: Flexible event system for business-specific tracking needs
- Real-Time Analytics: ClickHouse integration for comprehensive engagement insights
๐ฌ In-App Messaging #
- Hybrid Messaging: HTML campaigns (admin-created) + native Flutter inbox messages (structured data)
- Local Inbox: Offline-first message storage with Hive database (100 message limit)
- Inbox Messages: Native Flutter widgets with title, description, and CTA buttons
- Character Limits: Built-in validation (Title: 45, Short Description: 40, Description: 350, CTA: 10 chars)
- Message Lifecycle: Automatic expiration, cleanup, and state management
- Multiple Display Types: Popup modals, banner notifications, fullscreen overlays
๐ Push Notifications #
- Firebase Integration: FCM push notification engagement tracking with offline support
- Engagement Analytics: Delivered, opened, dismissed tracking to ClickHouse
- Cross-Platform: Android, iOS, Huawei device support
โ๏ธ Flexible Configuration #
- Modular Setup: Enable only needed features (tracking-only, messaging-only, full-featured)
- Use Case Optimized: Perfect for apps with existing analytics or standalone messaging needs
- Production Ready: Robust error handling, offline support, automatic retries
Getting started #
Installation #
Add the package to your pubspec.yaml:
dependencies:
releva_sdk: ^0.0.24
Generate Code (Required for In-App Messaging) #
flutter packages pub run build_runner build
Usage #
Quick Start #
import 'package:releva_sdk/client.dart';
import 'package:releva_sdk/types/releva_config.dart';
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late RelevaClient client;
@override
void initState() {
super.initState();
// Initialize with configuration
client = RelevaClient(
'your-realm', // Usually empty string ''
'your-access-token', // Provided by Releva
config: RelevaConfig.full(), // or .messagingOnly(), .trackingOnly()
);
_initializeSDK();
}
Future<void> _initializeSDK() async {
// Set required user info
await client.setDeviceId('unique-device-id');
await client.setProfileId('user-profile-id');
// Enable features
await client.enablePushEngagementTracking();
await client.enableInAppMessaging(context);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
// Add automatic screen tracking
navigatorObservers: [client.createScreenTrackingService()],
home: HomeScreen(client: client),
);
}
}
E-commerce Tracking #
// Product view with recommendations
final response = await client.trackProductView(
screenToken: 'product_detail',
productId: 'product-123',
categories: ['electronics', 'phones'],
);
// Handle personalized recommendations
if (response.hasRecommenders) {
for (final recommender in response.recommenders) {
print('${recommender.name}: ${recommender.response.length} products');
}
}
// Search with advanced filtering
final searchResponse = await client.trackSearchView(
screenToken: 'search_results',
query: 'red running shoes',
filter: NestedFilter.and([
SimpleFilter.priceRange(minPrice: 50, maxPrice: 200),
SimpleFilter.brand(brand: 'Nike'),
SimpleFilter.color(color: 'red'),
]),
);
// Checkout success tracking
await client.trackCheckoutSuccess(
screenToken: 'checkout_success',
orderedCart: Cart.active([...]),
userEmail: 'user@example.com',
);
In-App Messaging #
// Create inbox messages with structured data
final inboxMessage = InAppMessage(
id: 'inbox-msg-1',
type: MessageType.nativeRealtime,
content: '',
createdAt: DateTime.now(),
title: 'Special Offer', // max 45 chars
shortDescription: 'Limited time', // max 40 chars
description: 'Get 20% off your next purchase when you spend over $100. Valid until midnight tonight!', // max 350 chars
cta: 'Shop Now', // max 10 chars
imageUrl: 'https://example.com/offer.jpg',
);
// SDK automatically validates character limits
try {
await client.storeInboxMessage(inboxMessage);
} catch (ArgumentError e) {
// Handle validation errors (e.g., title too long)
}
// Native real-time notifications (for popups)
await client.sendNativeMessage(
title: 'Special Offer!',
subtitle: '50% off your next purchase',
imageUrl: 'https://example.com/offer.jpg',
displayType: MessageDisplayType.banner,
);
// Inbox with unread count
FutureBuilder<List<InAppMessage>>(
future: client.getUnreadMessages(),
builder: (context, snapshot) {
final unreadCount = snapshot.data?.length ?? 0;
return IconButton(
icon: Badge(
label: Text('$unreadCount'),
child: Icon(Icons.inbox),
),
onPressed: () => Navigator.push(context,
MaterialPageRoute(builder: (_) => client.buildInboxScreen())),
);
},
);
Configuration Options #
// Full e-commerce functionality (default)
RelevaClient('realm', 'token', config: RelevaConfig.full());
// Only messaging (when events come from other sources)
RelevaClient('realm', 'token', config: RelevaConfig.messagingOnly());
// Only tracking (analytics without messaging)
RelevaClient('realm', 'token', config: RelevaConfig.trackingOnly());
// Custom configuration
RelevaClient('realm', 'token', config: RelevaConfig(
enableTracking: true,
enableScreenTracking: false, // Manual tracking only
enableInAppMessaging: true,
enablePushNotifications: false,
));
Advanced Filtering #
// Complex product filtering (exactly like web SDK)
final complexFilter = NestedFilter.and([
// Price range
SimpleFilter.priceRange(minPrice: 10, maxPrice: 100),
// Multiple brands
NestedFilter.or([
SimpleFilter.brand(brand: 'Nike'),
SimpleFilter.brand(brand: 'Adidas'),
]),
// Size and color combinations
NestedFilter.and([
NestedFilter.or([
SimpleFilter.size(size: '42'),
SimpleFilter.size(size: '43'),
]),
SimpleFilter.color(color: 'red'),
]),
]);
What's New in v0.0.24 #
๐ Complete Web SDK Parity #
- Automatic Screen Tracking:
NavigatorObserverintegration for seamless route tracking - Standard E-commerce Events:
trackProductView(),trackSearchView(),trackCheckoutSuccess() - Advanced Filter System: Full nested AND/OR logic with all operators (
eq,lt,gt,lte,gte, composite operators) - Product Recommendations: Real-time AI-powered recommendations with
RelevaResponsehandling
๐ Hybrid In-App Messaging System #
- Dual Message Types: HTML campaigns (admin-created) + native Flutter inbox messages (structured data)
- Inbox Messages: Native Flutter widgets with title, short description, description, and CTA buttons
- Character Validation: Built-in limits (Title: 45, Short Description: 40, Description: 350, CTA: 10 chars)
- Local Inbox Storage: Hive-based offline storage with 100 message limit and automatic cleanup
- Message Lifecycle Management: Automatic expiration, state tracking, and analytics integration
- Multiple Display Modes: Popup modals, banner notifications, fullscreen overlays
๐ Flexible Configuration System #
- Modular Setup:
RelevaConfig.full(),RelevaConfig.messagingOnly(),RelevaConfig.trackingOnly() - Use Case Optimization: Perfect for apps with existing analytics or standalone messaging needs
- Feature Toggles: Granular control over tracking, messaging, push notifications, and analytics
๐ Advanced Analytics Integration #
- ClickHouse Pipeline: Comprehensive event tracking with batching and offline support
- Message Analytics: Track shown, clicked, dismissed, expired events with attribution
- Performance Optimized: Intelligent batching, automatic retries, memory management
๐ Enhanced Response Handling #
- Structured Responses:
RelevaResponsewith recommenders and banners - Product Attribution:
mergeContextfor proper click attribution and analytics - Template System: Reusable recommendation widgets and banner handling
๐ Developer Experience #
- Code Generation: Automatic Hive adapters for message storage
- Error Handling: Robust error handling with graceful degradation
- Documentation: Comprehensive guides, API reference, and integration examples
Framework Architecture #
Core Components Added #
lib/
โโโ services/
โ โโโ in_app_messaging_service.dart # Main messaging orchestrator
โ โโโ message_analytics_service.dart # ClickHouse event pipeline
โ โโโ message_storage_service.dart # Hive local storage
โ โโโ message_display_manager.dart # UI presentation layer
โ โโโ message_lifecycle_manager.dart # Expiration & cleanup
โ โโโ screen_tracking_service.dart # NavigatorObserver integration
โโโ types/
โ โโโ message/ # Message models with Hive adapters
โ โโโ tracking/ # Standard tracking events
โ โโโ response/ # API response models
โ โโโ filter/ # Advanced filtering system
โ โโโ releva_config.dart # Configuration management
โโโ widgets/
โโโ html_message_widget.dart # HTML campaign rendering
โโโ native_message_widget.dart # Native Flutter widgets
โโโ inbox_message_widget.dart # Inbox message widget
โโโ inbox_screen.dart # Message inbox UI
Integration Points #
- NavigatorObserver: Automatic screen tracking with route name formatting
- Hive Database: Type-safe message storage with automatic code generation
- ClickHouse Analytics: Batched event pipeline with offline support
- Flutter Widget System: Native message rendering with Material Design
- HTML Rendering:
flutter_widget_from_htmlfor campaign fidelity
Testing #
The SDK includes comprehensive test coverage (90%+) with realistic scenarios across all components. Tests use Hive memory implementation for fast, isolated testing and MockClient for HTTP requests.
Prepare Local Environment for Running Tests #
1. Install Flutter SDK (Required)
This is a Flutter package that requires the Flutter SDK to run tests. If you don't have Flutter installed:
# macOS (using Homebrew)
brew install flutter
# Or download from official site
# https://docs.flutter.dev/get-started/install
# Verify installation
flutter --version
flutter doctor
# Fix any issues reported by flutter doctor
flutter doctor --android-licenses # Accept Android licenses if needed
2. Clone and Navigate to SDK Directory
# If you haven't already
git clone <repository-url>
cd releva_sdk
# Or navigate to existing directory
cd /path/to/releva_sdk
3. Install Dependencies
# Install all Flutter dependencies
flutter pub get
# Verify pubspec.yaml dependencies are installed:
# - hive: ^2.2.3 & hive_flutter: ^1.1.0 (message storage)
# - flutter_widget_from_html: ^0.15.2 (HTML rendering)
# - hive_generator: ^2.0.1 & build_runner: ^2.4.7 (code generation)
4. Verify Required Generated Files (Already Included)
The following Hive adapter files are required and already included:
# Check these files exist:
ls -la lib/types/message/*.g.dart
# Should show:
# lib/types/message/in_app_message.g.dart
# lib/types/message/message_state.g.dart
# lib/types/message/message_type.g.dart
If missing, regenerate them:
flutter packages pub run build_runner build --delete-conflicting-outputs
5. Verify Test Environment
# Check Flutter can run tests
flutter test --help
# Verify test files exist
ls -la test/
# Should show 10 test files:
# client_test.dart, screen_tracking_test.dart, message_storage_test.dart
# message_analytics_test.dart, filter_test.dart, response_models_test.dart
# configuration_test.dart, widget_test.dart, in_app_messaging_service_test.dart
# inbox_message_test.dart
6. Environment Troubleshooting
Common Issues and Solutions:
# Issue: "flutter: command not found"
# Solution: Add Flutter to PATH
export PATH="$PATH:/path/to/flutter/bin"
# Add to ~/.bashrc or ~/.zshrc for permanent fix
# Issue: "packages get failed"
# Solution: Clear cache and retry
flutter clean
flutter pub cache repair
flutter pub get
# Issue: "build_runner conflicts"
# Solution: Clean and regenerate
flutter packages pub run build_runner clean
flutter packages pub run build_runner build --delete-conflicting-outputs
# Issue: "test execution failed"
# Solution: Check Flutter doctor and dependencies
flutter doctor -v
flutter pub deps
7. IDE Setup (Optional but Recommended)
VS Code:
# Install Flutter extension
code --install-extension Dart-Code.flutter
# Open project
code .
Android Studio:
- Install Flutter plugin
- Import project
- Configure Flutter SDK path in settings
8. Ready to Run Tests
Once environment is set up, you can run:
# Quick verification
flutter test test/configuration_test.dart
# Full test suite
flutter test --coverage
Test Files Overview #
| Test File | Coverage | Description |
|---|---|---|
test/client_test.dart |
Core SDK client | Updated with all new tracking methods, configuration testing, response handling |
test/screen_tracking_test.dart |
Screen tracking | NavigatorObserver integration, route formatting, automatic tracking |
test/message_storage_test.dart |
Local storage | Hive memory implementation, CRUD operations, message lifecycle |
test/message_analytics_test.dart |
Analytics pipeline | ClickHouse events, batching, offline support, error handling |
test/filter_test.dart |
Advanced filtering | Nested AND/OR logic, all operators, real-world e-commerce scenarios |
test/response_models_test.dart |
API responses | Serialization, product recommendations, banners, templates |
test/configuration_test.dart |
SDK configuration | All RelevaConfig combinations, use cases, feature toggles |
test/widget_test.dart |
UI components | HTML/native message widgets, user interactions, lifecycle events |
test/in_app_messaging_service_test.dart |
Messaging service | End-to-end messaging flow, analytics integration, storage management |
test/inbox_message_test.dart |
Inbox messages | Character limit validation, structured data, native Flutter widgets |
Running Tests #
Prerequisites
The tests require Hive adapters for message storage. These are already included in the SDK, but if you need to regenerate them:
# Install dependencies
flutter pub get
# Generate Hive adapters (optional - already included)
flutter packages pub run build_runner build
# Clean previous builds if needed (if regenerating)
flutter packages pub run build_runner build --delete-conflicting-outputs
Required Generated Files (Already Included):
lib/types/message/in_app_message.g.dart- InAppMessage Hive adapterlib/types/message/message_state.g.dart- MessageState enum adapterlib/types/message/message_type.g.dart- MessageType enum adapter
These files enable type-safe binary serialization for the in-app messaging system and are required for the tests to run properly.
Run All Tests
# Run all tests with coverage
flutter test --coverage
# Generate coverage report (optional)
# Requires lcov installation: brew install lcov (macOS) or apt-get install lcov (Ubuntu)
genhtml coverage/lcov.info -o coverage/html
open coverage/html/index.html # View coverage report
Run Specific Test Categories
# Core client functionality
flutter test test/client_test.dart
# In-app messaging system
flutter test test/message_storage_test.dart test/message_analytics_test.dart test/in_app_messaging_service_test.dart
# UI components and widgets
flutter test test/widget_test.dart
# Advanced filtering system
flutter test test/filter_test.dart
# Configuration and responses
flutter test test/configuration_test.dart test/response_models_test.dart
# Screen tracking
flutter test test/screen_tracking_test.dart
Run Individual Test Files
# Test specific functionality
flutter test test/message_storage_test.dart -v # Verbose output
flutter test test/filter_test.dart --reporter=json # JSON output
Test Features #
๐งช Realistic Test Scenarios
- E-commerce workflows: Product views, search, checkout with actual product data
- Real-world filtering: Complex nested filters matching production use cases
- Message lifecycle: Complete flow from creation to expiration and cleanup
- Configuration combinations: All RelevaConfig variants and edge cases
๐ Performance Optimized
- Hive memory storage: Lightning-fast tests without disk I/O
- MockClient HTTP: No network calls, predictable responses
- Isolated test environment: Each test starts with clean state
- Parallel execution: Tests can run concurrently
๐ง Developer Friendly
- Descriptive test names: Clear "Happy case" and "Edge case" labeling
- Comprehensive assertions: Full object validation and state checking
- Error scenario coverage: Network failures, malformed data, missing fields
- Integration testing: Cross-service functionality verification
๐ Coverage Areas
Core SDK (client_test.dart)
- All tracking methods (
trackProductView,trackSearchView,trackCheckoutSuccess) - Configuration-driven behavior (
RelevaConfig.full(),.messagingOnly(),.trackingOnly()) - Response handling (
RelevaResponsewith recommenders and banners) - Error handling (network failures, malformed responses)
In-App Messaging (message_*_test.dart)
- Message storage with Hive (CRUD operations, expiration, limits)
- Analytics pipeline (event batching, ClickHouse integration)
- Service orchestration (message lifecycle, display management)
- Widget rendering (HTML campaigns, native notifications)
Advanced Features (filter_test.dart, response_models_test.dart)
- Complex filtering (
NestedFilter.and()/.or(), all operators) - Product recommendations (serialization, attribution context)
- Template system (reusable components, dynamic content)
Configuration & Setup (configuration_test.dart, screen_tracking_test.dart)
- All configuration combinations and validation
- NavigatorObserver integration and route tracking
- Feature toggle behavior and edge cases
Test Development Guidelines #
When adding new tests, follow these patterns:
// Use descriptive test names with clear categorization
test('Happy case - basic functionality works as expected', () async {
// Test implementation
});
test('Edge case - handles malformed input gracefully', () async {
// Error scenario testing
});
// Use realistic test data
final productData = {
'id': 'nike-air-max-270',
'name': 'Nike Air Max 270',
'price': 150.0,
'categories': ['shoes', 'athletic'],
'brand': 'Nike',
};
// Verify complete state changes
expect(updatedMessage.state, equals(MessageState.clicked));
expect(updatedMessage.clickedAt, isNotNull);
expect(updatedMessage.readAt, isNull); // Ensure side effects
Continuous Integration #
For CI/CD pipelines, add this to your workflow:
# .github/workflows/test.yml
- name: Run tests with coverage
run: |
flutter pub get
flutter packages pub run build_runner build
flutter test --coverage
- name: Upload coverage
uses: codecov/codecov-action@v1
with:
file: coverage/lcov.info
Documentation #
- Complete Developer Guide - Comprehensive integration guide
- In-App Messaging Guide - Detailed messaging implementation
- API Reference - Complete API documentation
In-App Messaging Flow Architecture #
Overview #
The in-app messaging system uses a complete end-to-end flow from campaign configuration to message display:
Campaign Flow โ In-App Job โ Redis Storage โ SDK Polling โ Message Display
Backend Flow (Magellan API) #
-
Campaign Configuration
- Campaigns are created with flows containing nodes and edges
- In-app notification nodes are configured in the flow
- Campaigns can be triggered manually or via webhooks
-
Job Processing (
jobs/channels/in-app-notifications.js)- Campaign flow triggers in-app notification jobs
- Jobs process user segments and apply personalization
- Supports optimal timing and quiet hours configuration
-
Message Storage (
helpers/messaging/in-app-notification-helper.js)- Messages are stored in Redis with keys:
- Individual message:
in_app_notification:${userId}:${notificationId} - User queue:
in_app_notifications:${userId}
- Individual message:
- Messages have 7-day TTL for individual storage, 30-day TTL for queue
- Messages are stored in Redis with keys:
-
API Endpoints (
api/v0/messages.js)GET /api/v0/messages/fetch- Retrieve pending messagesPOST /api/v0/messages/:messageId/read- Mark message as readPOST /api/v0/messages/:messageId/track- Track message events
SDK Flow (Flutter) #
-
Polling Service (
services/in_app_messaging_service.dart)- Polls
/api/v0/messages/fetchevery 5 minutes - Fetches messages based on device_id or profile_id
- Processes and validates incoming messages
- Polls
-
Local Storage (
services/message_storage_service.dart)- Uses Hive for offline-first storage
- Maintains up to 100 messages locally
- Automatic cleanup of expired messages
-
Message Display (
services/message_display_manager.dart)- Supports multiple display types: popup, banner, fullscreen
- HTML rendering for campaign messages
- Native Flutter widgets for inbox messages
-
Analytics Tracking (
services/message_analytics_service.dart)- Tracks events: shown, clicked, dismissed, expired
- Batches events for efficient delivery
- Sends to
/api/v0/analytics/message-events
Message Types #
-
Campaign Messages (HTML)
- Created in admin dashboard
- Delivered as HTML content
- Supports rich formatting and custom styling
-
Native Messages
- Created programmatically via SDK
- Structured data with Flutter widgets
- Used for real-time notifications
-
Inbox Messages
- Stored locally with structured fields
- Character limits enforced:
- Title: 45 characters
- Short Description: 40 characters
- Description: 350 characters
- CTA: 10 characters
Key Features #
- Personalization: Handlebars templates with user attributes
- Targeting: Segment-based delivery with custom attributes
- Scheduling: Optimal time delivery and quiet hours
- Tracking: Complete event lifecycle tracking
- Offline Support: Local storage with sync on connectivity
Additional information #
For additional information please visit https://releva.ai and/or reach out to tech-support[@]releva.ai