تكامل تطبيقات الجوّال
يعمل 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 | لا | معرّف لعبة متجر واحدة (owner/repo، أو owner/repo/leaf). |
games | لا | قائمة مفصولة بفواصل؛ تُختار واحدة عشوائيًّا لكل جلسة. |
game-src | لا | رابط حزمة لعبتك المُستضافة الخاصة، للّعبة المستضافة ذاتيًّا. |
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 مع سرّك. انظر التكامل على جانب الخادم.
استقبال الأخطاء (اختياري)
كلّما واجهت الأداة خطأ، تعكسه صفحة التضمين عبر مجموعة موازية من القنوات: معالِج رسائل iOS caputchinError، وواجهة Android caputchinError (onError(json))، وقناة React Native كـ { type: "caputchin-error", ... }، ومُرحِّل iframe المحكوم نفسه. تحمل الحمولة { code, message, originalCode? }. يستقبلها iOS وAndroid كسلسلة JSON؛ ويستقبل React Native ومُرحِّل iframe المغلّف المكتوب الأنواع.
هذا اختياري بالكامل. التطبيق الذي لا يسجّل معالِج أخطاء ببساطة لا يستقبل الأخطاء، وصفحة التضمين تعرض أصلًا واجهة إعادة محاولة داخل WebView على أي حال.
انظر أيضًا
- التكامل على جانب الخادم لفحص الرمز.
- التكامل على جانب العميل لِما يعادله في الويب.