Flutter SDK
Um cliente em Dart puro para o chat de suporte Respondo — sem código nativo de plataforma para compilar ou depurar.
Requisitos#
- Dart
>=3.4.0 <4.0.0. - Flutter
>=3.16.0(a linha 3.x). - Dart puro: sem pontes nativas, sem
pod install, sem edições ao Gradle. As dependências transitivas são pacotes Dart simples (http, web_socket_channel, uuid).
Instalação#
Adicione o pacote a partir do pub.dev:
dependencies:
respondo_sdk: ^0.1.2import 'package:respondo_sdk/respondo_sdk.dart';Inicializar#
Ligue Respondo.navigatorKey ao seu MaterialApp para que o SDK possa abrir o sheet do chat sem o seu BuildContext, chame Respondo.init uma vez, e depois Respondo.open().
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:respondo_sdk/respondo_sdk.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
// O diretório de armazenamento de arquivos vem de um plugin do app anfitrião; o SDK mantém-se puro.
final dir = await getApplicationSupportDirectory();
await Respondo.init(
RespondoConfig(
agentId: '<agent-uuid>',
channelId: '<channel-uuid>',
storageDirectory: dir.path,
),
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: Respondo.navigatorKey, // obrigatório para que o SDK possa abrir o chat
home: Scaffold(
body: Center(
child: FilledButton(
onPressed: () => Respondo.open(),
child: const Text('Support'),
),
),
),
);
}
}Todos os métodos da fachada são idempotentes, seguros de chamar antes da init (armazenam em buffer e reproduzem), e nunca lançam exceções para dentro da seu app.
Identificar usuários#
Por padrão, todos os visitantes são anônimos. Na primeira execução o SDK gera um visitor_id estável e o salva no armazenamento local, para que um usuário que retorna encontre novamente a sua conversa. Não há nenhuma chave de API para embeber — cada conversa é protegida por um token de sessão por conversa que o backend cunha e faz avançar a cada mensagem, para que um visitante anônimo nunca tenha de se voltar a autenticar.
Chame identify assim que o seu usuário estiver autenticado. Isso associa a identidade real, para que o histórico o acompanhe entre dispositivos e reinstalações, e o nome e o e-mail apareçam junto à conversa na sua caixa de entrada em vez de um visitante anônimo.
O userHash é uma assinatura que o seu backend calcula a partir do identity_secret do agente — HMAC-SHA256(secret, userId) (ou o e-mail quando não há userId), codificado em hexadecimal minúsculo. O segredo prova que a identidade é genuína, por isso deve viver apenas no seu backend e nunca é enviado na app. Consulte a página Verificação de identidade para a fórmula completa e exemplos do lado do servidor.
// 1. Autentique-se contra o seu próprio backend e leia o hash pré-calculado
// (por exemplo, um campo retornado junto com a resposta de login).
final session = await api.login(email, password);
// 2. Entregue o userHash pronto ao SDK — nunca o calcule no app.
Respondo.identify(RespondoIdentity(
userId: session.userId,
email: session.email,
name: session.fullName,
userHash: session.respondoUserHash,
));
// 3. No logout: revogue a sessão e inicie um novo visitante anônimo.
Respondo.reset();Se o hash estiver ausente ou errado, nada é lançado: o backend mantém silenciosamente o visitante anônimo, o chat continua funcionando, e apenas perde o vínculo entre dispositivos até ser fornecido um hash válido. A verificação só roda quando o agente tem um identity_secret definido — deixe-o vazio durante o desenvolvimento e userId / e-mail são aceites tal como estão.
Observáveis & callbacks#
Tudo está disponível como um Stream broadcast, um setter de callback e um getter de valor atual.
// Stream reativo de contagens de não lidas (para um badge).
Respondo.unreadCountStream.listen((n) => setBadge(n));
// Ou um setter de callback.
Respondo.onUnreadChanged = (n) => setBadge(n);
// Intercepte links/CTAs; retorne true se o app anfitrião abriu a URL por conta própria.
Respondo.onUrlRequested = (url) {
openInAppBrowser(url);
return true;
};Rastreamento de tela#
Informe a tela atual em cada navegação para que os teasers proativos e a segmentação no nível da página possam corresponder a ela. Passe null para limpá-la; a cada mudança, o teaser proativo é reavaliado para a nova tela.
Respondo.setCurrentScreen('pricing');Próximos passos#
Adicione as Notificações push e a Verificação de identidade. A superfície completa da API, as superfícies de engagement e a resolução de problemas são abordadas no guia de introdução do Flutter SDK na página do pacote no pub.dev.