Chat v mobilní aplikaci
Chat Otta zobrazíte v aplikaci pro Android i iOS přes webové zobrazení. Stačí otevřít jednu adresu, nic se neinstaluje.
Adresa chatu
https://ottoai.sk/m/<veřejný klíč>?lang=csVeřejný klíč je stejný jako v kódu chatu na webu (data-otto-key). Tajný API klíč aplikace nepotřebuje. lang je sk, cs nebo en, bez něj platí jazyk z panelu.

Co stránka dělá
- Chat je otevřený přes celou obrazovku, bez bubliny, a respektuje výřez displeje.
- Křížek v hlavičce chat nezavře, ale pošle aplikaci událost
close. Obrazovku zavře aplikace. - Odkazy a karty produktů neopustí chat, aplikace dostane událost s adresou a sama rozhodne, kam ji otevře.
- Rozhovor zůstává uložený v úložišti zobrazení, po návratu do aplikace pokračuje.
Události pro aplikaci
Stránka posílá zprávy přes most, který aplikace připojí. Každá je JSON s "source": "otto".
| type | Kdy přijde | Další pole |
|---|---|---|
ready | chat se načetl a je otevřený | |
close | zákazník klikl na křížek nebo stiskl Esc | |
message | přišla odpověď Otta nebo zpráva kolegy | role: bot nebo operator |
handoff | Otto předal rozhovor kolegovi | |
resolved | kolega rozhovor uzavřel | |
productClick | zákazník klikl na kartu produktu | url |
link | zákazník klikl na jiný odkaz | url |
error | chat je vypnutý nebo klíč neplatí | reason: off nebo key |
Přihlášený zákazník
Pokud chcete, aby kolega viděl jméno a e-mail přihlášeného zákazníka, vložte před načtením stránky objekt window.ottoUser. Osobní údaje nikdy neposílejte v adrese. Příklady níže to ukazují pro každou platformu.
Android (Kotlin)
Most připojte přes androidx.webkit s povoleným původem https://ottoai.sk, ne přes addJavascriptInterface.
val web = WebView(this)
web.settings.javaScriptEnabled = true
web.settings.domStorageEnabled = true
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER)) {
WebViewCompat.addWebMessageListener(web, "ottoChatBridge", setOf("https://ottoai.sk")) { _, sprava, _, _, _ ->
val u = JSONObject(sprava.data ?: "{}")
when (u.optString("type")) {
"close" -> finish()
"productClick", "link" -> startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(u.optString("url"))))
}
}
}
if (WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) {
WebViewCompat.addDocumentStartJavaScript(web,
"window.ottoUser = { name: 'Ján Novák', email: 'jan@example.sk' };", setOf("https://ottoai.sk"))
}
web.loadUrl("https://ottoai.sk/m/pk_vas_kluc?lang=cs")iOS (Swift)
final class OttoMost: NSObject, WKScriptMessageHandler {
var zatvor: () -> Void = {}
func userContentController(_ c: WKUserContentController, didReceive m: WKScriptMessage) {
guard m.frameInfo.securityOrigin.host == "ottoai.sk", let u = m.body as? [String: Any] else { return }
switch u["type"] as? String {
case "close": zatvor()
case "productClick", "link":
if let s = u["url"] as? String, let url = URL(string: s) { UIApplication.shared.open(url) }
default: break
}
}
}
let most = OttoMost()
let nastavenie = WKWebViewConfiguration()
nastavenie.userContentController.add(most, name: "ottoChat")
nastavenie.userContentController.addUserScript(WKUserScript(
source: "window.ottoUser = { name: 'Ján Novák', email: 'jan@example.sk' };",
injectionTime: .atDocumentStart, forMainFrameOnly: true))
let web = WKWebView(frame: .zero, configuration: nastavenie)
web.load(URLRequest(url: URL(string: "https://ottoai.sk/m/pk_vas_kluc?lang=cs")!))WKUserContentController si most drží silnou referencí. Když obrazovku zavíráte, zavolejte removeScriptMessageHandler(forName: "ottoChat").
React Native
import { WebView } from "react-native-webview";
import { Linking } from "react-native";
<WebView
source={{ uri: "https://ottoai.sk/m/pk_vas_kluc?lang=cs" }}
injectedJavaScriptBeforeContentLoaded={"window.ottoUser = { name: 'Ján Novák', email: 'jan@example.sk' }; true;"}
onMessage={(e) => {
const u = JSON.parse(e.nativeEvent.data);
if (u.type === "close") navigation.goBack();
if (u.type === "productClick" || u.type === "link") Linking.openURL(u.url);
}}
/>Flutter
final ovladac = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..addJavaScriptChannel('OttoChat', onMessageReceived: (sprava) {
final u = jsonDecode(sprava.message) as Map<String, dynamic>;
if (u['type'] == 'close') Navigator.of(context).pop();
if (u['type'] == 'productClick' || u['type'] == 'link') launchUrl(Uri.parse(u['url'] as String));
})
..loadRequest(Uri.parse('https://ottoai.sk/m/pk_vas_kluc?lang=cs'));webview_flutter neumí vložit skript před načtením stránky, přihlášeného zákazníka tu zatím nepředáte.
Soukromí a obchody s aplikacemi
- Apple od listopadu 2025 (pravidlo 5.1.2(i)) chce, aby aplikace před odesláním osobních údajů do AI třetí strany jasně řekla, co posílá, a získala souhlas. Pokud předáváte
window.ottoUser, zeptejte se zákazníka nejdřív. - Ve štítcích soukromí App Store a ve formuláři Data safety na Google Play uveďte zprávy chatu a údaje, které chatu předáváte.
- Chat žije na
ottoai.sk. Do cizího rámu (iframe) ho vložit nejde, ve webovém zobrazení aplikace ano.

