Skip to main content

sequenzy_flutter 0.1.0 copy "sequenzy_flutter: ^0.1.0" to clipboard
sequenzy_flutter: ^0.1.0 copied to clipboard

Sequenzy for Flutter apps. Identify contacts, track events, register push tokens and show in-app messages and content cards.

example/lib/main.dart

import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:sequenzy_flutter/sequenzy_flutter.dart';

// Configure with --dart-define, e.g.
//   flutter run --dart-define=SEQUENZY_PUBLIC_KEY=seq_pk_... \
//     --dart-define=SEQUENZY_COMPANY_ID=... \
//     --dart-define=IDENTITY_TOKEN_URL=https://your-backend/identity-token
const publicKey = String.fromEnvironment('SEQUENZY_PUBLIC_KEY', defaultValue: 'seq_pk_replace_me');
const companyId = String.fromEnvironment('SEQUENZY_COMPANY_ID', defaultValue: 'replace-me');
const apiBaseUrl = String.fromEnvironment('SEQUENZY_API_URL', defaultValue: 'https://api.sequenzy.com');
// Your backend: POST { email } returns { identityToken } minted with your
// secret API key. Never ship the secret key in the app.
// A published Sequenzy form: its lists and opt-in settings apply.
const newsletterFormId = String.fromEnvironment('SEQUENZY_NEWSLETTER_FORM_ID', defaultValue: 'replace-me');
const identityTokenUrl = String.fromEnvironment('IDENTITY_TOKEN_URL', defaultValue: 'http://localhost:8787/identity-token');

String get platform => kIsWeb
    ? 'web'
    : defaultTargetPlatform == TargetPlatform.iOS
        ? 'ios'
        : 'android';

void main() {
  Sequenzy.configure(SequenzyConfig(
    publicKey: publicKey,
    companyId: companyId,
    appId: 'com.sequenzy.example',
    platform: platform,
    apiBaseUrl: apiBaseUrl,
    logLevel: SequenzyLogLevel.debug,
    identityTokenProvider: (email) async {
      final response = await http.post(
        Uri.parse(identityTokenUrl),
        headers: {'content-type': 'application/json'},
        body: jsonEncode({'email': email}),
      );
      return (jsonDecode(response.body) as Map<String, dynamic>)['identityToken'] as String;
    },
  ));
  // With firebase_messaging: use getToken() on Android and getAPNSToken() on iOS.
  // and Sequenzy.handleNotificationOpened(message.data) from onMessageOpenedApp.
  runApp(const ExampleApp());
}

class ExampleApp extends StatelessWidget {
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sequenzy example',
      theme: ThemeData(colorSchemeSeed: const Color(0xFF0F172A), useMaterial3: true),
      builder: (context, child) => SequenzyInAppHost(child: child!),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final _email = TextEditingController();
  final _cards = InAppCardsController();
  String? _signedIn;
  String _status = 'Not signed in';

  @override
  void initState() {
    super.initState();
    Sequenzy.client?.email().then((email) {
      if (email != null && mounted) {
        setState(() => _signedIn = email);
        _cards.refresh();
      }
    });
    _cards.addListener(() {
      for (final card in _cards.cards) {
        if (!card.isRead) _cards.markRead(card);
      }
    });
  }

  @override
  void dispose() {
    _cards.dispose();
    _email.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFFF8FAFC),
      body: SafeArea(
        child: Center(
          child: ConstrainedBox(
            constraints: const BoxConstraints(maxWidth: 520),
            child: ListView(padding: const EdgeInsets.all(24), children: [
              const Text('Sequenzy example', style: TextStyle(fontSize: 26, fontWeight: FontWeight.w700)),
              const SizedBox(height: 12),
              if (_signedIn == null) ...[
                TextField(
                  controller: _email,
                  keyboardType: TextInputType.emailAddress,
                  decoration: const InputDecoration(labelText: 'Email', border: OutlineInputBorder()),
                ),
                const SizedBox(height: 12),
                FilledButton(
                  onPressed: () async {
                    final identified = await Sequenzy.identify(_email.text);
                    setState(() {
                      _signedIn = identified ? _email.text.trim().toLowerCase() : null;
                      _status = identified ? 'Signed in' : 'Enter a valid email';
                    });
                  },
                  child: const Text('Sign in'),
                ),
                const SizedBox(height: 8),
                OutlinedButton(
                  onPressed: () async {
                    final result = await Sequenzy.subscribe(
                        SubscribeRequest(formId: newsletterFormId, email: _email.text));
                    setState(() => _status = result.ok ? 'Subscribed' : result.error ?? 'Could not subscribe');
                  },
                  child: const Text('Join the newsletter'),
                ),
              ] else ...[
                Text('Signed in as $_signedIn', style: const TextStyle(color: Color(0xFF64748B))),
                const SizedBox(height: 12),
                FilledButton(
                  onPressed: () async {
                    await Sequenzy.track('workout_completed', {'count': 4, 'source': 'flutter-example'});
                    setState(() => _status = 'Tracked workout_completed');
                  },
                  child: const Text('Log a workout'),
                ),
                const SizedBox(height: 8),
                OutlinedButton(
                  onPressed: () async {
                    await Sequenzy.screen('Pricing', {'from': 'home'});
                    await Sequenzy.viewedProduct(const CommerceProduct(
                        providerProductId: 'plan-annual', title: 'Annual plan', price: 99, currency: 'USD'));
                    setState(() => _status = 'Sent a screen view and a product view');
                  },
                  child: const Text('Open pricing'),
                ),
                const SizedBox(height: 8),
                OutlinedButton(
                  onPressed: () async {
                    await Sequenzy.setProfile(const ProfileUpdate(firstName: 'Jane', attributes: {'goal': 'strength'}));
                    setState(() => _status = 'Updated the profile');
                  },
                  child: const Text('Set goal: strength'),
                ),
                const SizedBox(height: 8),
                OutlinedButton(
                  onPressed: () async {
                    await Sequenzy.reset();
                    setState(() {
                      _signedIn = null;
                      _status = 'Signed out';
                    });
                  },
                  child: const Text('Sign out'),
                ),
                const SizedBox(height: 24),
                const Text('Inbox', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600)),
                const SizedBox(height: 12),
                ListenableBuilder(
                  listenable: _cards,
                  builder: (context, _) {
                    if (_cards.loading && _cards.cards.isEmpty) return const Text('Loading cards…');
                    if (_cards.error != null) return Text('Could not load cards: ${_cards.error}');
                    if (_cards.cards.isEmpty) return const Text('No cards yet');
                    return Column(children: [
                      for (final card in _cards.cards)
                        Padding(
                          padding: const EdgeInsets.only(bottom: 12),
                          child: InAppCardView(card: card, onDismiss: _cards.dismiss),
                        ),
                    ]);
                  },
                ),
              ],
              const SizedBox(height: 12),
              Text(_status, style: const TextStyle(color: Color(0xFF64748B))),
            ]),
          ),
        ),
      ),
    );
  }
}
0
likes
160
points
77
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Sequenzy for Flutter apps. Identify contacts, track events, register push tokens and show in-app messages and content cards.

Homepage
Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, http, shared_preferences, url_launcher

More

Packages that depend on sequenzy_flutter