reddit_pixel 1.0.0 copy "reddit_pixel: ^1.0.0" to clipboard
reddit_pixel: ^1.0.0 copied to clipboard

A privacy-centric, backend-agnostic Flutter library for Reddit Conversions API (CAPI) v3. Supports direct and proxy transport modes with offline-first persistence.

example/lib/main.dart

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:reddit_pixel/reddit_pixel.dart';

/// Example app demonstrating the reddit_pixel package.
///
/// This example shows:
/// 1. Initializing the library in privacy mode (no tracking)
/// 2. Tracking various conversion events
/// 3. How to implement a custom identity provider (commented)
void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Initialize RedditPixel with proxy mode (recommended for production)
  // Replace with your actual pixel ID and proxy URL
  await RedditPixel.initialize(
    pixelId: 'YOUR_PIXEL_ID',
    proxyUrl: 'https://your-server.com/api/reddit-events',
    testMode: true, // Enable test mode during development
    debug: true, // Enable debug logging
    // identityProvider: AppIdentityProvider(), // Uncomment to enable IDFA/AAID
  );

  runApp(const RedditPixelExampleApp());
}

/// Main application widget for the Reddit Pixel example.
class RedditPixelExampleApp extends StatelessWidget {
  /// Creates the example app.
  const RedditPixelExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Reddit Pixel Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepOrange),
        useMaterial3: true,
      ),
      home: const ExampleHomePage(),
    );
  }
}

/// Home page with buttons to trigger different events.
class ExampleHomePage extends StatefulWidget {
  /// Creates the home page.
  const ExampleHomePage({super.key});

  @override
  State<ExampleHomePage> createState() => _ExampleHomePageState();
}

class _ExampleHomePageState extends State<ExampleHomePage> {
  String _status = 'Ready to track events';
  int _pendingCount = 0;

  @override
  void initState() {
    super.initState();
    unawaited(_updatePendingCount());
  }

  Future<void> _updatePendingCount() async {
    final count = await RedditPixel.instance.pendingEventCount;
    setState(() {
      _pendingCount = count;
    });
  }

  Future<void> _trackEvent(
    String eventName,
    Future<void> Function() track,
  ) async {
    setState(() {
      _status = 'Tracking $eventName...';
    });

    try {
      await track();
      setState(() {
        _status = '$eventName tracked successfully!';
      });
    } on Exception catch (e) {
      setState(() {
        _status = 'Error tracking $eventName: $e';
      });
    }

    await _updatePendingCount();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('Reddit Pixel Example'),
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            // Status card
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Status',
                      style: Theme.of(context).textTheme.titleMedium,
                    ),
                    const SizedBox(height: 8),
                    Text(_status),
                    const SizedBox(height: 8),
                    Text('Pending events: $_pendingCount'),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 24),

            // Event tracking buttons
            Text(
              'Standard Events',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const SizedBox(height: 16),

            _EventButton(
              label: 'Track Purchase',
              icon: Icons.shopping_cart,
              onPressed: () => _trackEvent(
                'Purchase',
                () => RedditPixel.instance.trackPurchase(
                  value: 99.99,
                  currency: 'USD',
                  itemCount: 2,
                  userData: const RedditUserData(
                    email: 'customer@example.com',
                    externalId: 'user-123',
                  ),
                ),
              ),
            ),

            _EventButton(
              label: 'Track Sign Up',
              icon: Icons.person_add,
              onPressed: () => _trackEvent(
                'SignUp',
                () => RedditPixel.instance.trackSignUp(
                  userData: const RedditUserData(
                    email: 'newuser@example.com',
                  ),
                ),
              ),
            ),

            _EventButton(
              label: 'Track Lead',
              icon: Icons.contact_mail,
              onPressed: () => _trackEvent(
                'Lead',
                () => RedditPixel.instance.trackLead(
                  userData: const RedditUserData(
                    email: 'lead@example.com',
                  ),
                  customData: const {'lead_source': 'contact_form'},
                ),
              ),
            ),

            _EventButton(
              label: 'Track Add to Cart',
              icon: Icons.add_shopping_cart,
              onPressed: () => _trackEvent(
                'AddToCart',
                () => RedditPixel.instance.trackAddToCart(
                  value: 49.99,
                  currency: 'USD',
                  itemCount: 1,
                ),
              ),
            ),

            _EventButton(
              label: 'Track Add to Wishlist',
              icon: Icons.favorite,
              onPressed: () => _trackEvent(
                'AddToWishlist',
                () => RedditPixel.instance.trackAddToWishlist(
                  value: 199.99,
                  currency: 'USD',
                ),
              ),
            ),

            _EventButton(
              label: 'Track Search',
              icon: Icons.search,
              onPressed: () => _trackEvent(
                'Search',
                () => RedditPixel.instance.trackSearch(
                  searchString: 'wireless headphones',
                ),
              ),
            ),

            _EventButton(
              label: 'Track View Content',
              icon: Icons.visibility,
              onPressed: () => _trackEvent(
                'ViewContent',
                () => RedditPixel.instance.trackViewContent(
                  contentId: 'product-456',
                  contentName: 'Premium Headphones',
                ),
              ),
            ),

            _EventButton(
              label: 'Track Page Visit',
              icon: Icons.web,
              onPressed: () => _trackEvent(
                'PageVisit',
                () => RedditPixel.instance.trackPageVisit(
                  pageUrl: '/checkout',
                ),
              ),
            ),

            const SizedBox(height: 24),
            Text(
              'Custom Events',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const SizedBox(height: 16),

            _EventButton(
              label: 'Track Custom Event',
              icon: Icons.code,
              onPressed: () => _trackEvent(
                'Custom',
                () => RedditPixel.instance.trackCustom(
                  'VideoWatched',
                  customData: {
                    'video_id': 'vid-789',
                    'duration_seconds': 120,
                  },
                ),
              ),
            ),

            const SizedBox(height: 24),
            Text(
              'Queue Management',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const SizedBox(height: 16),

            _EventButton(
              label: 'Flush Queue',
              icon: Icons.sync,
              onPressed: () async {
                setState(() {
                  _status = 'Flushing queue...';
                });
                await RedditPixel.instance.flush();
                await _updatePendingCount();
                setState(() {
                  _status = 'Queue flushed!';
                });
              },
            ),
          ],
        ),
      ),
    );
  }
}

class _EventButton extends StatelessWidget {
  const _EventButton({
    required this.label,
    required this.icon,
    required this.onPressed,
  });

  final String label;
  final IconData icon;
  final VoidCallback onPressed;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 8),
      child: ElevatedButton.icon(
        onPressed: onPressed,
        icon: Icon(icon),
        label: Text(label),
        style: ElevatedButton.styleFrom(
          padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
          alignment: Alignment.centerLeft,
        ),
      ),
    );
  }
}

// =============================================================================
// OPTIONAL: Custom Identity Provider Implementation
// =============================================================================
// Uncomment the code below to enable IDFA/AAID tracking.
// You'll need to add these dependencies to your pubspec.yaml:
//   - advertising_id: ^2.3.0
//   - app_tracking_transparency: ^2.0.3
//
// Then uncomment the identityProvider parameter in main().
// =============================================================================

/*
import 'package:advertising_id/advertising_id.dart';
import 'package:app_tracking_transparency/app_tracking_transparency.dart';
import 'dart:io' show Platform;

/// Custom identity provider that retrieves IDFA/AAID.
///
/// This implementation:
/// 1. Checks App Tracking Transparency status on iOS
/// 2. Retrieves the appropriate advertising ID for the platform
class AppIdentityProvider implements RedditIdentityProvider {
  @override
  Future<String?> getAdvertisingId() async {
    try {
      // On iOS, first check ATT status
      if (Platform.isIOS) {
        final status =
            await AppTrackingTransparency.trackingAuthorizationStatus;
        if (status != TrackingStatus.authorized) {
          return null;
        }
      }

      // Get the advertising ID
      return await AdvertisingId.id(true);
    } catch (e) {
      // Failed to get ID - return null
      return null;
    }
  }

  @override
  Future<bool> isTrackingEnabled() async {
    try {
      if (Platform.isIOS) {
        final status =
            await AppTrackingTransparency.trackingAuthorizationStatus;
        return status == TrackingStatus.authorized;
      }

      // On Android, check if the ID is available
      final id = await AdvertisingId.id(true);
      return id != null && id.isNotEmpty;
    } catch (e) {
      return false;
    }
  }
}
*/
1
likes
150
points
48
downloads

Documentation

API reference

Publisher

verified publishertpn-labs.com

Weekly Downloads

A privacy-centric, backend-agnostic Flutter library for Reddit Conversions API (CAPI) v3. Supports direct and proxy transport modes with offline-first persistence.

Repository (GitHub)
View/report issues

License

BSD-3-Clause (license)

Dependencies

connectivity_plus, crypto, dio, flutter, hive, hive_flutter, meta, uuid

More

Packages that depend on reddit_pixel