> ## 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.

# نظرة عامة على الربط الاجتماعي

> كيف يربط مستخدموك حساباتهم الاجتماعية — الأسطح الثلاثة، وجلسة الربط الكامنة خلفها جميعًا، والخيارات المشتركة بينها.

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={false} />

يربط مستخدموك حساباتهم الاجتماعية بأنفسهم — فهم يصادقون مباشرةً مع كل شبكة، وأنت لا ترى
بيانات اعتمادهم ولا تخزنها أبدًا. كل ما في هذه الصفحة يدور حول إيصالهم إلى تلك اللحظة
ومعرفة كيف جرت.

ثمة أمر مشترك بين كل المسارات: **جلسة ربط (link session)**، تُنشأ عبر
[إنشاء Link Session](/docs/apis/profiles/create-link-session) من مفتاح API الخاص بك و`Profile-Key`.
لا يُوقَّع شيء من جانبك ولا يوجد مفتاح خاص في التدفق.

## ثلاث طرق للربط

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

| السطح                                                                                                                         | ما يراه مستخدمك                                                      | العلامة البيضاء                                             | اختره عندما                                                                                              |
| ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| **الأداة — إطارات مضمّنة** ([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>
  صفّا الأداة هما **تكامل واحد** لا اثنان. استدعاء `init` واحد يمنحك الاثنين معًا: ركّب الإطارات
  حيث تريد أزرارنا، واستدعِ `popup()` من زرك الخاص في أي مكان آخر. يتشاركان جلسة واحدة ويبلّغان
  على المعالجات نفسها.

  [الوضع المباشر (Direct mode)](/docs/multiple-users/connect-direct-mode) هو النافذة المنبثقة نفسها
  **دون** السكربت الخاص بنا — لصفحة ذات Content-Security-Policy صارمة، أو صفحة تُعرض من الخادم،
  أو تطبيق أصلي. هناك تفتح النافذة المنبثقة وتراقبها بنفسك.

  **غير متأكد؟** ابدأ بصفحة الربط المستضافة. فهي لا تحتاج إلى Max Pack ولا إلى معاملات إضافية،
  وهي أسرع طريق إلى شيء يعمل — والانتقال إلى الأداة لاحقًا لا يغيّر طريقة إنشاء الجلسات.
</Note>

## إنشاء رابط

استدعِ [إنشاء Link Session](/docs/apis/profiles/create-link-session) مع تمرير `Profile-Key` الخاص
بالمستخدم في الترويسة. بالنسبة للصفحة المستضافة، هذا هو الطلب بأكمله:

```bash cURL theme={"system"}
curl -X POST https://api.ayrshare.com/api/profiles/link-sessions \
  -H "Authorization: Bearer $AYRSHARE_API_KEY" \
  -H "Profile-Key: $PROFILE_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

يُعاد إليك `url` يحمل رمزًا معتّمًا قصير الأجل:

```javascript Linking URL theme={"system"}
https://profile.ayrshare.com?session=ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu&domain=YOUR_DOMAIN
```

يمكنك أيضًا [التحقق مما إذا كان رابط قد فُتح](/docs/apis/profiles/get-link-session)
و[إبطاله](/docs/apis/profiles/revoke-link-session) قبل انتهاء صلاحيته.

<Note>
  فيديو مدته دقيقة واحدة يوضّح كيفية إنشاء رابط. سُجّل قبل Link Sessions، لذا لا يزال يُظهر إرسال
  Private Key — لم تُعد هذه الخطوة لازمة، وكل ما عداه في الفيديو لم يتغيّر.

  <div class="video-container">
    <iframe width="380" height="200" src="https://www.youtube.com/embed/JI232HBWHWc" title="Create a linking URL" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" />
  </div>
</Note>

<h3 id="sending-the-linking-url">
  إرسال رابط الربط
</h3>

<Warning>
  يُسجّل رابط الربط دخول مستخدمك إلى ملفه، لذا تعامل معه كما تتعامل مع كلمة المرور. أرسله عبر قناة
  تثق بها، ولا تُدرجه في السجلات، ولا تُمرّره إلى طرف ثالث. ويظل صالحًا للاستخدام خلال نافذته
  الزمنية بأكملها، لذا يعمل إعادة التحميل أو إعادة محاولة OAuth — لكن أرسل كل رابط إلى مستخدم
  واحد فقط، وأنشئ رابطًا منفصلًا لكل شخص.
</Warning>

### فتح رابط الربط

افتحه في علامة تبويب متصفح جديدة أو نافذة جديدة أو View Controller. يمكنك التحكم في
[إغلاق أو إعادة توجيه](/docs/multiple-users/api-integration-business#opening-and-closing-the-social-linking-url)
تلك النافذة.

<Note>
  لا تسمح الشبكات الاجتماعية بفتح صفحة الربط المستضافة داخل iFrame، ولا بإخفاء نطاق أصل الشريك
  المعتمد `profile.ayrshare.com`. إذا أردت أن يجري الربط داخل صفحتك أنت، فذلك هو دور
  [الأداة المضمّنة](/docs/multiple-users/connect-widget): تُقدَّم إطاراتها من أصل تابع لـ Ayrshare
  وهي الطريقة المدعومة للقيام بذلك.
</Note>

### معرفة اكتمال الربط

إشارتان، ويمكنك استخدام أيٍّ منهما:

* **[أحداث اكتمال الربط](/docs/multiple-users/link-completion-events)** — عيّن `origin` عند إنشاء
  الرابط فترسل نافذة الربط `connect:success` و`connect:error` و`connect:cancelled` إلى صفحتك
  لحظة وقوعها. دون استطلاع.
* **[الحصول على Link Session](/docs/apis/profiles/get-link-session)** — يُبلغ عن `completedAt`
  و`lastCompletedAt` و`completedNetworks`. هذه هي إشارة التطبيقات الأصلية، والوحيدة لـ
  Telegram، الذي يكتمل خارج النطاق.

<h2 id="jwt-expires-in">
  انتهاء صلاحية الرابط
</h2>

الرابط صالح لمدة **5 دقائق** افتراضيًا. بعد ذلك، أنشئ رابطًا جديدًا.

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

مع Max Pack، اضبط `expiresIn` بالدقائق لتوسيع تلك النافذة — حتى **2880 دقيقة (48 ساعة)**، وهو
الحد الأقصى الذي تقبله API:

```json Expires In theme={"system"}
{
  "expiresIn": 30
}
```

النافذة الأطول هي ما يجعل [إرسال الرابط بالبريد الإلكتروني](#connect-accounts-email) عمليًا —
فالمستخدم الذي يعيد ربط حساب انقطع يمكنه الانتقال مباشرةً من بريدك الإلكتروني إلى الشبكة، دون
زيارة تطبيقك أولًا.

<Warning>
  راجع مع فريق الأمان لديك المدة التي ينبغي أن يظل الرابط فيها صالحًا. النافذة الأطول تعني فترة
  أطول يظل فيها الرابط المُعترَض صالحًا للعمل. وإذا تسرّب رابط، يمكنك
  [إبطاله](/docs/apis/profiles/revoke-link-session) بدلًا من انتظار انتهاء صلاحيته.
</Warning>

## Profile Key

يحدّد `Profile-Key` أي User Profile يخصّه الرابط. يمكنك العثور عليه في لوحة مطوّري Ayrshare
بالتبديل إلى ذلك الملف.

<Note>
  **لم تُعد Private Key مستخدمة.** الروابط غير موقّعة، لذا لا يوجد ما يُقرأ من ملف أو يُلصق في
  التعليمات البرمجية. ولا يزال المعامل القديم `privateKey` يُقبل ويُتجاهل، لذا تستمر عمليات
  التكامل الحالية في العمل، ويمكن ترك ملف `private.key` في Integration Package دون استخدام.
</Note>

## التبديل بين الملفات الشخصية

إذا كان ملف شخصي مُسجَّل الدخول بالفعل، فإن فتح رابط ملف آخر لا يبدّل الملفات — وهذا مقصود،
فهو يجعل التجربة أسرع للمستخدم الموجود هناك بالفعل. لفرض التبديل، راجع
[تسجيل الخروج التلقائي من جلسة الملف الشخصي](/docs/multiple-users/api-integration-business#automatic-logout-of-a-profile-session).

<h2 id="instagram-link-method">
  طريقة ربط Instagram
</h2>

يمكن ربط حسابات Instagram بـ [طريقتين](/docs/dashboard/connect-social-accounts/instagram): مباشرة عبر
**Instagram Login**، أو عبر **Facebook Page متصلة**. يتحكم في التدفق الذي يبدأ عند نقر المستخدم
على زر Instagram عادةً إعداد [Instagram Login](/docs/multiple-users/manage-user-profiles#instagram-login)
على مستوى الحساب.

يتجاوز معامل الجسم `instagramLinkMethod` هذا الإعداد لرابط واحد:

| القيمة      | تدفق ربط Instagram                                     |
| ----------- | ------------------------------------------------------ |
| `instagram` | تسجيل دخول مباشر إلى Instagram. لا يلزم Facebook Page. |
| `facebook`  | الربط عبر Facebook Page متصلة.                         |

```json Instagram Link Method theme={"system"}
{
  "instagramLinkMethod": "instagram"
}
```

يسري التجاوز طوال عمر ذلك الرابط، بما في ذلك عبر إعادة توجيه التفويض في Instagram/Facebook.
بعض الأمور التي يجب معرفتها:

* لا يغيّر إعدادك على مستوى الحساب ولا يؤثر على أي رابط آخر.
* إذا حُذف، يسري الإعداد على مستوى الحساب، تمامًا كما كان من قبل.
* تعيد القيمة غير الصالحة `400` مع سرد القيم الصالحة (`instagram`، `facebook`).
* راجع
  [اختلافات الميزات](/docs/multiple-users/manage-user-profiles#direct-instagram-login-vs-facebook-page-authentication)
  قبل الاختيار — بعض ميزات Instagram، مثل البحث عن الوسوم والتعاون، متاحة فقط مع مصادقة
  Facebook Page.

<h2 id="connect-accounts-email">
  بريد Connect Accounts
</h2>

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

يمكن لـ Ayrshare إرسال الرابط بالبريد الإلكتروني إلى مستخدمك نيابةً عنك، ليتمكن من الوصول إلى
صفحة الربط الخاصة به دون زيارة تطبيقك. اقرنه بقيمة [`expiresIn`](#jwt-expires-in) أطول —
فالدقائق الخمس الافتراضية نادرًا ما تصمد أمام صندوق وارد.

### JSON لربط الحسابات

**كل حقل داخل `email` مطلوب.** أي حقل مفقود يُفشل الإرسال.

```json Example Contact Email Request theme={"system"}
{
  "expiresIn": 60,
  "email": {
    "to": "john@user.com",
    "contactEmail": "support@mycompany.com",
    "company": "ACME",
    "termsUrl": "https://www.ayrshare.com/terms",
    "privacyUrl": "https://www.ayrshare.com/privacy"
  }
}
```

<Warning>
  `expiresIn` معامل من **المستوى الأعلى**، وليس جزءًا من كائن `email`. إذا وُضع داخل `email`
  يُتجاهل، ويحصل مستخدمك على رابط تنتهي صلاحيته خلال خمس دقائق.
</Warning>

تُبلّغ الاستجابة عن النتيجة في `emailSent`:

```json Example Contact Email Response theme={"system"}
{
  "status": "success",
  "sessionId": "c7a2434e72e91bde27579efde0fd6dd0b74ceee29a471fd368407f273708c2e8",
  "url": "https://profile.ayrshare.com?session=ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu&domain=YOUR_DOMAIN",
  "expiresAt": "2026-09-02T09:03:26.838Z",
  "emailSent": true,
  "title": "Acme Client"
}
```

**فشل** الإرسال لا يُعاد على شكل `emailSent: false` — بل يعيد `code: 333` بدلًا من ذلك. لذا فإن
`false` تعني أنه لم يُطلب أي بريد إلكتروني.

### مثال بريد Connect Accounts

فيما يلي مثال على البريد الإلكتروني الذي يفتح صفحة الربط الاجتماعي:

<img src="https://mintcdn.com/ayrshare-docs/Nmrhj2Gh7WSf62Bh/images/apis/profiles/jwt-email.webp?fit=max&auto=format&n=Nmrhj2Gh7WSf62Bh&q=85&s=fbe4ee86ca59c26a5bd5b289fda96b8b" alt="Connect Accounts email" width="563" class="center" data-path="images/apis/profiles/jwt-email.webp" />

يأتي البريد الإلكتروني من العنوان:

`Social Connect Hub <connect@socialconnecthub.com>`

<h2 id="mobile-jwt">
  تطبيقات الأجهزة المحمولة
</h2>

افتح رابط الربط في **متصفح النظام**، وليس أبدًا في webview مضمّن: يرفض Google تسجيل الدخول
فيه بالخطأ `disallowed_useragent`، وتحجبه Meta كليًا. سيرى مستخدمك صفحة الخطأ الخاصة بالشبكة
نفسها، ولا شيء من جانبك يصلح ذلك.

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

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

<h3 id="mobile-code-examples">
  أمثلة التعليمات البرمجية للأجهزة المحمولة
</h3>

استبدل `linkingURL` بقيمة `url` المُعادة من
[إنشاء Link Session](/docs/apis/profiles/create-link-session).

<CodeGroup>
  ```swift Swift theme={"system"}
  import UIKit
  import SafariServices

  class ViewController: UIViewController, SFSafariViewControllerDelegate {

      var linkingURL = "https://profile.ayrshare.com?session=ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu&domain=acme"

      override func viewDidLoad() {
          super.viewDidLoad()
          setupButton()
      }

      func setupButton() {
          let button = UIButton(type: .system)
          button.frame = CGRect(x: (view.bounds.width - 200) / 2, y: (view.bounds.height - 50) / 2, width: 200, height: 50)
          button.setTitle("Open URL", for: .normal)
          button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
          view.addSubview(button)
      }

      @objc func buttonTapped() {
          openURLInInAppBrowser()
      }

      func openURLInInAppBrowser() {
          if let url = URL(string: linkingURL) {
              let safariVC = SFSafariViewController(url: url)
              safariVC.delegate = self
              present(safariVC, animated: true, completion: nil)
          }
      }

      // Optional: If you want to handle when the in-app browser is closed
      func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
          controller.dismiss(animated: true, completion: nil)
      }
  }
  ```

  ```dart Flutter theme={"system"}
  /** yaml dependencies
    dependencies:
      flutter:
        sdk: flutter
      url_launcher: ^6.2.1
  */

  import 'package:flutter/material.dart';
  import 'package:url_launcher/url_launcher.dart';

  void main() {
    runApp(MyApp());
  }

  class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'URL Launcher Example',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: MyHomePage(),
      );
    }
  }

  class MyHomePage extends StatelessWidget {
    final String linkingURL = "https://profile.ayrshare.com?session=ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu&domain=acme";

    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: Text('URL Launcher Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              openURLInBrowser(context);
            },
            child: Text('Open URL'),
          ),
        ),
      );
    }

    void openURLInBrowser(BuildContext context) async {
      if (await canLaunch(linkingURL)) {
        await launch(linkingURL);
      } else {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Could not launch $linkingURL'),
          ),
        );
      }
    }
  }
  ```

  ```jsx React Native theme={"system"}
  /**
  • Using the API provided by expo-web-browser,
  • which opens a URL in a modal browser window that shares cookies
  • with the system browser.

  • Learn more about expo: https://reactnative.dev/docs/environment-setup?guide=quickstart
  • and running the following command:
  • expo install expo-web-browser
  */

  import React from 'react';
  import { StyleSheet, Button, View } from 'react-native';
  import * as WebBrowser from 'expo-web-browser';

  export default function App() {
    const linkingURL = 'https://profile.ayrshare.com?session=ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu&domain=acme';

    const openURLInBrowser = async () => {
      try {
        await WebBrowser.openBrowserAsync(linkingURL);
        // Optional: WebBrowser.openBrowserAsync returns a promise that resolves with an object containing
        // 'type' that can be 'cancelled' or 'dismissed'. You can use this to handle when the browser is closed.
      } catch (error) {
        console.error(error);
      }
    };

    return (
      <View style={styles.container}>
        <Button title="Open URL" onPress={openURLInBrowser} />
      </View>
    );
  }

  const styles = StyleSheet.create({
    container: {
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center',
    },
  });
  ```
</CodeGroup>

## الاختبار

**يوصى** أولًا بإنشاء رابط في [Postman](/docs/testing/postman). يتضمّن Integration Package الخاص بك
— المتوفر في صفحة API Key الخاصة بـ Primary Profile في لوحة التحكم — ملف إعداد Postman
نموذجيًا. استورده، واملأ Profile Key الخاص بك في حقل *body* الخاص بـ `profileKey`، وانقر على
*Send*.

لا يزال الإعداد النموذجي يملأ `privateKey` و`domain` مسبقًا. يُتجاهل `privateKey`، ويمكنك إفراغ
`domain` إلا إذا كان لحسابك أكثر من نطاق ربط واحد.

يمكنك أيضًا [توليد التعليمات البرمجية من Postman](/docs/testing/postman#auto-generate-api-code-with-postman).

### Bubble.io

<Card title="Bubble linking URL" icon="link" href="/docs/packages-guides/bubble#generate-a-linking-url-in-bubble" horizontal />

## القديم: generateJWT

<Info>
  تنفّذ [إنشاء رابط ربط](/docs/apis/profiles/generate-jwt) (`generateJWT`) المهمة نفسها وهي
  **مهملة (deprecated)** — مدعومة بالكامل، وبلا موعد للإزالة، ودون تغيير للروابط التي سلّمتها
  بالفعل. توثّق صفحتها الخاصة معاملاتها، بما في ذلك المعاملات الثلاثة التي باتت تُقبل الآن
  وتُتجاهل.

  تستخدم نقطتا النهاية المُحقِّق نفسه، لذا فإن كل ما في هذه الصفحة ينطبق على أيٍّ منهما. الفرق
  الوحيد الجدير بالمعرفة عند الانتقال: يتسامح `generateJWT` مع ثلاثة أمور ترفضها إنشاء Link
  Session — شبكة غير معروفة في `allowedSocial`، ونصف واحد فقط من بيانات اعتماد X، و`redirect`
  غير نصي.
</Info>
