Menu de guias

Android

A biblioteca Android do Kavchat adiciona ao seu app o bot de atendimento baseado em roteiro, com componentes Jetpack Compose e uma Activity para apps criados com Views. As respostas são previsíveis e continuam funcionando mesmo sem internet, com base na última versão publicada. Requer Android 6.0 (API 23) ou superior.

São dois componentes: kavchat-engine, a versão Kotlin/JVM do mecanismo de conversa, sem dependências do Android ou de bibliotecas de terceiros, e kavchat, com a comunicação de rede (HttpURLConnection), o cache no dispositivo (SharedPreferences), os componentes Compose KavchatChat e KavchatLauncher, e KavchatActivity.

Instalação

Gradle (Kotlin DSL)
// settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven("https://jitpack.io")
    }
}

// app/build.gradle.kts
dependencies {
    implementation("com.kavchat:kavchat-android:0.0.11")
}

A biblioteca é distribuída pelo JitPack. Adicione o repositório dele uma única vez, ao lado de google() e mavenCentral(). O SDK tem código aberto, sob a licença MIT: bitbucket.org/maxsave/kavchat-android.

A própria biblioteca declara a permissão INTERNET e a KavchatActivity no seu manifesto. Não é preciso adicionar nada manualmente.

Configuração

Chame configure uma única vez, em Application.onCreate:

Kotlin
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        Kavchat.configure(this, publicKey = "pk_live_...")
        // Optional: Kavchat.configure(this, "pk_live_...", apiBase = "https://api.kavchat.com", locale = "he")
    }
}

Você pode incluir a chave pública no app. Nunca inclua a chave secreta (sk_live_...).

Compose

Um botão flutuante no canto definido no painel, que abre o chat em tela cheia:

Compose
KavchatOverlay(Modifier.fillMaxSize()) {
    AppContent()
}

Você também pode posicionar o botão por conta própria ou incorporar o chat em uma tela do seu app:

Compose
KavchatLauncher()                                    // com.kavchat.ui.KavchatLauncher
KavchatChat(Modifier.fillMaxSize())                  // full chat, no close button
KavchatChat(Modifier.fillMaxSize(), onClose = { navController.popBackStack() })

Abra e feche o chat do botão flutuante pelo código com Kavchat.controller.setPresented(true) e setPresented(false).

Views (sem Compose no app)

Kotlin
Kavchat.open(context)                                // starts KavchatActivity

Em Java: Kavchat.open(context);. A Activity usa Compose internamente, mas seu app não precisa usar.

Token de identidade

Identifique o usuário conectado com um JWT assinado pelo seu servidor com a chave secreta (consulte Identificação de usuários). O token é enviado no cabeçalho Authorization: Bearer <token>. Um usuário identificado pode ver versões disponíveis apenas para usuários de teste e enviar o formulário de contato sem e-mail ou telefone.

Kotlin
Kavchat.setUser(token = identityToken, name = "Dana")   // after login
Kavchat.setUser(token = null)                           // after logout

A troca de usuário recarrega a versão e inicia uma nova conversa, para que a conversa de um usuário não apareça para outro.

Telas do app: onScreen

Um botão do tipo screen no roteiro solicita que o app abra uma de suas telas. O chat é fechado primeiro (o diálogo de KavchatLauncher ou a KavchatActivity), para que a tela fique visível:

Kotlin
Kavchat.onScreen = { screen, targetId ->
    navController.navigate("$screen/${targetId.orEmpty()}")   // e.g. "orders", "42"
}

Sem um handler, esses botões não fazem nada. Botões link abrem apenas links https (no navegador) e tel (no discador). Para análise de dados, Kavchat.onEvent informa os eventos Ready, Unavailable, Open, Close, Effect e Ticket.

Lista de telas no editor

Declare uma única vez as telas que o app pode abrir em Kavchat.configure(..., screens = ...) (tipo KavchatAppScreen). O SDK envia a lista ao Kavchat automaticamente, e o editor de roteiros oferece essas telas em uma lista suspensa com seus nomes, no lugar de um campo de texto livre. O editor também solicita um identificador de item quando a tela precisa dele e avisa quando um botão leva a uma tela não declarada. Ninguém precisa digitar a lista de telas manualmente no painel.

Kotlin
Kavchat.configure(
    this, publicKey = "pk_live_...",
    screens = listOf(
        KavchatAppScreen("orders", "My orders"),
        KavchatAppScreen("product", "Product page", needsTarget = true),   // needs a targetId
    ),
)
// or later: Kavchat.registerScreens(listOf(...))
  • id é o valor recebido por onScreen: letras latinas, dígitos, _, . e -, com até 40 caracteres. label é o nome que o administrador vê, com até 60 caracteres. O limite é de 100 telas. Registros inválidos e identificadores duplicados são descartados.
  • needsTarget: o botão também carrega um identificador de item (por exemplo, o identificador de um produto), recebido por onScreen como targetId.
  • A lista é enviada em segundo plano após o carregamento da versão, apenas quando muda ou uma vez por semana. Uma falha não é exibida, e o envio será tentado novamente na próxima abertura do app. O usuário não vê nada.
  • As telas registradas aparecem no painel em Bot, Configurações, "Telas do app", com as plataformas que informaram cada tela. Uma tela removida do app pode ser excluída ali.

Cores

As cores vêm do painel (primaryColor). O texto sobre a cor da marca é branco ou quase preto, conforme o contraste WCAG. Uma cor clara demais para texto sobre fundo branco é substituída por quase preto nos links e botões. O nome do bot, o subtítulo, a imagem e o lado do botão flutuante (start ou end) também vêm do painel e podem mudar sem atualizar o app. As superfícies e a tipografia seguem o seu MaterialTheme.

O selo "Desenvolvido por Kavchat by maxsave" aparece em todos os planos, com um link para kavchat.com. No Premium, você pode ocultá-lo nas configurações do bot.

Idiomas e RTL

  • O idioma da interface é o locale passado para configure. Se ele não for informado, será usado o idioma do dispositivo, caso exista tradução (he, en, ar, ru, es, fr, de, pt, it, tr); depois, o idioma do roteiro e, por último, o inglês.
  • A correspondência com o roteiro sempre usa o idioma do roteiro (palavras comuns ignoradas e prefixos em hebraico e árabe).
  • Em hebraico e árabe, o LocalLayoutDirection de todo o chat é RTL. Nada é invertido manualmente: se você envolver os componentes em outros elementos, use start e end. Mantenha android:supportsRtl="true" no manifesto do app.

Respostas de IA (Premium)

Não é preciso configurar nada no app. Ao ativar as respostas de IA no painel de administração (com sua própria chave de um provedor de IA), uma pergunta que nenhum roteiro responde é enviada ao Kavchat. Durante a espera, de até 20 segundos, o chat mostra que o bot está digitando. A resposta aparece como texto simples com uma pequena indicação "Resposta de IA" no idioma da interface. Abaixo dela, aparecem um botão para um assunto relacionado, se houver, e o botão "Falar com a equipe".

Se não houver resposta, ou se a solicitação falhar, demorar demais ou ultrapassar o limite (10 respostas por conversa a cada 15 minutos), o chat exibe a mensagem habitual "Não encontrei uma resposta". A pergunta continua aparecendo no relatório de perguntas sem resposta, e as respostas de IA ficam na conversa salva como qualquer outra mensagem.

Chat com atendente

Não é preciso configurar nada no app. Ao ativar o chat com atendentes no painel de administração, o chat no app funciona exatamente como o widget do site.

  • A opção só aparece quando o chat com atendentes está ativado na versão publicada. Quando o bot exibe "Falar com a equipe", o SDK verifica se há um atendente disponível. O resultado fica em cache por 30 segundos. Se houver um atendente disponível, o botão "Falar com atendente" aparece antes dessa opção. Caso contrário, aparece apenas o formulário de contato. Acima dele, uma linha curta explica o motivo: fora do horário de atendimento (incluindo o horário de retorno) ou todos os atendentes ocupados.
  • Antes da conversa, o usuário preenche um formulário curto: nome, e-mail ou telefone, departamento (apenas quando há mais de um departamento aberto) e primeira mensagem (opcional). Um visitante precisa informar e-mail ou telefone. Um usuário identificado por token de identidade não precisa informar nenhum dos dois. Se não houver mais atendentes disponíveis no momento do envio, o formulário de contato será aberto com os dados já preenchidos.
  • Durante a espera, aparecem o tempo restante até a conversa se tornar um chamado e o botão "Deixar uma mensagem". O tempo de espera é definido no painel de administração, com padrão de 2 minutos. É possível escrever durante a espera, e o atendente verá as mensagens. Se nenhum atendente ficar disponível a tempo, a conversa será salva como um chamado comum, e o número do chamado será exibido.
  • Durante a conversa, aparecem o nome do atendente, um aviso quando um atendente entra (inclusive após a transferência para outro atendente), um indicador de digitação e um botão para encerrar a conversa. As mensagens contêm apenas texto simples, com até 2.000 caracteres, sem links. Uma mensagem que ainda não chegou ao servidor fica marcada como "Enviando...". Se o envio falhar várias vezes, é possível tocar na mensagem para tentar novamente. Uma nova tentativa não duplica a mensagem.
  • Após cada desconexão, o SDK espera um pouco, recupera o que foi perdido e se reconecta. O tempo de espera aumenta gradualmente. As mensagens sempre aparecem na ordem e sem duplicatas. Se a conexão contínua não funcionar (por exemplo, por causa de um proxy corporativo), o SDK passa temporariamente a consultar o servidor em intervalos.
  • Quando o app vai para segundo plano, a conexão é fechada. Ao voltar ao app, o SDK recupera o que foi perdido e se reconecta. Uma conversa aberta continua mesmo depois de fechar e reabrir o app, desde que não tenham passado 12 horas.
  • Esta versão não tem notificações push. As mensagens chegam apenas enquanto o app está aberto. Uma resposta enviada enquanto o app estava em segundo plano aparece assim que o usuário volta.
  • As credenciais de acesso à conversa ficam na memória. No dispositivo, elas só são armazenadas com criptografia usando uma chave do Android Keystore. Elas não são gravadas na URL nem nos logs. As credenciais são excluídas quando a conversa termina, se torna um chamado ou expira, e também quando o usuário é trocado em setUser.

Você pode usar Kavchat.controller.livePage para informar ao atendente de qual tela o usuário veio.

Perguntas, condições e leads

Não é preciso configurar nada no app. Um roteiro pode pedir dados (nome, telefone, e-mail, número ou texto livre), decidir como continuar com base nas informações conhecidas e enviar um lead.

  • Teclado adequado: Quando o bot espera uma resposta, o campo de texto exibe um teclado de telefone, e-mail ou números. Nas perguntas de nome, o teclado usa maiúscula no início de cada palavra. Se a resposta for inválida, o bot responde com uma mensagem curta no idioma do chat, e o campo fica destacado. Nas perguntas que podem ser puladas, aparece o botão "Pular". Digitar "Cancelar", em qualquer idioma compatível, sai da pergunta.
  • Telefone: Números sem + usam o país padrão do espaço de trabalho, definido nas configurações do painel de administração.
  • Lead: Uma etapa de lead exibe o texto de consentimento com os botões "Enviar" e "Não, obrigado", seguido da mensagem de confirmação. O lead entra em uma fila no dispositivo e é enviado ao servidor. Se não houver conexão com a internet ou o servidor estiver indisponível, o envio será tentado novamente, inclusive na próxima abertura do app e após reload(). O servidor ignora duplicatas.
  • Preenchimento automático: O formulário de contato e o formulário de solicitação de atendimento são preenchidos com o nome, o e-mail e o telefone coletados. Todos os valores coletados são anexados ao chamado ou à solicitação de atendimento. As perguntas anteriores ao chat com atendente (Premium) são feitas antes da conexão.
  • Token de identidade: Ao usar setUser, os campos name, email e phone do token preenchem as respostas das perguntas correspondentes, e o bot pula essas perguntas.
  • Tela atual: As condições podem verificar a tela atual. Defina Kavchat.controller.livePage (por exemplo, "checkout").

Os valores coletados são dados pessoais. Eles permanecem na conversa salva no dispositivo e são enviados apenas para leads, chamados e conversas com atendentes, nunca para relatórios.

Uso sem internet e cache

A última versão fica salva em SharedPreferences com seu ETag e é revalidada com If-None-Match (304) a cada abertura do app. Sem internet, a cópia salva é usada, e um aviso informa isso. Quando o bot está desativado, disponível apenas para usuários de teste ou com a cota esgotada, nada é exibido. Uma conversa aberta é mantida por até 30 minutos de inatividade, para que sair do chat ou do app não a reinicie. O percurso da conversa é enviado dois segundos após a última ação e imediatamente quando o app vai para segundo plano.