dito_sdk 3.1.4
dito_sdk: ^3.1.4 copied to clipboard
Plugin Flutter para integração com o CRM Dito, fornecendo APIs unificadas para iOS e Android
Dito SDK Flutter Plugin #
Plugin Flutter oficial da Dito para integração com o CRM Dito, fornecendo APIs unificadas para iOS e Android.
📋 Visão Geral #
O Dito SDK Flutter Plugin é a biblioteca oficial da Dito para aplicações Flutter, permitindo que você integre seu app com a plataforma de CRM e Marketing Automation da Dito.
Com o Dito SDK Flutter Plugin você pode:
- 🔐 Identificar usuários e sincronizar seus dados com a plataforma
- 📊 Rastrear eventos e comportamentos dos usuários
- 🔔 Gerenciar notificações push via Firebase Cloud Messaging
- 💾 Gerenciar dados offline automaticamente
📱 Requisitos #
| Requisito | Versão Mínima |
|---|---|
| Flutter | 3.3.0+ |
| Dart | 3.10.7+ |
| iOS | 16.0+ |
| Android API | 24+ |
📦 Instalação #
1. Adicione a dependência no pubspec.yaml #
dependencies:
dito_sdk:
path: ../flutter
Ou se publicado no pub.dev:
dependencies:
dito_sdk: ^1.0.0
2. Instale as dependências #
flutter pub get
3. Configure as plataformas nativas #
Android
Para tracking de notificações em background, é necessário adicionar as credenciais no AndroidManifest.xml do seu app:
<application>
<meta-data
android:name="br.com.dito.API_KEY"
android:value="${DITO_API_KEY}" />
<meta-data
android:name="br.com.dito.API_SECRET"
android:value="${DITO_API_SECRET}" />
</application>
E configurar no build.gradle.kts do módulo app:
android {
defaultConfig {
// ... outras configurações
val ditoApiKey = System.getenv("DITO_API_KEY")
?: (localProperties.getProperty("DITO_API_KEY") ?: "")
val ditoApiSecret = System.getenv("DITO_API_SECRET")
?: (localProperties.getProperty("DITO_API_SECRET") ?: "")
manifestPlaceholders["DITO_API_KEY"] = ditoApiKey
manifestPlaceholders["DITO_API_SECRET"] = ditoApiSecret
}
}
Por quê? Quando uma notificação chega em background, o SDK nativo Android precisa das credenciais para fazer tracking do evento "receive-android-notification" mesmo que o app não tenha sido inicializado explicitamente.
Para mais detalhes, consulte Android.
iOS
O plugin já configura o Firebase Messaging no iOS em tempo de execução, sem necessidade
de alterar o AppDelegate. Ainda assim, algumas configurações continuam obrigatórias:
- Adicionar o arquivo
GoogleService-Info.plistno app iOS - Habilitar Push Notifications e Background Modes (Remote notifications) no Xcode
- Configurar APNs no Firebase (chave ou certificados)
Configuração Opcional - Credenciais no Info.plist
Para tracking de notificações em background (similar ao Android), você pode adicionar as credenciais no Info.plist do seu app iOS:
<key>AppKey</key>
<string>sua-api-key</string>
<key>AppSecret</key>
<string>seu-api-secret</string>
Por quê? Se uma notificação chegar em background antes do app ter sido inicializado explicitamente, o SDK nativo iOS poderá carregar as credenciais do Info.plist para fazer tracking do evento "receive-ios-notification".
Nota: Se você inicializar o SDK com DitoSdk.initialize() no main(), as credenciais passadas via código terão prioridade sobre as do Info.plist.
⚙️ Configuração Inicial #
1. Inicialize o SDK #
import 'package:dito_sdk/dito_sdk.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
try {
await DitoSdk.initialize(
apiKey: "sua-api-key",
apiSecret: "seu-api-secret",
);
print('SDK initialized successfully');
} catch (e) {
print('Failed to initialize: $e');
}
runApp(MyApp());
}
📖 Métodos Disponíveis #
initialize #
Descrição: Inicializa o Dito SDK com as credenciais fornecidas. Este método deve ser chamado antes de usar qualquer outro método do SDK.
Assinatura:
Future<void> initialize({
required String apiKey,
required String apiSecret,
})
Parâmetros:
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| apiKey | String | Sim | Chave API fornecida pela Dito |
| apiSecret | String | Sim | Segredo API fornecido pela Dito |
Retorno: Future<void>
Possíveis Erros:
PlatformExceptioncom códigoINVALID_PARAMETERS: SeapiKeyouapiSecretforem null ou vaziosPlatformExceptioncom códigoINITIALIZATION_FAILED: Se a inicialização falharPlatformExceptioncom códigoINVALID_CREDENTIALS: Se as credenciais forem inválidas
Exemplo:
try {
await DitoSdk.initialize(
apiKey: "sua-api-key",
apiSecret: "seu-api-secret",
);
print('SDK initialized successfully');
} on PlatformException catch (e) {
print('Failed to initialize: ${e.message}');
}
Notas:
- Deve ser chamado apenas uma vez durante o ciclo de vida do app
- Deve ser chamado antes de qualquer outro método do SDK
identify #
Descrição: Identifica um usuário no CRM Dito.
Assinatura:
Future<void> identify({
required String id,
String? name,
String? email,
Map<String, dynamic>? customData,
})
Parâmetros:
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| id | String | Sim | Identificador único do usuário |
| name | String? | Não | Nome do usuário |
| String? | Não | Email do usuário (deve ser válido se fornecido) | |
| customData | Map<String, dynamic>? | Não | Dados customizados adicionais |
Retorno: Future<void>
Possíveis Erros:
PlatformExceptioncom códigoNOT_INITIALIZED: Se o SDK não foi inicializadoPlatformExceptioncom códigoINVALID_PARAMETERS: Seidfor null ou vazio, ou seemailfor inválido
Exemplo:
try {
await DitoSdk.identify(
id: 'user123',
name: 'João Silva',
email: 'joao@example.com',
customData: {
'tipo_cliente': 'premium',
'pontos': 1500,
},
);
} on PlatformException catch (e) {
print('Error: ${e.message}');
}
Notas:
- O usuário deve ser identificado antes de rastrear eventos
- O email é opcional, mas se fornecido deve ser válido
track #
Descrição: Rastreia um evento no CRM Dito.
Assinatura:
Future<void> track({
required String action,
Map<String, dynamic>? data,
})
Parâmetros:
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| action | String | Sim | Nome da ação do evento |
| data | Map<String, dynamic>? | Não | Dados adicionais do evento |
Retorno: Future<void>
Possíveis Erros:
PlatformExceptioncom códigoNOT_INITIALIZED: Se o SDK não foi inicializadoPlatformExceptioncom códigoINVALID_PARAMETERS: Seactionfor null ou vazio
Exemplo:
try {
await DitoSdk.track(
action: 'purchase',
data: {
'product': 'item123',
'price': 99.99,
'currency': 'BRL',
},
);
} on PlatformException catch (e) {
print('Error: ${e.message}');
}
Notas:
- O usuário deve ser identificado antes de rastrear eventos
- Dados são sincronizados automaticamente em background
registerDeviceToken #
Descrição: Registra um token de dispositivo para receber push notifications.
Assinatura:
Future<void> registerDeviceToken(String token)
Parâmetros:
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| token | String | Sim | Token FCM do dispositivo |
Retorno: Future<void>
Possíveis Erros:
PlatformExceptioncom códigoNOT_INITIALIZED: Se o SDK não foi inicializadoPlatformExceptioncom códigoINVALID_PARAMETERS: Setokenfor null ou vazio
Exemplo:
import 'package:firebase_messaging/firebase_messaging.dart';
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
Future<void> registerDevice() async {
try {
final token = await _firebaseMessaging.getToken();
if (token != null) {
await DitoSdk.registerDeviceToken(token);
}
} on PlatformException catch (e) {
print('Error: ${e.message}');
}
}
Notas:
- Deve ser chamado após obter o token FCM do Firebase
- O token deve ser atualizado sempre que o Firebase gerar um novo token
unregisterDeviceToken #
Descrição: Remove o registro de um token de dispositivo para parar de receber push notifications.
Assinatura:
Future<void> unregisterDeviceToken(String token)
Parâmetros:
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| token | String | Sim | Token FCM do dispositivo a ser removido |
Retorno: Future<void>
Possíveis Erros:
PlatformExceptioncom códigoNOT_INITIALIZED: Se o SDK não foi inicializadoPlatformExceptioncom códigoINVALID_PARAMETERS: Setokenfor null ou vazio
Exemplo:
Future<void> unregisterDevice() async {
try {
final token = await FirebaseMessaging.instance.getToken();
if (token != null) {
await DitoSdk.unregisterDeviceToken(token);
}
} on PlatformException catch (e) {
print('Error: ${e.message}');
}
}
Notas:
- Use este método quando o usuário fizer logout ou desabilitar notificações
🔔 Push Notifications #
Para um guia completo de configuração de Push Notifications, consulte o guia unificado.
Android (Flutter) com firebase_messaging #
No Android, o sistema executa apenas um FirebaseMessagingService por app. Se o seu app usa firebase_messaging, você deve criar um service delegador que:
- Delega notificações
channel=DITOpara o SDK nativo Dito - Encaminha as demais notificações para o FlutterFire
No seu app Android, crie:
package com.seu.app
import br.com.dito.ditosdk.DitoMessagingServiceHelper
import com.google.firebase.messaging.RemoteMessage
import io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingService
class CustomMessagingService : FlutterFirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage) {
val handled = DitoMessagingServiceHelper.handleMessage(applicationContext, remoteMessage)
if (!handled) {
super.onMessageReceived(remoteMessage)
}
}
override fun onNewToken(token: String) {
super.onNewToken(token)
DitoMessagingServiceHelper.handleNewToken(applicationContext, token)
}
}
E registre no AndroidManifest.xml do app:
<service
android:name=".CustomMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
iOS (Flutter) #
O plugin cuida da configuração nativa do Firebase Messaging no iOS. Para que o fluxo funcione, o app precisa:
- Adicionar
GoogleService-Info.plistno target iOS - Habilitar Push Notifications e Background Modes (Remote notifications)
- Configurar APNs no Firebase
Se você usa firebase_messaging no Dart para tratar mensagens, mantenha a inicialização do Firebase no main():
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// Processar notificação em background
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
}
Configuração Básica (Flutter) #
- Configure o Firebase no seu projeto Flutter
- Instale o plugin
firebase_messaging:
dependencies:
firebase_messaging: ^14.0.0
- Configure o tratamento de notificações no Dart (se aplicavel ao seu app)
⚠️ Tratamento de Erros #
O SDK Flutter lança PlatformException para erros. Todos os erros incluem mensagens descritivas:
- INITIALIZATION_FAILED: Falha na inicialização do SDK
- INVALID_CREDENTIALS: Credenciais inválidas fornecidas
- NOT_INITIALIZED: Método chamado antes da inicialização
- INVALID_PARAMETERS: Parâmetros inválidos fornecidos
- NETWORK_ERROR: Erro de rede durante a operação
Exemplo de tratamento de erros:
try {
await DitoSdk.initialize(
apiKey: apiKey,
apiSecret: apiSecret,
);
} on PlatformException catch (e) {
switch (e.code) {
case 'INITIALIZATION_FAILED':
print('Failed to initialize SDK');
break;
case 'INVALID_CREDENTIALS':
print('Invalid credentials');
break;
default:
print('Error: ${e.message}');
}
}
🐛 Troubleshooting #
Erro: "Dito SDK is not initialized" #
Solução: Certifique-se de chamar DitoSdk.initialize() antes de usar qualquer outro método:
await DitoSdk.initialize(
apiKey: 'your-api-key',
apiSecret: 'your-api-secret',
);
Erro: "Invalid email format" #
Solução: Verifique se o email fornecido está no formato correto (ex: user@example.com). O email é opcional, então você pode passar null se não tiver um email válido.
Eventos não aparecem no painel Dito #
Checklist:
- ✅ SDK inicializado (
DitoSdk.initialize()) - ✅ Usuário identificado ANTES de rastrear eventos
- ✅ Conexão com internet (ou aguardar sincronização offline)
// ❌ ERRADO - evento antes da identificação
await DitoSdk.track(action: 'purchase', data: {'product': 'item123'});
await DitoSdk.identify(id: userId, name: 'John', email: 'john@example.com');
// ✅ CORRETO - identifique primeiro
await DitoSdk.identify(id: userId, name: 'John', email: 'john@example.com');
await DitoSdk.track(action: 'purchase', data: {'product': 'item123'});
Evento "receive-android-notification" não dispara em background #
Causa: SDK não consegue se inicializar automaticamente em background sem credenciais.
Solução: Configure as credenciais no AndroidManifest.xml:
<application>
<meta-data
android:name="br.com.dito.API_KEY"
android:value="${DITO_API_KEY}" />
<meta-data
android:name="br.com.dito.API_SECRET"
android:value="${DITO_API_SECRET}" />
</application>
Veja a seção Configure as plataformas nativas - Android para detalhes completos.
Evento "receive-ios-notification" não dispara em background #
Checklist:
GoogleService-Info.plistno target iOS- Push Notifications e Background Modes (Remote notifications) habilitados
- APNs configurado no Firebase
Se o problema persistir: Adicione as credenciais no Info.plist para permitir tracking em background mesmo quando o app não foi inicializado explicitamente:
<key>AppKey</key>
<string>sua-api-key</string>
<key>AppSecret</key>
<string>seu-api-secret</string>
Veja a seção Configure as plataformas nativas - iOS para mais detalhes.
4. App aberto ao menos uma vez para registrar o token
5. Notificacao enviada com channel=DITO no payload
💡 Exemplos Completos #
Exemplo Básico #
import 'package:dito_sdk/dito_sdk.dart';
import 'package:flutter/material.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
try {
await DitoSdk.initialize(
apiKey: "sua-api-key",
apiSecret: "seu-api-secret",
);
} catch (e) {
print('Failed to initialize: $e');
}
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
Future<void> _identifyUser() async {
try {
await DitoSdk.identify(
id: 'user123',
name: 'João Silva',
email: 'joao@example.com',
customData: {'source': 'flutter_app'},
);
print('User identified successfully');
} catch (e) {
print('Error: $e');
}
}
Future<void> _trackEvent() async {
try {
await DitoSdk.track(
action: 'purchase',
data: {
'product_id': 'item123',
'price': 99.99,
'currency': 'BRL',
},
);
print('Event tracked successfully');
} catch (e) {
print('Error: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Dito SDK Example')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: _identifyUser,
child: Text('Identify User'),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: _trackEvent,
child: Text('Track Event'),
),
],
),
),
);
}
}
📄 Licença #
Este projeto está licenciado sob uma licença proprietária. Veja LICENSE para detalhes completos dos termos de licenciamento.
Resumo dos Termos:
- ✅ Permite uso das SDKs em aplicações comerciais
- ✅ Permite uso em aplicações próprias dos clientes
- ❌ Proíbe modificação do código fonte
- ❌ Proíbe cópia e redistribuição do código
🔗 Links Úteis- 🌐 Website Dito #
🛠️ Desenvolvimento no Monorepo #
Este projeto usa Melos para gerenciamento de pacotes no monorepo.
Setup Inicial #
cd flutter
./setup_melos.sh
Comandos Úteis #
cd flutter
melos bootstrap # Instalar dependências de todos os pacotes
melos run test # Executar testes
melos run analyze # Analisar código
melos run format # Formatar código
melos run check # Executar todos os checks
Para mais informações, consulte o Guia Melos.