southgames_flutter 0.5.11
southgames_flutter: ^0.5.11 copied to clipboard
Flutter SDK for SouthGames — integrate gamification and loyalty features (spin wheel, scratch cards, trivia, slot machine, promo codes, in-app notifications) into your Flutter app with a single package.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:southgames_flutter/southgames_flutter.dart';
// import 'firebase_options.dart'; // Generated by `flutterfire configure`
/// Background message handler — must be a top-level function.
@pragma('vm:entry-point')
Future<void> _firebaseBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
await SouthGamesSDK.handleBackgroundMessage(message);
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 1. Initialize Firebase (required before SouthGamesSDK.init)
await Firebase.initializeApp(
// options: DefaultFirebaseOptions.currentPlatform, // Uncomment after running `flutterfire configure`
);
// 2. Register background message handler
FirebaseMessaging.onBackgroundMessage(_firebaseBackgroundHandler);
// 3. Initialize SouthGames — push permissions, tokens, and
// foreground handling are all set up automatically.
await SouthGamesSDK.init(
apiKey: 'sg_live_xxxxxxxxxxxxxxxx',
orgId: 'your-org-slug',
pushConfig: PushConfig(
// Request permissions on init (default: true).
// Set to false to request manually at a better moment.
requestPermissionOnInit: true,
// Show notifications when app is in foreground (default: true)
showForegroundNotifications: true,
// Handle notification taps (deep links, navigation, etc.)
onNotificationTap: (message) {
debugPrint('Notification tapped: ${message.data}');
// Example: navigate to a specific screen based on data
// Navigator.pushNamed(context, message.data['route']);
},
// Handle foreground messages
onForegroundMessage: (message) {
debugPrint('Foreground message: ${message.notification?.title}');
},
),
);
runApp(const MyApp());
}
/// Example app demonstrating the SouthGames Flutter SDK.
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'SouthGames Demo',
// Wrap with the notification overlay to show in-app notifications
home: SouthGamesNotificationOverlay(
onCtaTap: (action) {
debugPrint('CTA tapped: $action');
// Handle deep links / URLs
},
child: const HomeScreen(),
),
);
}
}
/// Home screen with gamification features.
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
String? _clientId;
List<Campaign> _campaigns = [];
String _status = 'Identificando cliente...';
@override
void initState() {
super.initState();
_identify();
}
Future<void> _identify() async {
try {
// identify() automatically gets the FCM token and registers it.
// No need to pass tokenProvider — it's handled internally.
final res = await SouthGamesSDK.identify(
externalId: 'demo_user_123',
email: 'demo@example.com',
customParams: {'plan': 'free'},
);
setState(() {
_clientId = res.clientId;
_status = res.created
? 'Cliente registrado: ${res.clientId}'
: 'Cliente actualizado: ${res.clientId}';
});
// Start heartbeat to track sessions
await SouthGamesSDK.heartbeat(clientId: res.clientId);
} on SouthGamesException catch (e) {
setState(() => _status = 'Error: ${e.message}');
}
}
Future<void> _loadCampaigns() async {
try {
final campaigns = await SouthGamesSDK.getCampaigns();
setState(() {
_campaigns = campaigns;
_status = '${campaigns.length} campaña(s) encontrada(s)';
});
} on SouthGamesException catch (e) {
setState(() => _status = 'Error: ${e.message}');
}
}
Future<void> _play(Campaign campaign) async {
try {
final result = await SouthGamesSDK.play(
campaignId: campaign.id,
externalUserId: _clientId ?? 'demo_user',
);
setState(() {
if (result.won) {
_status = '¡Ganaste! Código: ${result.prizeCode ?? "sin código"}';
} else {
_status = 'No ganaste. Resultado: ${result.result}';
}
});
} on SouthGamesException catch (e) {
setState(() => _status = 'Error: ${e.message}');
}
}
Future<void> _loadNotifications() async {
if (_clientId == null) {
setState(() => _status = 'Registra un cliente primero');
return;
}
try {
final notifications = await SouthGamesSDK.getInAppNotifications(
clientId: _clientId!,
);
setState(() {
_status = '${notifications.length} notificación(es)';
});
} on SouthGamesException catch (e) {
setState(() => _status = 'Error: ${e.message}');
}
}
Future<void> _trackEvent() async {
try {
final result = await SouthGamesSDK.trackEvent(
eventName: 'button_clicked',
externalUserId: _clientId ?? 'demo_user',
properties: {'screen': 'home'},
);
setState(() {
_status = 'Evento trackeado: ${result.eventName}';
if (result.triggeredNotifications.isNotEmpty) {
_status +=
' (${result.triggeredNotifications.length} notificación(es) triggered)';
}
});
} on SouthGamesException catch (e) {
setState(() => _status = 'Error: ${e.message}');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('SouthGames Demo')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(_status, style: Theme.of(context).textTheme.bodyLarge),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _identify,
child: const Text('Identificar cliente'),
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: _loadCampaigns,
child: const Text('Cargar campañas'),
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: _loadNotifications,
child: const Text('Ver notificaciones'),
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: _trackEvent,
child: const Text('Trackear evento'),
),
const SizedBox(height: 16),
Expanded(
child: ListView.builder(
itemCount: _campaigns.length,
itemBuilder: (context, index) {
final c = _campaigns[index];
return ListTile(
title: Text(c.name),
subtitle: Text(c.gameType ?? 'traditional'),
trailing: ElevatedButton(
onPressed: () => _play(c),
child: const Text('Jugar'),
),
);
},
),
),
],
),
),
);
}
}