Caputchin
أدلة التكامل

تكامل تطبيقات الجوّال

يعمل 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 على أي حال.

انظر أيضًا

في هذه الصفحة