> ## Documentation Index
> Fetch the complete documentation index at: https://www.ayrshare.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# ابنِ نافذة الربط المنبثقة الخاصة بك

> الوضع المباشر (Direct Mode) — اربط شبكة واحدة في كل مرة من زرك الخاص، بنافذة منبثقة تفتحها وتراقبها بنفسك.

export const PlansAvailable = ({plans = [], maxPackRequired}) => {
  let displayPlans = plans;
  if (plans && plans.length === 1) {
    const lowerCasePlan = plans[0].toLowerCase();
    if (lowerCasePlan === "business") {
      displayPlans = ["Launch", "Business", "Enterprise"];
    } else if (lowerCasePlan === "premium") {
      displayPlans = ["Premium", "Launch", "Business", "Enterprise"];
    }
  }
  return <Note>
Available on {displayPlans.length === 1 ? "the " : ""}
{displayPlans.join(", ").replace(/\b\w/g, l => l.toUpperCase())}{" "}
{displayPlans.length > 1 ? "plans" : "plan"}.

{maxPackRequired && <span onClick={() => window.open('https://www.ayrshare.com/docs/additional/maxpack', '_self')} className="flex items-center mt-2 cursor-pointer">
 <span className="px-1.5 py-0.5 rounded text-sm" style={{
    backgroundColor: '#C264B6',
    color: 'white',
    fontSize: '12px'
  }}>
   Max Pack required
 </span>
</span>}
</Note>;
};

<PlansAvailable plans={["business"]} maxPackRequired={true} />

يربط الوضع المباشر (Direct Mode) **شبكة اجتماعية واحدة في كل مرة**، من زر في لوحة التحكم
الخاصة بك. تُنشئ جلسة ربط لتلك الشبكة، وتفتح عنوان URL الذي تعيده في نافذة منبثقة، وتسمع
صفحتك ما حدث. مستخدمك لا يرى أبدًا صفحة تسرد كل الشبكات، ولا يغادر تطبيقك لمدة أطول مما
يستغرقه تسجيل دخول الشبكة نفسها.

## أي سطح تريد

ثلاثة أشكال، والأول والثاني هما التكامل نفسه. هذه الصفحة هي التي تبنيها بنفسك.

| السطح                                                                                                                         | ما يراه مستخدمك                                                      | العلامة البيضاء                                             | اختره عندما                                                                                              |
| ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| **الأداة — إطارات مضمّنة** ([mount](/docs/multiple-users/connect-widget#mount-a-slot))                                             | أزرارنا مدمجة في تخطيط صفحتك؛ لا نافذة منبثقة حتى نافذة الشبكة نفسها | **الأقوى.** صفحتك وخطوطك وألوانك، ومستخدمك لا يغادرها أبدًا | لديك لوحة تحكم فيها صف لكل شبكة وتريد أن يجري الربط في مكانه. يتطلب Max Pack.                            |
| **الأداة — زرك الخاص** ([popup](/docs/multiple-users/connect-widget#your-own-button))                                              | زرك، ثم نافذة منبثقة واحدة للشبكة                                    | **قوي.** النافذة المنبثقة نافذتنا، لكنها وجيزة وترث مظهرك   | تريد زرك وتنسيقك الخاصين، ولا إطارات في تخطيطك. يتطلب Max Pack.                                          |
| **صفحة الربط المستضافة** ([كيفية الاستخدام](/docs/multiple-users/api-integration-business#single-sign-on-with-jwt-authentication)) | صفحة نستضيفها نحن، تحمل شعارك وألوانك وCSS المخصص الخاص بك           | **الأضعف.** إنها صفحتنا، ويغادر مستخدمك صفحتك لاستخدامها    | تريد رابطًا واحدًا لتوزيعه، أو تجري التأهيل عبر البريد الإلكتروني. لا شيء لبنائه، ولا حاجة إلى Max Pack. |

<Note>
  **الوضع المباشر هو النافذة المنبثقة في الصف الثالث دون السكربت الخاص بنا.** إذا كانت صفحتك
  تستطيع تحميل السكربت، فإن [الأداة](/docs/multiple-users/connect-widget) تنجز عنك كل ما في هذه
  الصفحة — فهي تفتح النافذة المنبثقة وتراقبها بنفسها، وتستطيع تضمين الإطارات أيضًا. الوضع
  المباشر هو ما تريده عندما يتعذر على صفحتك تحميل سكربت من طرف ثالث، أو عندما يكون السطح
  تطبيقًا أصليًا لا متصفحًا.
</Note>

<Frame caption="زرك، صفحتك. النافذة المنبثقة هي الشيء الوحيد الذي يراه مستخدمك من عندنا، وللمدة التي تحتاجها الشبكة فقط.">
  <img src="https://mintcdn.com/ayrshare-docs/-2tpx3mFy9vWIObd/images/multiple-users/connect-widget-popup.webp?fit=max&auto=format&n=-2tpx3mFy9vWIObd&q=85&s=b68021d477703d97a5994ee85d299be6" alt="A customer dashboard with its own Connect buttons and an Ayrshare popup showing the Facebook hand-off screen" width="2880" height="1317" data-path="images/multiple-users/connect-widget-popup.webp" />
</Frame>

## ما الذي تبنيه

أربع خطوات. الأولى على خادمك، والباقي في صفحتك.

<Steps>
  <Step title="أنشئ جلسة لشبكة واحدة">
    من خادمك الخلفي، استدعِ
    [إنشاء Link Session](/docs/apis/profiles/create-link-session) مع `mode: "connect"`
    و`network` و`origin` الذي تعمل عليه صفحتك.

    ```javascript Your backend theme={"system"}
    const response = await fetch("https://api.ayrshare.com/api/profiles/link-sessions", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${process.env.AYRSHARE_API_KEY}`,
        "Profile-Key": profileKey,
      },
      body: JSON.stringify({
        mode: "connect",
        network: "reddit",
        origin: "https://app.example.com",
      }),
    });

    const { url } = await response.json();
    ```

    يُعاد إليك `url` يشير إلى صفحة ربط لشبكة واحدة، ولا `token` — فالتوكن داخل عنوان URL.
    تعامل مع عنوان URL بأكمله كما تتعامل مع كلمة المرور: فهو يُسجّل دخول مستخدمك إلى User
    Profile الخاص به.

    <Warning>
      أنشئ الجلسة على خادمك، وليس في المتصفح أبدًا. الاستدعاء يحتاج إلى مفتاح API الخاص بك.
    </Warning>
  </Step>

  <Step title="افتحه في معالج النقر، بشكل متزامن">
    يجب أن تُفتح النافذة المنبثقة بـ `window.open` **داخل معالج النقر نفسه**. لا يسمح المتصفح
    بنافذة منبثقة إلا وهو لا يزال يعالج نقرة مستخدمك، وهذا الإذن لا ينجو من `await` — لذا فإن
    جلب عنوان URL أولًا ثم فتحه في الاستدعاء الراجع (callback) يُحجب حجبًا شبه مؤكد.

    اجلب عنوان URL عند عرض الزر، أو عندما يمرّر مستخدمك المؤشر فوقه. بحلول وقت النقر ينبغي أن
    يكون لديك بالفعل.

    ```javascript Your page theme={"system"}
    // `url` was fetched earlier. Nothing async between the click and window.open.
    button.addEventListener("click", () => {
      const popup = window.open(url, "ayrshare-connect", "width=600,height=800");
      if (!popup) {
        showError("Allow popups for this site to connect an account.");
        return;
      }
      listenForOutcome(popup, url);
    });
    ```
  </Step>

  <Step title="استمع إلى النتيجة">
    لأنك مرّرت `origin`، ترسل النافذة المنبثقة حدثًا إلى صفحتك عن كل ما يقع فيها:
    `connect:success` و`connect:error` و`connect:cancelled`، وأحداث تقدّم بينها. يصل واحد
    بالضبط من تلك الثلاثة لكل عملية ربط.

    تحوي [أحداث اكتمال الربط](/docs/multiple-users/link-completion-events) جدول الأحداث الكامل
    ومستمعًا جاهزًا للنسخ واللصق — `listenForOutcome` أعلاه هو ذلك المقتطف. جزآن منه يسهل
    إغفالهما وكلاهما يسبب أخطاء حقيقية:

    * **تحقق من `event.origin`** مقابل أصل عنوان URL الذي فتحته. يمكن لأي صفحة إرسال رسالة
      إلى نافذتك، والأصل هو الجزء الوحيد من الرسالة الذي لا يمكن تزويره.
    * **استطلع `popup.closed`**، مع مهلة سماح قصيرة قبل أن تستنتج أي شيء. النافذة المنبثقة
      التي أغلقها مستخدمك يدويًا لا ترسل شيئًا إطلاقًا، ومن دون مهلة السماح قد يُبلَّغ عن ربط
      ناجح على أنه إلغاء.
  </Step>

  <Step title="عالج كل نهاية">
    | النهاية             | معناها                                                                           | ما ينبغي فعله                                                                                            |
    | ------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
    | `connect:success`   | الحساب متصل **ومحفوظ**                                                           | حدّث ذلك الصف. استدعاء [`GET /user`](/docs/apis/user/profile-details) بعده مباشرةً يُظهره بالفعل.             |
    | `connect:error`     | فشل الربط                                                                        | اعرض `message`. يكون `code` حاضرًا عندما يكون للفشل رمز مفهرس وغائبًا عندما لا يكون.                     |
    | `connect:cancelled` | تراجع مستخدمك، أو أغلق النافذة                                                   | اترك الصف كما كان. `reason` هي `popupClosed` أو `scopesDenied` أو `userCancelled`.                       |
    | لا شيء يصل          | الرابط منتهي الصلاحية أو مُبطل أو مجهول، فلم تعرف الصفحة قط إلى أين ترسل الأحداث | استطلع [الحصول على Link Session](/docs/apis/profiles/get-link-session)، الذي يبلّغ عن تلك الحالات بشكل موثوق. |
  </Step>
</Steps>

<Tip>
  أضف `&autoClose=false` إلى عنوان URL أثناء البناء. تبقى النافذة المنبثقة عندئذٍ مفتوحة بعد كل
  نتيجة بدلًا من أن تُغلق نفسها، فتستطيع قراءة ما تقوله.
</Tip>

## ملاحظات لكل شبكة

معظم الشبكات نافذة منبثقة واحدة ولا شيء غيرها: ينقر مستخدمك، ويفوّض عند الشبكة، وتُغلق
النافذة. هذه هي الاستثناءات الجديرة بالمعرفة قبل البناء.

<AccordionGroup>
  <Accordion title="X تتطلب مفاتيح API الخاصة بك">
    تستخدم X في الوضع المباشر بيانات اعتماد تطبيق X Developer **الخاص بك**، المزوَّدة عند
    إنشاء الجلسة عبر الترويستين `X-Twitter-OAuth1-Api-Key` و`X-Twitter-OAuth1-Api-Secret` على
    [إنشاء Link Session](/docs/apis/profiles/create-link-session).

    الجلسة المُنشأة لـ `twitter` أو `x` **بدون** هاتين الترويستين تُرفض عند فتح النافذة
    المنبثقة: يُخبَر مستخدمك بأن الاتصال غير متاح ولا يُعرض له أي نموذج، وتتلقى صفحتك
    `connect:error` مع `message` و**بدون `code`**. وهذا مقصود. فبيانات الاعتماد المفقودة
    خاصتك، لا خاصة مستخدمك، ويجب ألا يُطلب من المستخدمين النهائيين إدخال مفاتيح API الخاصة بك
    أبدًا.

    قارن ذلك بـ Bluesky، حيث كلمة مرور التطبيق هي بيانات اعتماد المستخدم النهائي نفسه — تلك
    تجمعها صفحة الربط فعلًا، في نموذج داخل النافذة المنبثقة.
  </Accordion>

  <Accordion title="Facebook يعرض زرًا واحدًا قبل تسجيل دخول Meta">
    يعرض `network: "facebook"` زرًا واحدًا في النافذة المنبثقة، ويفتح تسجيل دخول Meta نفسه من
    تلك النقرة — إذ تشترط Meta أن يبدأ تسجيل دخولها بنقرة داخل الصفحة التي تستضيف SDK الخاص
    بها. ينقر مستخدمك مرتين بدلًا من مرة؛ ولا شيء آخر يختلف.

    يتصرف Instagram بالطريقة نفسها عندما يُربط **عبر Facebook Page** — أي عندما تحمل الجلسة
    `instagramLinkMethod: "facebook"`، أو عندما يختار إعداد
    [Instagram Login](/docs/multiple-users/manage-user-profiles#instagram-login) في حسابك ذلك
    التدفق. أما مع تسجيل دخول Instagram المباشر فلا زر إضافي.
  </Accordion>

  <Accordion title="Bluesky وTelegram يعرضان محتوى صفحة، لا إعادة توجيه">
    لا يرسل أي منهما مستخدمك إلى تسجيل دخول شبكة. تعرض النافذة المنبثقة محتوى بدلًا من ذلك:
    نموذج معرّف (handle) وكلمة مرور تطبيق لـ Bluesky، ورمز يُستخدم لـ Telegram. أحداث النتيجة
    هي نفسها في الحالتين.

    لا تنتمي X إلى هذه المجموعة. فمع مفاتيحك على الجلسة تكتمل دون مطالبة مستخدمك بأي شيء،
    وبدونها تُرفض — راجع أعلاه.
  </Accordion>

  <Accordion title="Telegram يكتمل خارج النطاق">
    يعرض Telegram رمزًا بدلًا من إعادة التوجيه إلى أي مكان، ويكتمل الاتصال عندما يستخدم
    مستخدمك ذلك الرمز — بعد زوال النافذة المنبثقة. لا يوجد حدث متصفح تنتظره، لذا استطلع
    [الحصول على Link Session](/docs/apis/profiles/get-link-session) وراقب `completedNetworks`.
  </Accordion>

  <Accordion title="لا يمكن ربط Facebook Groups بهذه الطريقة">
    ليست Facebook Groups هدف ربط، لذا يعيد `network: "fbg"` الرمز `code: 508` عند إنشاء
    الجلسة.

    أما WhatsApp **فمتاح** في الوضع المباشر. يفتح Embedded Signup من Meta في النافذة
    المنبثقة، وأحداث النتيجة هي نفسها كأي شبكة أخرى.
  </Accordion>
</AccordionGroup>

## التطبيقات الأصلية

يفتح التطبيق الأصلي `url` نفسه، في **متصفح النظام**، ويعرف النتيجة باستطلاع
[الحصول على Link Session](/docs/apis/profiles/get-link-session). عيّن `origin` على مخططك المخصص
(`myapp://connected`) حتى يكون للصفحة طريق عودة إلى تطبيقك؛ المخطط المخصص لا يمكنه تلقّي
الأحداث، لأنه لا توجد نافذة متصفح تُرسل إليها.

* **iOS** — ‏`ASWebAuthenticationSession`، أو `SFSafariViewController`.
* **Android** — ‏Chrome Custom Tabs.

<Warning>
  **لا تفتح رابط ربط أبدًا في webview مضمّن** (`WKWebView` أو `UIWebView` أو `WebView` في
  Android). ترفض الشبكات الاجتماعية المصادقة فيه: يرفض Google تسجيل الدخول بالخطأ
  `disallowed_useragent`، وتحجبه Meta كليًا. يرى مستخدمك صفحة الخطأ الخاصة بالشبكة نفسها، لا
  صفحتنا، ولا شيء يمكنك تغييره من جانبك يصلح ذلك. مكوّنات متصفح النظام أعلاه موجودة لهذا
  السبب بالضبط وتُبقي المستخدم داخل تطبيقك.
</Warning>

## ما يتطلبه الوضع المباشر

<ul className="custom-bullets">
  <li>
    **[Max Pack](/docs/additional/maxpack)**. إنشاء جلسة بوضع connect من دونه يعيد `code: 504`،
    أيًّا كان ما يقوله الطلب غير ذلك.
  </li>

  <li>
    **`origin`** على كل جلسة. لا توجد قائمة سماح ولا خطوة تسجيل — ترسله مع كل استدعاء. حذفه
    يعيد `code: 505`؛ والقيمة التي ليست أصل `https` أو مخططًا مخصصًا أو `http://localhost`
    تعيد `code: 506`.
  </li>

  <li>
    **`network`** فعّلها حسابك. الاسم غير المعروف يعيد `code: 508`؛ والاسم المعروف الذي لم
    يفعّله حسابك يعيد `code: 509`، وهو ما يمكنك إصلاحه في صفحة
    [Social Networks](/docs/multiple-users/manage-user-profiles#set-social-networks-access).
  </li>

  <li>
    **ليس** `allowedSocial`. لا يمكن جمعه مع `network` (يعيد `code: 507`) — فجلسة الشبكة
    الواحدة هي قائمة السماح الخاصة بها بالفعل.
  </li>
</ul>

كل واحد من هذه الرموز موجود في مرجع
[أخطاء Link Session](/docs/errors/errors-ayrshare#link-session-errors)، مع الرسالة التي تعيدها API.

## الخطوات التالية

<Card title="Link Completion Events" icon="tower-broadcast" href="/docs/multiple-users/link-completion-events" horizontal>
  كل حدث ترسله النافذة المنبثقة، والمستمع الذي يتلقاها.
</Card>

## ذات صلة

<Card title="Create a Link Session" icon="link" href="/docs/apis/profiles/create-link-session#connect-mode" horizontal>
  معاملات `mode` و`origin` و`network`، وأشكال الاستجابة.
</Card>

<Card title="Get a Link Session" icon="magnifying-glass" href="/docs/apis/profiles/get-link-session" horizontal>
  استطلع الاكتمال عندما يتعذر عليك استخدام نافذة منبثقة.
</Card>
