Интеграция в мобильных приложениях
Caputchin работает внутри нативного приложения через размещённую страницу встраивания. Ты наводишь WebView на эту страницу, посетитель проходит испытание внутри неё, и страница пробрасывает получившийся токен (и любую ошибку) обратно в твой нативный код. Сама проверка идентична веб-версии; различается только хост-оболочка.
1. Открой страницу встраивания
Наведи WebView на https://caputchin.com/embed хотя бы с ключом сайта:
https://caputchin.com/embed?sitekey=cpt_pub_...&game=caputchin/games/leaf-memoryОпусти параметры игры для простой галочки. Список games=a,b выбирает одну случайно на сессию.
Параметры запроса
| Параметр | Обязателен | Эффект |
|---|---|---|
sitekey | да | Твой публичный ключ (cpt_pub_...). Без него рендерится оболочка с ошибкой без виджета. |
game | нет | Один id игры из маркетплейса (owner/repo или owner/repo/leaf). |
games | нет | Список через запятую; одна выбирается случайно на сессию. |
game-src | нет | URL твоей собственной размещённой сборки игры, для самостоятельно размещённой игры. |
layout | нет | inline, modal, fullscreen или auto. По умолчанию inline на встраивании. |
locale / skin / config | нет | Пробрасываются в виджет для выбора языка, скина или конфигурации. |
no-verify | нет | Запускает игру без проверочных ворот (только игра, без токена). |
postMessageTarget | нет | Только для встраивающих в браузерный iframe (см. ниже). Игнорируется в нативном WebView. |
Опусти все три из game / games / game-src для простой галочки. Параметра mode нет; виджет сам управляет триггером.
2. Пробрось токен в свой код
Когда посетитель проходит, страница встраивания проталкивает токен через канал, подходящий твоему хосту. Зарегистрируй соответствующий обработчик.
iOS (WKWebView, Swift)
Токен приходит сырой строкой на обработчик сообщений с именем caputchin:
class TokenHandler: NSObject, WKScriptMessageHandler {
func userContentController(_ controller: WKUserContentController,
didReceive message: WKScriptMessage) {
guard let token = message.body as? String else { return }
// send `token` to your backend
}
}
let config = WKWebViewConfiguration()
config.userContentController.add(TokenHandler(), name: "caputchin")
let webView = WKWebView(frame: .zero, configuration: config)
webView.load(URLRequest(url: URL(string: "https://caputchin.com/embed?sitekey=cpt_pub_...&game=caputchin/games/leaf-memory")!))Android (WebView, Kotlin)
Токен приходит сырой строкой на @JavascriptInterface с именем caputchin:
class TokenBridge {
@JavascriptInterface
fun onToken(token: String) {
// send `token` to your backend
}
}
webView.settings.javaScriptEnabled = true
webView.addJavascriptInterface(TokenBridge(), "caputchin")
webView.loadUrl("https://caputchin.com/embed?sitekey=cpt_pub_...&game=caputchin/games/leaf-memory")React Native (react-native-webview)
Встраивание постит JSON-строку в единый канал React Native. Распарси её и ветвись по type:
<WebView
source={{ uri: "https://caputchin.com/embed?sitekey=cpt_pub_...&game=caputchin/games/leaf-memory" }}
onMessage={(e) => {
const msg = JSON.parse(e.nativeEvent.data);
if (msg.type === "caputchin-token") {
// send msg.token to your backend
} else if (msg.type === "caputchin-error") {
// msg.code, msg.message, msg.originalCode (optional)
}
}}
/>Браузерный iframe (postMessage)
Если ты встраиваешь страницу в браузерный <iframe>, а не в нативный WebView, ретрансляция к родителю по умолчанию выключена и срабатывает только когда ты явно включаешь её с точным целевым источником через ?postMessageTarget=<origin> (например postMessageTarget=https://app.example.com). Подстановочный знак (*), путь или что угодно, что не парсится в голую схему, хост и порт, отклоняется, так что одноразовый, привязанный к сайту токен никогда не вещается непроверенному родителю. Слушай на родителе и проверяй event.origin, прежде чем доверять сообщению:
window.addEventListener("message", (event) => {
if (event.origin !== "https://embed-host.example.com") return;
const msg = event.data;
if (msg.type === "caputchin-token") {
// msg.token
} else if (msg.type === "caputchin-error") {
// msg.code, msg.message
}
});3. Проверь на своём бэкенде
Это то же, что и в вебе: отправь POST с токеном на /siteverify со своим секретом. Смотри Серверную интеграцию.
Приём ошибок (опционально)
Всякий раз, когда виджет наталкивается на ошибку, страница встраивания зеркалит её через параллельный набор каналов: обработчик сообщений caputchinError под iOS, интерфейс caputchinError под Android (onError(json)), канал React Native как { type: "caputchin-error", ... } и та же огороженная ретрансляция iframe. Нагрузка несёт { code, message, originalCode? }. iOS и Android получают её как JSON-строку; React Native и ретрансляция iframe получают типизированный конверт.
Это полностью опционально. Приложение, не регистрирующее обработчик ошибок, просто не получает ошибки, а страница встраивания всё равно показывает UI повтора внутри WebView в любом случае.
См. также
- Серверная интеграция для проверки токена.
- Клиентская интеграция для веб-эквивалента.