Módulo AtaliaChat, pelo Swift Package Manager (https://github.com/Atalia-IA/atalia-mobile-sdk, versão 0.4.0). Tudo é chamado pelo Atalia, que vive na main thread (@MainActor). As funções de push são a exceção: podem ser chamadas de qualquer thread, porque os delegates do iOS e do Firebase não garantem a main thread.
Atalia
Configuração
| Membro | Descrição |
|---|
configure(channelToken: String, options: AtaliaOptions = AtaliaOptions()) | Inicia o SDK. Chame uma vez, no início do app. Chamar de novo troca o canal. |
sdkVersion: String | Versão do SDK ("0.4.0"). |
Chat
| Membro | Descrição |
|---|
present(from: UIViewController? = nil, conversationId: Int? = nil, animated: Bool = true) | Abre o chat por cima da tela atual (ou de from). Com conversationId, direto nessa conversa. Com o chat já aberto, só troca de conversa. |
dismiss(animated: Bool = true) | Fecha o chat aberto por present. |
urlHandler: ((URL) -> Bool)? | Decide como abrir os links tocados no chat. Devolva true se o app tratou; false (ou nil) abre pelo sistema. |
Identificação
| Membro | Descrição |
|---|
identify(jwt: String) async throws -> AtaliaContact | Liga o visitante ao usuário logado. O JWT vem do seu backend. Lança AtaliaError. |
logout() async | Encerra a sessão identificada; o aparelho volta a ser visitante anônimo. |
Não lidas e estado
| Membro | Descrição |
|---|
state: AtaliaState | Estado observável, para SwiftUI. |
unreadCount: Int | Mensagens do atendente, da IA e do sistema ainda não lidas. |
isIdentified: Bool | A sessão pertence a um usuário identificado. |
refreshUnread() async throws -> Int | Consulta as não lidas na Atalia e atualiza o estado. O SDK já consulta sozinho quando o app volta para a frente. |
Eventos
| Membro | Descrição |
|---|
addListener(_ listener: @escaping (AtaliaEvent) -> Void) -> AtaliaListenerToken | Recebe os eventos do chat, na main thread. |
removeListener(_ token: AtaliaListenerToken) | Para de receber. |
Swift
let token = Atalia.addListener { event in
switch event {
case let .messageReceived(_, messageId):
print("mensagem \(messageId)")
case let .error(code, _):
print("erro \(code)")
default:
break
}
}
Notificações push
Todas podem ser chamadas de qualquer thread.
| Membro | Descrição |
|---|
setPushToken(_ token: String) | Token do Firebase do aparelho. |
setAPNsToken(_ deviceToken: Data, environment: AtaliaPushEnvironment) | Token do APNs, para quem envia pelo próprio backend (webhook). |
clearPushToken() | Tira o aparelho da Atalia. |
isAtaliaNotification(_ userInfo: [AnyHashable: Any]) -> Bool | A notificação veio da Atalia? |
presentationOptions(for notification: UNNotification) -> UNNotificationPresentationOptions? | Para o willPresent. Atualiza as não lidas e devolve [] com o chat na tela; senão banner, lista, som e badge. nil quando não é da Atalia. |
handleNotificationTap(_ userInfo: [AnyHashable: Any]) -> Bool | Para o didReceive. Abre o chat na conversa, inclusive quando o toque é que abriu o app. false quando não é da Atalia. |
AtaliaState
ObservableObject, em Atalia.state. As propriedades só mudam pelo SDK.
| Propriedade | Tipo | Descrição |
|---|
unreadCount | Int | Não lidas. |
isIdentified | Bool | Usuário identificado. |
isChatOpen | Bool | A tela do chat está aberta. |
AtaliaOptions
Passadas no configure.
| Propriedade | Tipo | Padrão | Descrição |
|---|
baseURL | URL | AtaliaOptions.defaultBaseURL (https://chat.atalia.ai) | Origem do chat. Troque só para homologação ou para o domínio próprio do canal. |
customDomain | Bool | false | true quando baseURL é o domínio próprio vinculado ao canal. |
closeButton | Bool | true | Mostra o botão "Fechar". Desligue quando o chat for uma aba do app. |
presentationStyle | .pageSheet, .fullScreen | .pageSheet | Como present e .ataliaChat(isPresented:) abrem o chat: folha que sobe sobre o app, com a alça no topo (arrastar para baixo fecha), ou tela cheia. Até a 0.3.0, o padrão era .fullScreen. |
debug | Bool | false | Permite inspecionar o WebView pelo Safari (iOS 16.4 ou mais novo). Nunca em produção. |
appBadge | Bool | true | Com o push ligado, o número no ícone do app acompanha as não lidas. Com false, nem o SDK nem o push da Atalia mexem no número. |
AtaliaPushEnvironment
Ambiente do token do APNs em setAPNsToken: .sandbox nos builds instalados pelo Xcode, .production no TestFlight e na App Store.
AtaliaEvent
| Evento | Quando |
|---|
.ready | O chat terminou de carregar. |
.opened / .closed | A tela do chat apareceu ou foi fechada. |
.identified(externalId: String, contactId: Int) | O visitante foi identificado. |
.loggedOut | A sessão identificada foi encerrada. |
.conversationStarted(conversationId: Int) | Uma conversa começou. |
.conversationClosed(conversationId: Int) | Uma conversa foi encerrada. |
.messageReceived(conversationId: Int, messageId: Int) | Chegou mensagem do atendente, da IA ou do sistema. Só os ids: o texto nunca sai do chat. |
.unreadChanged(count: Int) | O total de não lidas mudou. |
.error(code: String, command: String?) | Falha do chat (INIT_FAILED) ou de um comando (command = "identify", "open_conversation"...). |
Devolvido pelo identify.
| Propriedade | Tipo | Descrição |
|---|
externalId | String | O sub do JWT: o id do usuário no seu sistema. |
contactId | Int | O contato na Atalia. |
name | String? | Nome do contato, quando há. |
AtaliaError
Erro das chamadas do SDK. code é o mesmo código devolvido pela Atalia.
code | Quando |
|---|
NO_SECRET_CONFIGURED, INVALID_SIGNATURE, EXPIRED, INVALID_TOKEN, REPLAYED | identify recusado. Veja os códigos. |
NOT_CONFIGURED (AtaliaError.notConfigured) | O configure ainda não foi chamado. |
TIMEOUT (AtaliaError.timeout) | Com o chat aberto, ele não respondeu a tempo a um comando. |
SESSION_FAILED | A Atalia não criou a sessão do visitante. |
UNREAD_FAILED | A consulta de não lidas falhou. |
Falha de rede chega como URLError, não como AtaliaError.
Telas
| Tipo | Descrição |
|---|
AtaliaChatViewController(conversationId: Int? = nil) | O chat em UIKit. onClose: (() -> Void)? é chamado no "Fechar"; openConversation(_:) troca de conversa. |
AtaliaChatView(conversationId: Int? = nil, onClose: (() -> Void)? = nil) | O chat como view do SwiftUI. Para uma aba, use com AtaliaOptions(closeButton: false). |
View.ataliaChat(isPresented: Binding<Bool>, conversationId: Int? = nil) | Abre o chat enquanto isPresented for true, numa folha ou em tela cheia (AtaliaOptions.presentationStyle). |
View.ataliaLauncher(_ options: AtaliaLauncherOptions = AtaliaLauncherOptions()) | Botão flutuante por cima da view. |
AtaliaLauncherView(options:) e AtaliaLauncherView.attach(to: UIView, options:) -> AtaliaLauncherView | O botão flutuante em UIKit. Ocupa a área de quem o recebe, mas só o botão recebe toque. |
As opções do botão estão em Botão flutuante.
Dados da notificação
A notificação da Atalia traz, no primeiro nível do userInfo, estes dados em texto: atalia ("1"), v, channel_token, conversation_id, message_id e sender_type. No teste do painel, type vale "test" e não há conversa. O thread-id e o apns-collapse-id são atalia-conv-<conversation_id>.