
# واجهة برمجة تطبيقات (API) توصيل القنوات

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

هناك نمط واحد يجب أن تفهمه مسبقاً، لأنه ينطبق على كل قناة تقريباً هنا.

## نمط التوصيل ثم الاستطلاع (connect-then-poll)

لا يمكن توصيل معظم القنوات من خلال طلب API واحد. توصيل WhatsApp أو Instagram أو Messenger يعني أنه يجب على صاحب الحساب تسجيل الدخول إلى حساب مزود الخدمة الخاص به والموافقة على الوصول. **لا يوجد مسار غير مرئي (مؤتمت بالكامل)** لهذا الاعتماد - يجب على شخص حقيقي فتح رابط URL في متصفح، أو مسح رمز QR بهاتفه.

لذا فإن سير العمل يكون دائماً كالتالي:

1. **بدء الاتصال** باستخدام `POST`. تمنحك الاستجابة إما رابط URL لفتحه، أو رمز QR لعرضه.
2. **تسليم ذلك للمستخدم النهائي** - افتح الرابط في متصفحه، أو اعرض رمز QR على الشاشة ليقوم بمسحه.
3. **استطلاع نقطة نهاية الحالة** باستخدام `GET` على فترات قصيرة (كل بضع ثوانٍ) حتى تصل الحالة إلى حالة الاتصال.

تتمثل مهمة تكاملك في إدارة هذه الحلقة: عرض الرابط أو رمز QR، ثم الاستطلاع حتى الانتهاء. خطط لواجهة المستخدم الخاصة بك حول الاستطلاع - مؤشر تحميل مع رسالة "في انتظار انتهائك من المتصفح" يعمل بشكل جيد.

::: note
**ملاحظة:** قبل البدء، تأكد من تمكين الوصول إلى واجهة برمجة التطبيقات (API) في خطتك وأن لديك مفتاح API. راجع [الوصول إلى واجهة برمجة التطبيقات](../integrations/api-access.md) لمعرفة كيفية إنشاء مفتاح. تستخدم جميع الطلبات أدناه عنوان URL الأساسي `https://api.youraiconnector.com/v1` ويجب عليك مصادقة كل طلب. راجع [المصادقة](authentication.md) للاطلاع على الأشكال الأربعة المقبولة - تستخدم الأمثلة هنا ترويسة `X-API-Key`، مع مثال cURL واحد لكل صفحة يوضح نموذج الاستعلام الأبسط `?apiKey=`.
:::


---

## Instagram + Messenger (Meta)

يتم توصيل Instagram و Messenger معاً في تدفق واحد، لأنهما يعملان على صفحة Facebook. يقوم صاحب الحساب بالتفويض من خلال Facebook، وتقوم أنت بجلب قائمة الصفحات التي يديرها، وتختار الصفحة التي تريد توصيلها.

### الخطوة 1 - بدء اتصال Instagram + Messenger

```
POST /channels/meta/connect
```

يعيد هذا رابط URL للموافقة. لا يتم إرسال أي بيانات اعتماد في هذا الطلب - يتم تفويض الاتصال بالكامل في المتصفح.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/meta/connect?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/channels/meta/connect", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
// Open data.oauth_url in the end user's browser.
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/channels/meta/connect",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
# Open data["oauth_url"] in the end user's browser.
```

**الاستجابة**

```json
{
  "success": true,
  "oauth_url": "https://www.facebook.com/v21.0/dialog/oauth?client_id=...&state=...",
  "state_token": "opaque-one-time-token",
  "connect_url": "https://api.youraiconnector.com/v1/channels/meta/connect/page?token=eyJhbGciOi...",
  "connect_url_expires_at": 1717000000000,
  "expires_at": "2026-06-10T12:30:00.000Z"
}
```

افتح `oauth_url` في متصفح المستخدم النهائي حتى يتمكن من تسجيل الدخول إلى Facebook والموافقة على الوصول. تنتهي محاولة الاتصال في `expires_at` (حوالي 30 دقيقة) - إذا انتهت صلاحيتها، ابدأ من جديد. تعامل مع `state_token` كسر قصير الأجل ولا تقم بتسجيله.

### الخيار الأسهل لـ Instagram + Messenger: تسليم `connect_url`

تتضمن الاستجابة أيضًا `connect_url` جاهزًا: صفحة مستضافة تُشغّل العملية بأكملها لصاحب الحساب. يقوم بفتحها، وتسجيل الدخول إلى فيسبوك، وعندما يكون لديه أكثر من صفحة، تعرض الصفحة قائمة وتتيح له اختيار الصفحة التي يريد ربطها - ثم تبلغ عن النجاح من تلقاء نفسها. امنح هذا الرابط لصاحب الحساب بدلاً من فتح `oauth_url` بنفسك، وبناء أداة اختيار الصفحة، وإجراء الاستطلاع. يعمل الرابط لمدة 30 دقيقة تقريبًا (`connect_url_expires_at`)؛ إذا انتهت صلاحيته، ابدأ اتصالاً جديداً. الخطوات اليدوية أدناه مخصصة لعمليات التكامل التي ترغب في إدارة العملية وعرض أداة اختيار الصفحة بنفسها.

### الخطوة 2 - استعلم عن الحالة حتى يتم تحميل الصفحات

```
GET /channels/meta/status
```

بعد أن ينتهي المستخدم من تسجيل الدخول عبر فيسبوك، استعلم عن نقطة النهاية هذه كل بضع ثوانٍ. يمر الحقل `status` عبر هذه الخطوات:

| `status` | المعنى |
|---|---|
| `pending` | لم تكتمل الموافقة بعد. استمر في الانتظار. |
| `token_received` | تم التفويض، ولكن قائمة الصفحات لا تزال قيد التحميل. |
| `pages_loaded` | الصفحات متاحة - انتقل إلى الخطوة 3. |
| `connected` | تم اختيار صفحة وأصبحت القناة مباشرة. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/channels/meta/status" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/channels/meta/status", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
// Poll until data.status === "pages_loaded".
```

**Python**

```python
res = requests.get(
    "https://api.youraiconnector.com/v1/channels/meta/status",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
# Poll until data["status"] == "pages_loaded".
```

**الاستجابة (بمجرد تحميل الصفحات)**

```json
{
  "success": true,
  "status": "pages_loaded",
  "pages": [
    {
      "id": "1234567890",
      "name": "My Business Page",
      "category": "Local business",
      "instagram_business_account": {
        "id": "17890000000000000",
        "username": "mybusiness"
      }
    }
  ],
  "selected_page": null
}
```

### الخطوة 3 - سرد الصفحات (اختياري)

إذا كنت تفضل جلب قائمة الصفحات بمفردها (على سبيل المثال، لعرض أداة اختيار)، استخدم:

```
GET /channels/meta/pages
```

```bash
curl "https://api.youraiconnector.com/v1/channels/meta/pages" \
  -H "X-API-Key: YOUR_API_KEY"
```

تُرجع هذه النقطة نفس مصفوفة `pages` الموجودة في نقطة نهاية الحالة. (تتضمن نقطة النهاية `status` الصفحات بالفعل، لذا فإن هذا الاستدعاء هو مجرد وسيلة مريحة.)

### الخطوة 4 - اختيار الصفحة للاتصال

```
POST /channels/meta/select-page
```

أرسل `page_id` الصفحة التي اختارها المستخدم. يتم توصيل حساب إنستغرام المرتبط بتلك الصفحة تلقائيًا؛ تحتاج فقط إلى كائن `instagram` إذا كنت ترغب في تجاوز حساب إنستغرام المراد استخدامه.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/meta/select-page" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "page_id": "1234567890" }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/channels/meta/select-page", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ page_id: "1234567890" }),
});
const data = await res.json();
```

**Python**

```python
res = requests.post(
    "https://api.youraiconnector.com/v1/channels/meta/select-page",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"page_id": "1234567890"},
)
data = res.json()
```

**الاستجابة**

```json
{
  "success": true,
  "page_id": "1234567890",
  "instagram_business_account_id": "17890000000000000"
}
```

تم توصيل القناة الآن. سيقوم استدعاء `GET /channels/meta/status` لاحق بالإبلاغ عن `status: "connected"`.

### سرد منشورات الصفحة المتصلة

```
GET /channels/meta/posts?platform=instagram
```

يعيد المنشورات الحديثة للصفحة التي قمت بتوصيلها - وسائط Instagram أو منشورات Facebook. هذا هو ما تقوم بإنشاء أداة اختيار منه عند إعداد نقطة دخول (Entry Point) تتفاعل مع التعليقات على منشور معين.

| معلمة الاستعلام | مطلوبة | الوصف |
|---|---|---|
| `platform` | نعم | `instagram` أو `facebook`. أي قيمة أخرى ستعيد `400`. |
| `limit` | لا | عدد المنشورات المراد إرجاعها، من `1` إلى `50`. القيمة الافتراضية هي `25`. |
| `after` | لا | مؤشر (Cursor) للصفحة التالية - مرر قيمة `nextCursor` من الاستجابة السابقة. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/channels/meta/posts?platform=instagram&limit=25" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{
  "success": true,
  "connected": true,
  "platform": "instagram",
  "posts": [
    {
      "id": "17900000000000000",
      "caption": "New spring menu is live",
      "thumbnailUrl": "https://scontent.cdninstagram.com/...",
      "permalink": "https://www.instagram.com/p/Cxxxxxxxxxx/",
      "createdAt": "2026-05-02T09:12:00.000Z",
      "mediaType": "REELS"
    }
  ],
  "nextCursor": "QVFIUkxxxxxxxx"
}
```

`mediaType` هو تصنيف Instagram الخاص (`REELS`، أو `FEED`، أو `STORY`، أو التنسيق - `IMAGE`، أو `VIDEO`، أو `CAROUSEL_ALBUM`)؛ بالنسبة لـ Facebook يكون دائماً `POST`. `nextCursor` يكون `null` في الصفحة الأخيرة.

إذا لم يكن هناك شيء يمكن سرده، فسيظل الاستدعاء يعيد `200` مع `connected: false` ومصفوفة `posts` فارغة، بالإضافة إلى `reason` يوضح السبب:

| `reason` | ما يجب فعله |
|---|---|
| _(غير موجود)_ | لم يتم توصيل أي صفحة بعد - قم بتشغيل تدفق التوصيل أولاً. |
| `no_instagram_account` | صفحة Facebook متصلة ولكن لا يوجد حساب أعمال Instagram مرتبط بها. لا تزال منشورات Facebook تُسرد بشكل جيد. |
| `token_expired` | بيانات اعتماد الصفحة المخزنة لم تعد تعمل - أعد توصيل القناة. |

### قطع اتصال Instagram + Messenger

```
DELETE /channels/meta
```

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/channels/meta" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{ "success": true, "disconnected": true }
```

يؤدي هذا إلى إيقاف التوجيه الوارد لكل من إنستغرام وماسنجر. هذه العملية متماثلة (idempotent) - استدعاؤها عندما لا يكون هناك شيء متصل ينجح أيضًا.

---

## واتساب للأعمال

يؤدي هذا إلى ربط رقم رسمي لـ WhatsApp Business. يجب أن يكون الرقم موجوداً بالفعل في الحساب قبل استدعاء الربط. مثل Meta، يقوم صاحب الحساب بالتفويض في متصفحه، ثم تقوم أنت بالاستعلام حتى يبلغ الرقم عن `ONLINE`.

### الخطوة 1 - بدء اتصال WhatsApp Business

```
POST /channels/whatsapp/connect
```

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/whatsapp/connect?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "phone_number": "+14155551234" }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/channels/whatsapp/connect", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ phone_number: "+14155551234" }),
});
const data = await res.json();
// Open data.oauth_url in the account holder's browser.
```

**Python**

```python
res = requests.post(
    "https://api.youraiconnector.com/v1/channels/whatsapp/connect",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"phone_number": "+14155551234"},
)
data = res.json()
# Open data["oauth_url"] in the account holder's browser.
```

| الحقل | مطلوب | الوصف |
|---|---|---|
| `phone_number` | نعم | الرقم المراد ربطه، بتنسيق E.164 (على سبيل المثال `+14155551234`). |
| `only_waba_sharing` | لا | قصر التفويض على مشاركة حساب WhatsApp Business موجود، مع تخطي إعداد مرسل جديد. القيمة الافتراضية هي `false`. |
| `retry` | لا | إعادة تشغيل التفويض لرقم لم تكتمل محاولته السابقة. القيمة الافتراضية هي `false`. |
| `business_name` | لا | تجاوز تجميلي لاسم النشاط التجاري المعروض على شاشة الموافقة فقط (بحد أقصى 256 حرفاً). لا يتم تخزينه. |
| `description` | لا | تجاوز تجميلي لوصف النشاط التجاري المعروض على شاشة الموافقة فقط (بحد أقصى 256 حرفاً). لا يتم تخزينه. |

**الاستجابة**

```json
{
  "success": true,
  "status": "pending",
  "oauth_url": "https://www.facebook.com/v21.0/dialog/oauth?client_id=...&state=...",
  "state_token": "opaque-one-time-token",
  "expires_at": "2026-06-10T12:30:00.000Z"
}
```

افتح `oauth_url` في متصفح صاحب الحساب للتفويض. بمجرد الموافقة، يكتمل التسجيل في الخلفية.

### الخطوة 2 - استعلم عن الحالة حتى تصبح ONLINE

```
GET /channels/whatsapp/connect/{phoneNumber}/status
```

استعلم عن هذا حتى تصبح `status` هي `ONLINE`.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/channels/whatsapp/connect/+14155551234/status" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const phone = encodeURIComponent("+14155551234");
const res = await fetch(
  `https://api.youraiconnector.com/v1/channels/whatsapp/connect/${phone}/status`,
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
// Poll until data.status === "ONLINE".
```

**Python**

```python
import urllib.parse

phone = urllib.parse.quote("+14155551234")
res = requests.get(
    f"https://api.youraiconnector.com/v1/channels/whatsapp/connect/{phone}/status",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
# Poll until data["status"] == "ONLINE".
```

**الاستجابة**

```json
{
  "success": true,
  "phone_number": "+14155551234",
  "channel": "whatsapp",
  "status": "ONLINE",
  "status_reason": null,
  "live": true
}
```

يمكن أن يكون حقل `status` كالتالي:

| `status` | المعنى |
|---|---|
| `PENDING` | تم التفويض، ولا تزال الموافقة قيد المعالجة. استمر في الاستعلام. |
| `ONLINE` | متصل وجاهز للإرسال. |
| `RATE_LIMITED` | الكثير من المحاولات - انتظر قبل إعادة المحاولة. |
| `REGISTRATION_FAILED` | تعذر إكمال الإعداد. |
| `DELETED` | التسجيل لم يعد موجوداً. |

تعني `live: true` أنه تم التحقق من الحالة مقابل المزود في الوقت الفعلي؛ وتعني `false` أنها جاءت من آخر حالة مخزنة مؤقتاً.

### قطع اتصال رقم WhatsApp Business

```
DELETE /channels/whatsapp/{phoneNumber}
```

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/channels/whatsapp/+14155551234" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{ "success": true, "phone_number": "+14155551234", "disconnected": true }
```

يبقى الرقم نفسه في الحساب، لذا يمكنك إعادة ربطه لاحقاً.

---

## WhatsApp Web

يربط WhatsApp Web رقم WhatsApp عادي عن طريق مسح رمز QR، تماماً مثل ربط جهاز في تطبيق WhatsApp. تسلسل الخطوات هو: بدء الجلسة، جلب رمز QR وعرضه، ثم الاستمرار في الاستعلام عن الحالة حتى تصبح `connected`.

### الخطوة 1 - بدء جلسة اقتران WhatsApp Web

```
POST /channels/whatsapp-web/connections
```

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/whatsapp-web/connections?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "phone_number": "+15551230000" }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/channels/whatsapp-web/connections", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ phone_number: "+15551230000" }),
});
const data = await res.json();
```

**Python**

```python
res = requests.post(
    "https://api.youraiconnector.com/v1/channels/whatsapp-web/connections",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"phone_number": "+15551230000"},
)
data = res.json()
```

| الحقل | مطلوب | الوصف |
|---|---|---|
| `phone_number` | نعم | رقم WhatsApp المراد توصيله، بتنسيق E.164. |
| `proxy_country` | لا | رمز البلد ISO 3166-1 alpha-2 لمنطقة التوجيه. يتم اكتشافه تلقائياً من الرقم عند حذفه. |
| `force_new` | لا | تجاهل أي جلسة موجودة وبدء اقتران جديد. القيمة الافتراضية هي `false`. |
| `import_contacts` | لا | استيراد جهات اتصال الجهاز الموجودة عند الاتصال الأول. القيمة الافتراضية هي `false`. |
| `pause_ai_for_imported_contacts` | لا | عند استيراد جهات الاتصال، أبقِ الردود التلقائية متوقفة مؤقتاً لها. القيمة الافتراضية هي `true`. |
| `import_existing_chats` | لا | استيراد سجل الدردشة الحالي (يتطلب `import_contacts: true`). القيمة الافتراضية هي `false`. |

**الاستجابة**

```json
{
  "success": true,
  "phone_number": "+15551230000",
  "session_id": "session-id",
  "status": "qr_pending",
  "connect_url": "https://api.youraiconnector.com/v1/channels/whatsapp-web/connect?token=eyJhbGciOi...",
  "connect_url_expires_at": 1717000000000,
  "poll_qr_path": "/v1/channels/whatsapp-web/connections/%2B15551230000/qr",
  "poll_status_path": "/v1/channels/whatsapp-web/connections/%2B15551230000/status"
}
```

### الخيار الأسهل لـ WhatsApp Web: تسليم `connect_url`

تتضمن الاستجابة `connect_url` جاهزاً للاستخدام: صفحة مستضافة تعرض رمز الاستجابة السريعة (QR)، وتقوم بتحديثه تلقائياً أثناء دورانه، وتنتقل إلى رسالة نجاح بمجرد ربط الرقم. ما عليك سوى إعطاء هذا الرابط لصاحب الحساب (افتحه في متصفح، أو أرسله إليهم، أو اعرضه كرمز QR أو زر) واطلب منهم مسحه ضوئياً باستخدام واتساب - لست بحاجة إلى جلب رمز QR أو إجراء استطلاع لأي شيء بنفسك. يعمل الرابط لمدة 30 دقيقة تقريباً (`connect_url_expires_at`)؛ إذا انتهت صلاحيته قبل أن ينتهوا، ابدأ اتصالاً جديداً للحصول على رابط جديد.

هذا هو المسار الموصى به عندما يتمكن الشخص من فتح رابط. الخطوات اليدوية أدناه (جلب رمز QR بنفسك، واستطلاع الحالة) مخصصة لعمليات التكامل التي ترغب في عرض رمز QR داخل واجهتها الخاصة بدلاً من ذلك.

تزودك الاستجابة أيضاً بـ `poll_qr_path` و `poll_status_path` الدقيقين للاستخدام، حتى لا تضطر إلى بنائهما بنفسك.

### الخطوة 2 - جلب رمز QR وعرضه

```
GET /channels/whatsapp-web/connections/{phoneNumber}/qr
```

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/channels/whatsapp-web/connections/+15551230000/qr" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const phone = encodeURIComponent("+15551230000");
const res = await fetch(
  `https://api.youraiconnector.com/v1/channels/whatsapp-web/connections/${phone}/qr`,
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
// Render data.qr_data_url as an <img src> for the user to scan.
```

**Python**

```python
import urllib.parse

phone = urllib.parse.quote("+15551230000")
res = requests.get(
    f"https://api.youraiconnector.com/v1/channels/whatsapp-web/connections/{phone}/qr",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
# Render data["qr_data_url"] for the user to scan.
```

**الاستجابة**

```json
{
  "success": true,
  "phone_number": "+15551230000",
  "status": "qr_pending",
  "qr_code": "2@raw-qr-payload-string...",
  "qr_data_url": "data:image/png;base64,iVBORw0KGgo...",
  "expires_at": "2026-06-10T12:05:00.000Z"
}
```

اعرض رمز QR ليقوم المستخدم بمسحه ضوئياً بهاتفه (WhatsApp > الأجهزة المرتبطة > ربط جهاز):

- `qr_data_url` هي صورة جاهزة للاستخدام - ضعها مباشرة في `<img src>`.
- `qr_code` هي الحمولة الخام إذا كنت تفضل إنشاء الصورة بنفسك.

رمز QR قصير العمر. إذا قمت باستدعاء هذا مباشرة بعد بدء الجلسة، فقد تحصل على `404` مع رسالة "رمز QR غير متاح بعد" - فقط انتظر لحظة وأعد المحاولة. إذا حصلت على `410` ("انتهت صلاحية رمز QR")، ابدأ الاتصال من جديد للحصول على رمز جديد.

### الخطوة 3 - الاستعلام عن الحالة حتى يتم الاتصال

```
GET /channels/whatsapp-web/connections/{phoneNumber}/status
```

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/channels/whatsapp-web/connections/+15551230000/status" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const phone = encodeURIComponent("+15551230000");
const res = await fetch(
  `https://api.youraiconnector.com/v1/channels/whatsapp-web/connections/${phone}/status`,
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
// Poll until data.status === "connected" (or "open").
```

**Python**

```python
import urllib.parse

phone = urllib.parse.quote("+15551230000")
res = requests.get(
    f"https://api.youraiconnector.com/v1/channels/whatsapp-web/connections/{phone}/status",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
# Poll until data["status"] == "connected" (or "open").
```

**الاستجابة**

```json
{
  "success": true,
  "phone_number": "+15551230000",
  "status": "connected",
  "has_qr": false,
  "qr_expires_at": null,
  "last_activity": null,
  "message_count": null,
  "proxy": null,
  "live": true
}
```

| `status` | المعنى |
|---|---|
| `not_initialized` | لا توجد جلسة بعد (فشل نهائي). |
| `qr_pending` | في انتظار مسح رمز QR. |
| `connecting` | تم المسح، جاري إنهاء الإعداد. |
| `connected` / `open` | مرتبط ويعمل - هذا هو النجاح. |
| `disconnected` | انتهت الجلسة (فشل نهائي). |

### قطع اتصال جلسة WhatsApp Web

```
DELETE /channels/whatsapp-web/connections/{phoneNumber}
```

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/channels/whatsapp-web/connections/+15551230000" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{ "success": true, "phone_number": "+15551230000", "status": "removed" }
```

يؤدي هذا إلى إلغاء ربط الجهاز وإزالة الاتصال. وهو يقوم دائمًا بتنظيف الحالة المحلية، لذا فهو عملية متكررة (idempotent) حتى لو كانت الجلسة الأساسية قد انتهت بالفعل.

---

## Telegram

> **التوفر:** يتصل Telegram مثل أي قناة أخرى وهو متاح لكل حساب — لا تحتاج إلى تفعيله خصيصاً لك. لا تزال نقاط نهاية Telegram أدناه قادرة على إرجاع `403` إذا لم يكن Telegram مشمولاً في خطة الحساب، وفي هذه الحالة تكون رسالة الخطأ `"This channel is not included in your current plan. Upgrade to unlock it."`.

يربط تيليجرام حساباً شخصياً عن طريق رقم الهاتف بالإضافة إلى رمز تسجيل دخول لمرة واحدة (وكلمة مرور للمصادقة الثنائية، إذا كان الحساب قد ضبط واحدة). تسير العملية كالتالي: بدء الجلسة، إرسال الرمز، إرسال كلمة المرور اختيارياً، ثم التأكيد عبر الحالة.

### الخطوة 1 - بدء جلسة اتصال Telegram

```
POST /channels/telegram/connect
```

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/telegram/connect?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "phone_number": "+14155550100" }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/channels/telegram/connect", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ phone_number: "+14155550100" }),
});
const data = await res.json();
```

**Python**

```python
res = requests.post(
    "https://api.youraiconnector.com/v1/channels/telegram/connect",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"phone_number": "+14155550100"},
)
data = res.json()
```

| الحقل | مطلوب | الوصف |
|---|---|---|
| `phone_number` | نعم | رقم هاتف الحساب المراد ربطه، بتنسيق E.164. |
| `mode` | لا | `code` (الافتراضي) يرسل رمز تسجيل دخول لمرة واحدة إلى الحساب؛ `qr` يعيد رمز تسجيل دخول ورابط QR للعرض. |
| `proxy_country` | لا | رمز البلد ISO 3166-1 alpha-2 لمسار الشبكة الصادر. |
| `force_new` | لا | عند ضبطه على `true`، يتم تجاهل أي جلسة موجودة والبدء من جديد. |

**الاستجابة**

```json
{
  "success": true,
  "phone_number": "+14155550100",
  "status": "code_required",
  "session_id": "session-id",
  "connect_url": "https://api.youraiconnector.com/v1/channels/telegram/connect/page?token=eyJhbGciOi...",
  "connect_url_expires_at": 1717000000000
}
```

في وضع `code`، يتلقى الحساب رمز تسجيل دخول في تيليجرام وتكون `status` هي `code_required`. (في وضع `qr`، تتضمن الاستجابة أيضاً `login_token` و `qr_url` للعرض من أجل المسح الضوئي، وتكون `status` هي `qr_required`.)

### الخيار الأسهل لـ Telegram: تسليم `connect_url`

تتضمن الاستجابة `connect_url` جاهزاً: صفحة مستضافة تُكمل الاتصال من تلقاء نفسها. في وضع `code`، يقوم صاحب الحساب بإدخال رمز تسجيل الدخول - وكلمة مرور التحقق بخطوتين إذا كان حسابه يحتوي على واحدة. في وضع `qr`، تعرض الصفحة رمز QR يتجدد تلقائياً ليقوم المستخدم بمسحه ضوئياً من تطبيق Telegram. في كلتا الحالتين، يتم الإبلاغ عن النجاح تلقائياً، لذا يمكنك ببساطة إعطاء هذا الرابط لصاحب الحساب بدلاً من بناء واجهة مستخدم خاصة بك وإجراء عمليات الاستطلاع (polling). يعمل الرابط لمدة 30 دقيقة تقريباً (`connect_url_expires_at`)؛ إذا انتهت صلاحيته، ابدأ اتصالاً جديداً للحصول على رابط جديد.

الخطوات اليدوية أدناه (جمع الرمز بنفسك، إرساله، استطلاع الحالة؛ أو عرض `qr_url` والاستطلاع) مخصصة لعمليات التكامل التي ترغب في عرض واجهة المستخدم الخاصة بها بنفسها.

### الخطوة 2 - إرسال رمز تسجيل الدخول

```
POST /channels/telegram/connect/{phoneNumber}/verify-code
```

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/telegram/connect/+14155550100/verify-code" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "code": "12345" }'
```

**JavaScript**

```javascript
const phone = encodeURIComponent("+14155550100");
const res = await fetch(
  `https://api.youraiconnector.com/v1/channels/telegram/connect/${phone}/verify-code`,
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ code: "12345" }),
  }
);
const data = await res.json();
```

**Python**

```python
import urllib.parse

phone = urllib.parse.quote("+14155550100")
res = requests.post(
    f"https://api.youraiconnector.com/v1/channels/telegram/connect/{phone}/verify-code",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"code": "12345"},
)
data = res.json()
```

**الاستجابة**

```json
{
  "success": true,
  "phone_number": "+14155550100",
  "status": "connected",
  "telegram_user_id": "100000001",
  "username": "myhandle"
}
```

إذا كانت `status` هي `connected`، فقد انتهيت. إذا كان الحساب مفعلاً للمصادقة الثنائية، فستكون `status` هي `password_required` بدلاً من ذلك - انتقل إلى الخطوة 3.

### الخطوة 3 - إرسال كلمة مرور المصادقة الثنائية (فقط إذا لزم الأمر)

```
POST /channels/telegram/connect/{phoneNumber}/verify-password
```

لا تستدعِ هذا إلا عندما تعيد الخطوة 2 `password_required`.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/telegram/connect/+14155550100/verify-password" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "password": "the-2fa-password" }'
```

**JavaScript**

```javascript
const phone = encodeURIComponent("+14155550100");
const res = await fetch(
  `https://api.youraiconnector.com/v1/channels/telegram/connect/${phone}/verify-password`,
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ password: "the-2fa-password" }),
  }
);
const data = await res.json();
```

**Python**

```python
import urllib.parse

phone = urllib.parse.quote("+14155550100")
res = requests.post(
    f"https://api.youraiconnector.com/v1/channels/telegram/connect/{phone}/verify-password",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"password": "the-2fa-password"},
)
data = res.json()
```

**الاستجابة**

```json
{
  "success": true,
  "phone_number": "+14155550100",
  "status": "connected",
  "telegram_user_id": "100000001",
  "username": "myhandle"
}
```

### التحقق من حالة Telegram

```
GET /channels/telegram/connect/{phoneNumber}/status
```

```bash
curl "https://api.youraiconnector.com/v1/channels/telegram/connect/+14155550100/status" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{
  "success": true,
  "phone_number": "+14155550100",
  "status": "connected",
  "telegram_user_id": "100000001",
  "live": true
}
```

يمكن أن تكون `status` عبارة عن `connected`، أو `code_required`، أو `password_required`، أو `initializing`، أو `disconnected`، أو `not_initialized`، أو `error`.

### قطع اتصال Telegram

```
DELETE /channels/telegram/{phoneNumber}
```

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/channels/telegram/+14155550100" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{ "success": true, "phone_number": "+14155550100", "status": "removed" }
```

غير مؤثرة (Idempotent) - تنجح المكالمات المتكررة.

---

## إنستغرام (حساب شخصي)

> إصدار تجريبي محدود التوفر، يتم تفعيله لكل حساب على حدة. يربط هذا الاتصال حساب إنستغرام شخصي عن طريق تسجيل الدخول باستخدام اسم المستخدم وكلمة المرور (وليس واجهة برمجة تطبيقات الأعمال الرسمية). إذا لم يكن الحساب مفعلاً للإصدار التجريبي، فسيُرجع استدعاء الاتصال خطأ في الأذونات.

نظرًا لأن هذا يتطلب تسجيل دخول صاحب الحساب إلى إنستغرام الخاص به، فإن أبسط مسار هو تسليمه `connect_url` المستضاف والسماح له بإدخال بيانات اعتماده هناك - لن يتعامل تكاملك أبداً مع كلمة المرور.

### الخطوة 1 - بدء اتصال Instagram (الشخصي)

```
POST /channels/instagram-private/connect
```

أرسل `username` و `password` الخاص بـ Instagram.

**الاستجابة**

```json
{
  "success": true,
  "status": "connected",
  "connect_url": "https://api.youraiconnector.com/v1/channels/instagram-private/connect/page?token=eyJhbGciOi...",
  "connect_url_expires_at": 1717000000000
}
```

إذا كان الحساب يحتوي على مصادقة ثنائية أو قدم Instagram نقطة تحقق، فستعود `status` كـ `two_factor_required` أو `challenge_required` - أرسل الرمز إلى `/connect/{id}/verify-2fa` أو `/connect/{id}/verify-challenge` أدناه، ثم استعلم عن `/connect/{id}/status` حتى `connected`. `{id}` هو اسم مستخدم Instagram الموحد الذي تم إرجاعه كـ `account_id`/`username` في الاستجابة أعلاه - استخدمه في كل خطوة أدناه.

### الخطوة 2 - إرسال رمز المصادقة الثنائية (إذا طُلب ذلك)

```
POST /channels/instagram-private/connect/{id}/verify-2fa
```

لا تستدعِ هذا إلا عندما تعيد الخطوة 1 (أو الخطوة 3) القيمة `two_factor_required`.

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/instagram-private/connect/yourbrand/verify-2fa" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "code": "123456" }'
```

**الاستجابة**

```json
{
  "success": true,
  "account_id": "yourbrand",
  "status": "connected",
  "ig_user_id": "17890000000000000",
  "username": "yourbrand"
}
```

يمكن أن تعود `status` كـ `connected` (تم)، أو `two_factor_required` (رمز خاطئ، حاول مرة أخرى)، أو `challenge_required` (يريد Instagram أيضاً رمز نقطة تحقق - انتقل إلى الخطوة 3).

### الخطوة 3 - إرسال رمز تأكيد نقطة التحقق (إذا طُلب ذلك)

```
POST /channels/instagram-private/connect/{id}/verify-challenge
```

لا تستدعِ هذا إلا عندما تعيد خطوة سابقة القيمة `challenge_required`. نفس شكل الطلب والاستجابة كما في الخطوة 2 أعلاه.

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/instagram-private/connect/yourbrand/verify-challenge" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "code": "123456" }'
```

### التحقق من حالة Instagram (الشخصي)

```
GET /channels/instagram-private/connect/{id}/status
```

استعلم عن هذا حتى تصبح `status` هي `connected`، أو حتى تبلغ عن فشل نهائي.

```bash
curl "https://api.youraiconnector.com/v1/channels/instagram-private/connect/yourbrand/status" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{
  "success": true,
  "account_id": "yourbrand",
  "status": "connected",
  "ig_user_id": "17890000000000000",
  "username": "yourbrand",
  "live": true
}
```

يمكن أن تكون `status` هي `connected`، أو `two_factor_required`، أو `challenge_required`، أو `initializing`، أو `disconnected`، أو `not_initialized`، أو `error`. تعني `live: true` أن هذه القيمة تمت قراءتها مباشرة من عامل التوصيل بدلاً من قيمة مخزنة مؤقتاً.

### الخيار الأسهل لـ Instagram (الشخصي): تسليم `connect_url`

تتضمن الاستجابة `connect_url`: صفحة مستضافة حيث يقوم صاحب الحساب بإدخال اسم مستخدم إنستغرام وكلمة المرور (ورمز المصادقة الثنائية أو رمز نقطة التحقق إذا طلب إنستغرام ذلك)، والتي تبلغ عن النجاح من تلقاء نفسها. تذهب بيانات الاعتماد مباشرة إلى إنستغرام ولا يتم تخزينها. امنح هذا الرابط لصاحب الحساب بدلاً من جمع كلمة المرور الخاصة به في واجهة المستخدم الخاصة بك. يعمل الرابط لمدة 30 دقيقة تقريبًا (`connect_url_expires_at`).

### إلغاء ربط Instagram (شخصي)

```
DELETE /channels/instagram-private/{id}
```

غير مؤثرة (Idempotent) - تنجح المكالمات المتكررة.

### مزامنة المتابعين

```
POST /channels/instagram-private/{id}/sync-followers
```

يؤدي هذا إلى تشغيل مزامنة المتابعين يدويًا لحساب متصل - وهي نفس المهمة التي تعمل تلقائيًا في الخلفية، ولكنها متاحة هنا كإجراء "تحديث المتابعين" عند الطلب. يقوم هذا الإجراء بجلب قائمة المتابعين الحالية للحساب، وتسجيل أي متابعين جدد، و(عندما تكون حملة البث المباشر مفعلة لخيار التواصل مع المتابعين) إرسال رسالة مباشرة افتتاحية للمتابعين الجدد، بحد أقصى يومي.

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/instagram-private/yourbrand/sync-followers" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{
  "success": true,
  "accountId": "yourbrand",
  "totalFollowers": 1204,
  "newFollowers": 6,
  "dmsSent": 6,
  "isBaselineSeed": false
}
```

> هذه الحقول الخمسة هي المكان الوحيد في هذه الصفحة الذي يعود بـ `camelCase` بدلاً من `snake_case` - هكذا تم إعداد نقطة النهاية هذه حاليًا، وليس خطأ مطبعيًا. تعني `isBaselineSeed: true` أن هذه كانت أول عملية مزامنة بعد الاتصال، والتي تقوم فقط بتسجيل قائمة المتابعين الأولية ولا ترسل أبدًا رسائل تواصل مباشرة (لذا تكون `dmsSent` دائمًا `0` في تلك العملية).

قد يستغرق الاستدعاء الأول للحساب بعض الوقت (بسبب استعراض قائمة المتابعين بالكامل)؛ أما الاستدعاءات اللاحقة فتكون أسرع نظرًا لأنه يتم تحديد المتابعين الجدد فقط. تعني `404` أن الحساب غير متصل؛ وتعني `412` أن الاتصال لم ينتهِ من التهيئة بعد - انتظر وأعد المحاولة.

---

## LINE

تعد LINE أبسط قناة للاتصال نظرًا لعدم وجود إعادة توجيه للمتصفح أو استطلاع (polling). يقوم العميل بإنشاء قناة Messaging API في وحدة تحكم مطوري LINE، وينسخ قيمتين، ثم تقوم أنت بإرسالهما في مكالمة واحدة. بعد ذلك، تمنحهم رابط webhook للصقه في وحدة التحكم.

### الخطوة 1 - الاتصال باستخدام بيانات اعتماد القناة

```
POST /channels/line
```

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/line?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel_access_token": "LONG_LIVED_CHANNEL_ACCESS_TOKEN",
    "channel_secret": "CHANNEL_SECRET"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/channels/line", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    channel_access_token: "LONG_LIVED_CHANNEL_ACCESS_TOKEN",
    channel_secret: "CHANNEL_SECRET",
  }),
});
const data = await res.json();
```

**Python**

```python
res = requests.post(
    "https://api.youraiconnector.com/v1/channels/line",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "channel_access_token": "LONG_LIVED_CHANNEL_ACCESS_TOKEN",
        "channel_secret": "CHANNEL_SECRET",
    },
)
data = res.json()
```

| الحقل | مطلوب | الوصف |
|---|---|---|
| `channel_access_token` | نعم | رمز وصول قناة Messaging API طويل الأمد للحساب الرسمي. يُستخدم لإرسال واستقبال الرسائل. |
| `channel_secret` | نعم | سر قناة Messaging API، يُستخدم للتحقق من توقيعات الأحداث الواردة. |
| `channel_id` | لا | معرف القناة الرقمي. للمعلومات فقط. |

**الاستجابة**

```json
{
  "success": true,
  "status": "connected",
  "bot_user_id": "Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "basic_id": "@mybusiness",
  "display_name": "My Business",
  "picture_url": "https://...",
  "chat_mode": "bot",
  "chat_mode_ok": true,
  "webhook_url": "https://api.youraiconnector.com/line/webhook/..."
}
```

هناك حقلان مهمان لما ستفعله بعد ذلك:

- **`webhook_url`** - يجب على العميل لصق هذا في حقل **Webhook URL** الخاص بقناة LINE الخاصة بهم في وحدة تحكم مطوري LINE (وتفعيل "Use webhook"). حتى يقوموا بذلك، لن تصل أي رسائل واردة. اعرض هذا عليهم بشكل بارز.
- **`chat_mode_ok`** - عندما تكون `false`، يكون الحساب الرسمي في وضع "الدردشة" ولن يستقبل أو يرسل رسائل حتى يتم تبديله إلى وضع "البوت" في مدير الحساب الرسمي لـ LINE. قم بتقييد عملية الإعداد الخاصة بك بناءً على هذا العلم وأخبر العميل بتبديل الوضع.

> لا يتم إرجاع `channel_access_token` و `channel_secret` أبدًا بواسطة أي نقطة نهاية. قم بتخزينهما من جانبك إذا كنت بحاجة إليهما مرة أخرى؛ وإلا قم بإعادة لصقهما من وحدة تحكم LINE.

إن `bot_user_id` الذي يتم إرجاعه هنا هو معرف الاتصال الذي تستخدمه في مكالمات الحالة والتحقق وقطع الاتصال أدناه.

### الخطوة 2 - إعادة التحقق بعد إعداد webhook

```
POST /channels/line/{botUserId}/verify-webhook
```

بعد أن ينتهي العميل من تهيئة عنوان URL الخاص بـ webhook والتبديل إلى وضع البوت، استدعِ هذا لإعادة التحقق من الرمز المخزن وتحديث وضع الدردشة المخزن مؤقتاً.

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/line/Uxxxxxxxx.../verify-webhook" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{
  "success": true,
  "token_valid": true,
  "chat_mode": "bot",
  "chat_mode_ok": true,
  "webhook_url": "https://api.youraiconnector.com/line/webhook/..."
}
```

إذا كان `token_valid` هو `false`، فإن رمز الوصول المخزن لم يعد صالحاً للمصادقة - اطلب من العميل إعادة إصداره في وحدة التحكم واستدعاء `POST /channels/line` مرة أخرى باستخدام الرمز الجديد.

### التحقق من حالة LINE

```
GET /channels/line/{botUserId}/status
```

```bash
curl "https://api.youraiconnector.com/v1/channels/line/Uxxxxxxxx.../status" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{
  "success": true,
  "bot_user_id": "Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "channel": "line",
  "status": "connected",
  "basic_id": "@mybusiness",
  "display_name": "My Business",
  "picture_url": "https://...",
  "chat_mode": "bot",
  "is_active": true,
  "live": false
}
```

لا توفر LINE موجز حالة مباشراً، لذا فإن `live` دائماً ما يكون `false` هنا - تعكس القيم الحالة التي تم التقاطها في وقت الاتصال (أو آخر تحقق).

### إلغاء ربط LINE

```
DELETE /channels/line/{botUserId}
```

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/channels/line/Uxxxxxxxx..." \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{ "success": true, "status": "removed", "bot_user_id": "Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }
```

---

## فايبر (Viber)

يتصل فايبر بنفس طريقة اتصال LINE - قم بلصق رمز المصادقة الخاص بالبوت من لوحة تحكم مسؤول فايبر في استدعاء واحد - مع اختلاف واحد يستحق المعرفة: الاتصال يقوم أيضًا بتسجيل خطاف الويب (webhook) الخاص بنا على البوت في تلك اللحظة، لذا لا توجد خطوة منفصلة في وحدة التحكم بعد ذلك. وهذا يعني أيضًا أن محاولة الاتصال قد تفشل إذا لم يتمكن نظامنا من الرد على فحص خطاف الويب المتزامن الخاص بفايبر، وليس فقط إذا كان الرمز نفسه خاطئًا.

### الخطوة 1 - الاتصال باستخدام رمز مصادقة البوت

```
POST /channels/viber
```

| الحقل | مطلوب | الوصف |
|---|---|---|
| `auth_token` | نعم | رمز مصادقة البوت، من لوحة تحكم مسؤول فايبر (إعدادات البوت الخاص بي). |

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/viber?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "auth_token": "444d5555e6666f7777a8888b9999c000" }'
```

**الاستجابة**

```json
{
  "success": true,
  "status": "connected",
  "bot_id": "botIdFromViber",
  "bot_name": "My Business Bot",
  "bot_avatar": "https://...",
  "bot_uri": "mybusinessbot",
  "subscribers_count": 0,
  "webhook_url": "https://api.youraiconnector.com/v1/incoming-viber-message/...",
  "event_types": ["delivered", "seen", "failed", "subscribed", "unsubscribed", "conversation_started"]
}
```

لا يتم إرجاع رمز المصادقة أبدًا بواسطة أي نقطة نهاية - قم بتخزينه من جانبك إذا كنت ستحتاج إلى إعادة لصقه. `bot_id` هو معرف الاتصال المستخدم في استدعاءات الحالة والتحقق وقطع الاتصال أدناه.

### التحقق من حالة فايبر

```
GET /channels/viber/{botId}/status
```

يُبلغ عن حالة الاتصال المخزنة. أضف `?live=true` لإعادة فحص البوت مقابل فايبر وتحديث تسجيل خطاف الويب المخزن مؤقتًا - مفيد قبل افتراض أن البوت الصامت معطل بالفعل.

```bash
curl "https://api.youraiconnector.com/v1/channels/viber/botIdFromViber/status?live=true" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{
  "success": true,
  "bot_id": "botIdFromViber",
  "channel": "viber",
  "status": "connected",
  "bot_name": "My Business Bot",
  "bot_avatar": "https://...",
  "bot_uri": "mybusinessbot",
  "webhook_url": "https://api.youraiconnector.com/v1/incoming-viber-message/...",
  "registered_webhook": "https://api.youraiconnector.com/v1/incoming-viber-message/...",
  "webhook_ok": true,
  "subscribers_count": 128,
  "is_active": true,
  "live": true
}
```

تعني `webhook_ok: false` أن خطاف الويب الخاص بالبوت لم يعد يشير إلينا - الرسائل الواردة متوقفة. يعني هذا عادةً أن أداة أخرى اتصلت بنفس البوت لاحقًا (تسجيل خطاف الويب في فايبر يعتمد على آخر عملية كتابة). قم بإصلاح ذلك باستخدام استدعاء إعادة التحقق أدناه، ولا حاجة لطلب إعادة لصق الرمز من العميل. تكون `live` هي `false` عندما تكون الاستجابة هي آخر حالة مخزنة مؤقتًا بدلاً من فحص جديد مقابل فايبر.

### إعادة تسجيل خطاف الويب

```
POST /channels/viber/{botId}/verify-webhook
```

إجراء الإصلاح لـ `webhook_ok: false` - يقوم بإعادة تسجيل خطاف الويب الخاص بنا على البوت باستخدام رمز المصادقة المخزن مسبقًا.

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/viber/botIdFromViber/verify-webhook" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{ "success": true, "token_valid": true, "webhook_ok": true, "webhook_url": "https://api.youraiconnector.com/v1/incoming-viber-message/...", "event_types": ["delivered", "seen", "failed", "subscribed", "unsubscribed", "conversation_started"] }
```

تعني `token_valid: false` أن الرمز المخزن لم يعد يعمل - أعد الاتصال باستخدام `POST /channels/viber` ورمز جديد.

### قطع اتصال Viber

```
DELETE /channels/viber/{botId}
```

يقوم بإلغاء تسجيل خطاف الويب (webhook) الخاص بنا من جانب Viber (بأفضل جهد ممكن) ويزيل الاتصال.

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/channels/viber/botIdFromViber" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{ "success": true, "status": "removed", "bot_id": "botIdFromViber", "webhook_removed": true }
```

---

## TikTok

> **التوفر:** إصدار تجريبي محدود التوفر، يتم تفعيله لكل حساب. سيؤدي توصيل TikTok إلى ظهور خطأ في الأذونات حتى يتم تفعيل الحساب لهذه الميزة.

تعد مراسلة TikTok للأعمال (TikTok Business Messaging) قناة OAuth كاملة مثل Meta، ولكنها أبسط من جانب الاستطلاع (polling): لا توجد خطوة مخصصة لاستطلاع الحالة للبناء عليها، لأن الحساب المتصل يظهر من تلقاء نفسه بمجرد إعادة توجيه TikTok وكتابة الاتصال. نقطة نهاية الحالة أدناه موجودة لتأكيد الحالة عند الطلب (أدوات الدعم، فحوصات السلامة)، وليس كشيء تحتاج إلى تكراره أثناء الاتصال.

### الخطوة 1 - بدء اتصال TikTok

```
POST /channels/tiktok/connect
```

لا يتطلب أي بيانات اعتماد - يقوم صاحب الحساب بالتفويض بالكامل في متصفحه.

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/tiktok/connect?apiKey=YOUR_API_KEY"
```

**الاستجابة**

```json
{
  "success": true,
  "status": "pending_authorization",
  "oauth_url": "https://www.tiktok.com/v2/auth/authorize?client_key=...&state=...",
  "state_token": "opaque-one-time-token",
  "expires_at": "2026-06-10T12:30:00.000Z"
}
```

افتح `oauth_url` في متصفح صاحب الحساب حتى يتمكنوا من تسجيل الدخول إلى TikTok والموافقة على الوصول. تنتهي صلاحية الحالة في `expires_at` (حوالي 30 دقيقة) - إذا انقضت، ابدأ من جديد. لا يوجد اختصار لصفحة مستضافة `connect_url` لـ TikTok؛ فتح `oauth_url` بنفسك هو المسار الوحيد.

### التحقق من حالة TikTok

```
GET /channels/tiktok/{openId}/status
```

`openId` هو open_id الخاص بحساب TikTok للأعمال، والذي يُعرف بمجرد تشغيل رد اتصال OAuth.

```bash
curl "https://api.youraiconnector.com/v1/channels/tiktok/openIdFromTikTok/status" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{
  "success": true,
  "open_id": "openIdFromTikTok",
  "channel": "tiktok",
  "status": "connected",
  "business_id": "openIdFromTikTok",
  "username": "mybusiness",
  "display_name": "My Business",
  "avatar_url": "https://...",
  "status_reason": null,
  "is_active": true,
  "live": false
}
```

لا يحتوي TikTok على فحص سلامة مباشر وغير مكلف، لذا فإن `live` هنا دائماً `false` - تعكس الحقول ما كتبه الاتصال (أو آخر تحديث للرمز). `status: "reauth_required"` مع ضبط `status_reason` يعني أن الحساب يحتاج إلى المرور بعملية الاتصال مرة أخرى؛ يتم تحديث رموز TikTok تلقائياً في دورة سنوية، وهذا ما يظهر إذا فشلت تلك الدورة في أي وقت.

### قطع اتصال TikTok

```
DELETE /channels/tiktok/{openId}
```

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/channels/tiktok/openIdFromTikTok" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{ "success": true, "status": "removed", "open_id": "openIdFromTikTok" }
```

---

## GoHighLevel

GoHighLevel (GHL) هو تكامل CRM، وليس قناة مراسلة - توصيله لا يستهلك خانة قناة في الخطة، لأنه يعتمد على القنوات الموجودة في الحساب بدلاً من إضافة قناة جديدة. إنه أيضاً التكامل الوحيد في هذه الصفحة الذي يمكنه الاحتفاظ **بأكثر من اتصال في وقت واحد**: كل حساب فرعي (موقع) في GHL يقوم العميل بتثبيت التطبيق عليه يحصل على إدخال خاص به.

### الخطوة 1 - بدء اتصال GHL

```
POST /channels/ghl/connect
```

| الحقل | مطلوب | الوصف |
|---|---|---|
| `brand` | لا | قائمة GHL marketplace التي سيتم التفويض من خلالها. يتم استخدام القائمة القياسية افتراضياً - وهذا ذو صلة فقط إذا كان لديك أكثر من تطبيق marketplace مهيأ في عملية النشر الخاصة بك. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/ghl/connect?apiKey=YOUR_API_KEY"
```

**الاستجابة**

```json
{
  "success": true,
  "status": "pending_authorization",
  "oauth_url": "https://marketplace.gohighlevel.com/oauth/chooselocation?client_id=...&state=...",
  "state_token": "opaque-one-time-token",
  "brand": "dmchamp",
  "expires_at": "2026-06-10T12:30:00.000Z"
}
```

افتح `oauth_url` في متصفح صاحب الحساب ليتمكن من اختيار موقع GHL والموافقة على الوصول. تنتهي صلاحية الحالة في `expires_at` (حوالي 30 دقيقة).

### سرد اتصالات GHL

```
GET /channels/ghl/status
```

على عكس القنوات الأخرى، هذه ليست حالة اتصال واحد - بل تسرد كل موقع قام الحساب بالاتصال به.

```bash
curl "https://api.youraiconnector.com/v1/channels/ghl/status" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{
  "success": true,
  "connections": [
    {
      "location_id": "abc123location",
      "company_id": "xyz789company",
      "brand": "dmchamp",
      "status": "connected",
      "status_reason": null,
      "scopes": ["conversations.readonly", "conversations.write", "conversations/message.write"],
      "connected_at": "2026-06-01T10:00:00.000Z",
      "conversation_provider_id": "provider-id-in-ghl",
      "trigger_subscriptions": [
        { "id": "sub_1", "key": "InboundMessage", "workflow_id": "wf_123" }
      ]
    }
  ]
}
```

### قطع اتصال موقع GHL

```
DELETE /channels/ghl/{locationId}
```

يحذف الاتصال هنا، مما يوقف كل المزامنات والمشغلات (triggers) لهذا الموقع. هذا لا يؤدي إلى إلغاء تثبيت التطبيق من جانب GHL - يقوم العميل بإزالته من تثبيتات GHL marketplace الخاصة به إذا أراد ذلك أيضاً.

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/channels/ghl/abc123location" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{ "success": true, "status": "disconnected", "location_id": "abc123location" }
```

---

## أرقام الهواتف (الشراء والإلغاء)

بدلاً من توصيل رقم موجود، يمكنك شراء رقم جديد يدعم WhatsApp مباشرة. ابحث عن الأرقام المتاحة، واشترِ واحداً، ثم استمر في الاستعلام حتى ينتهي من التوفير.

::: note
**ملاحظة:** الأرقام التي يتم شراؤها هنا تدعم WhatsApp. يتم تشغيل تسجيل مرسل WhatsApp في الخلفية بعد الشراء، لذا يجب عليك استطلاع الحالة حتى تصل إلى `ONLINE` قبل الإرسال. يتم خصم الرصيد عند الشراء ولا يتم استرداده عند تحرير الرقم.
:::


### الخطوة 1 - البحث عن الأرقام المتاحة

```
GET /phone-numbers/available?country_code=ISO2
```

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/phone-numbers/available?country_code=US&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/phone-numbers/available?country_code=US",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
```

**Python**

```python
res = requests.get(
    "https://api.youraiconnector.com/v1/phone-numbers/available",
    params={"country_code": "US"},
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

| معامل الاستعلام | مطلوب | الوصف |
|---|---|---|
| `country_code` | نعم | رمز البلد ISO 3166-1 alpha-2 للبحث فيه (على سبيل المثال `US`، `GB`، `NL`). |
| `type` | لا | فئة الرقم المفضلة، `local` أو `mobile`. قد يتم إرجاع كلتا الفئتين. |

**الاستجابة**

```json
{
  "success": true,
  "phone_numbers": [
    {
      "phone_number": "+14155551234",
      "purchase_credits": 50,
      "monthly_credits": 50,
      "cost_usd": 1.15
    }
  ]
}
```

تُظهر كل نتيجة التكلفة لمرة واحدة `purchase_credits` والتكلفة المتكررة `monthly_credits`. يكلف الرقم الذي توفره المنصة 50 رصيداً شهرياً على الأقل، ويرتفع السعر بناءً على السعر الشهري الخاص بشركة الاتصالات، ويتم خصمه عند الشراء وعند كل تجديد. استخدم `purchase_credits` / `monthly_credits` التي تُرجعها عملية البحث؛ لا تقم أبداً بحساب السعر بنفسك. يؤدي البحث الأول في حساب جديد إلى توفير بعض الموارد الأساسية، لذا قد يكون أبطأ قليلاً من عمليات البحث اللاحقة.

### الخطوة 2 - شراء رقم

```
POST /phone-numbers
```

استخدم `phone_number` من نتائج البحث.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/phone-numbers" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "+14155551234",
    "country_code": "US",
    "display_name": "Support line"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/phone-numbers", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    phone_number: "+14155551234",
    country_code: "US",
    display_name: "Support line",
  }),
});
const data = await res.json();
```

**Python**

```python
res = requests.post(
    "https://api.youraiconnector.com/v1/phone-numbers",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "phone_number": "+14155551234",
        "country_code": "US",
        "display_name": "Support line",
    },
)
data = res.json()
```

| الحقل | مطلوب | الوصف |
|---|---|---|
| `phone_number` | نعم | رقم تم إرجاعه بواسطة بحث الأرقام المتاحة، بتنسيق E.164. |
| `country_code` | نعم | رمز البلد ISO 3166-1 alpha-2 (على سبيل المثال `US`). |
| `display_name` | لا | تسمية وصفية. يتم تعيينه افتراضياً إلى رقم الهاتف. |
| `category` | لا | تسمية فئة اختيارية. |

**الاستجابة**

```json
{
  "success": true,
  "phone_number": "+14155551234",
  "channel": "whatsapp",
  "whatsapp_status": "PURCHASED",
  "outgoing_status": "PURCHASED",
  "status": "PURCHASED",
  "purchase_credits": 50,
  "monthly_credits": 50
}
```

يبدأ الرقم في حالة `PURCHASED`. ثم يستمر تسجيل WhatsApp في الخلفية: `PURCHASED` -> `PENDING` -> `ONLINE`.

> إذا فشلت عملية الشراء بسبب فقدان عنوان النشاط التجاري أو عدم تعيين تفاصيل مطلوبة أخرى، فستتلقى `400` مع `error` وصفي. قم بإعداد التفاصيل المفقودة وحاول مرة أخرى.

### الخطوة 3 - الاستعلام حتى تصبح الحالة ONLINE

```
GET /phone-numbers/{phoneNumber}/status
```

هذه هي نقطة نهاية حالة رقم الهاتف المشتركة - وهي تعمل مع أرقام WhatsApp المشتراة بالإضافة إلى أرقامك الأخرى المتصلة.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/phone-numbers/+14155551234/status" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const phone = encodeURIComponent("+14155551234");
const res = await fetch(
  `https://api.youraiconnector.com/v1/phone-numbers/${phone}/status`,
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
// Poll until data.status === "ONLINE".
```

**Python**

```python
import urllib.parse

phone = urllib.parse.quote("+14155551234")
res = requests.get(
    f"https://api.youraiconnector.com/v1/phone-numbers/{phone}/status",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
# Poll until data["status"] == "ONLINE".
```

**الاستجابة**

```json
{
  "success": true,
  "phone_number": "+14155551234",
  "channel": "whatsapp",
  "status": "ONLINE",
  "status_reason": null,
  "live": true
}
```

### الخطوة 4 - تحرير رقم

```
DELETE /phone-numbers/{phoneNumber}
```

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/phone-numbers/+14155551234" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{ "success": true, "phone_number": "+14155551234", "released": true }
```

يعتمد ما يقوم به هذا الإجراء على هوية مالك الرقم.

بالنسبة لرقم **مستأجر من خلال المنصة**، فهو تحرير حقيقي: يتم إلغاء تسجيل مرسل WhatsApp، وإعادة الرقم إلى شركة الاتصالات وإزالته من الحساب، ويتم تطبيق فترة تهدئة مدتها 7 أيام لا يمكن خلالها إعادة شراء الرقم من قبل أي شخص، ولا يتم استرداد أي أرصدة.

بالنسبة للرقم الذي **جلب الحساب نفسه** (حسابه الخاص على Twilio، أو تطبيق Meta الخاص به، أو حساب WhatsApp Business، أو بوابة SMS تعمل بنظام Android)، فإن نفس الاستدعاء يقوم فقط بإزالته من الحساب. لا يتم تحرير أي شيء لدى المزود الأساسي ولا يتم كتابة أي فترة تهدئة، لذا يمكن إعادة توصيل الرقم على الفور. قد يظل تسجيل مرسل WhatsApp الخاص به، إذا كان موجوداً، قائماً أو لا: تحاول عملية الإلغاء حذف المرسل باستخدام بيانات اعتماد Twilio المُدارة بواسطة منصة الحساب. في الحساب الذي لا يزال يستخدم الإعداد المُدار، تكون بيانات الاعتماد هذه صالحة ويتم حذف المرسل، لذا فإن إعادة التوصيل تعني تسجيله مرة أخرى. أما في الحساب الذي تحول إلى استخدام Twilio الخاص به، فلا يمكن لعملية الحذف المصادقة، ويظل المرسل مسجلاً في ذلك الحساب — لذا فإن إعادة التوصيل هي مجرد إعادة ربط للمرسل الموجود بالفعل.

### إضافة رقم تمتلكه بالفعل (BYO)

```
POST /phone-numbers/byo
```

يتخطى مسار البحث والشراء المذكور أعلاه بالكامل. استخدم هذا عندما يجلب الحساب رقمه الخاص (Twilio الخاص به، أو حساب Meta WhatsApp Business الخاص به، أو بوابة Android SMS) بدلاً من استئجار رقم من خلال المنصة. هذا يسجل الرقم فقط - لا يتم خصم أرصدة، ولا يتم توفير أي شيء مع مزود الخدمة هنا. يظل الرقم غير نشط حتى يكمل صاحب الحساب عملية OAuth الخاصة بـ WhatsApp لتسجيل مرسل (Sender) عليه (وهو نفس المسار الذي يبدأه زر "Bring your own number" في لوحة التحكم).

| الحقل | مطلوب | الوصف |
|---|---|---|
| `phone_number` | نعم | الرقم المراد إضافته، بتنسيق E.164 (مثال: `+14155551234`). |
| `country_code` | نعم | رمز البلد ISO 3166-1 alpha-2 (مثال: `US`). |
| `display_name` | لا | تسمية ودية. يتم استخدام رقم الهاتف افتراضياً. |
| `category` | لا | تسمية فئة اختيارية. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/phone-numbers/byo?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "+14155551234",
    "country_code": "US",
    "display_name": "Support line"
  }'
```

**الاستجابة** (`201 Created`):

```json
{
  "success": true,
  "phone_number": "+14155551234",
  "channel": "whatsapp",
  "type": "BYO",
  "whatsapp_status": "ADDED",
  "outgoing_status": "ADDED",
  "is_active": false
}
```

أي `phone_number` ليس رقم E.164 حقيقياً (أو يبدو مثل رقم اختبار WhatsApp الخاص بـ Meta، والذي لا يمكنه مراسلة عملاء حقيقيين) يُرجع `400`. إضافة رقم موجود بالفعل في الحساب - حتى لو كان مكتوباً بشكل مختلف قليلاً، مثل صيغ المكسيك `+52` مقابل `+521` - يُرجع `409` بدلاً من إنشاء صف مكرر.

### تعيين رقم كرقم أساسي

```
POST /phone-numbers/{phoneNumber}/set-primary
```

يغير رقماً واحداً إلى `is_active: true` ويحول كل رقم آخر في الحساب إلى `is_active: false`، بشكل ذري - لا ينتهي الأمر بالحساب أبداً بوجود رقمين نشطين، أو بدون أي رقم، في منتصف الطلب. لا يمكن تعيين `is_active` من خلال نقطة نهاية التحديث العامة عن قصد؛ هذا الاستدعاء المخصص هو الطريقة الوحيدة لتغيير الرقم الأساسي.

```bash
curl -X POST "https://api.youraiconnector.com/v1/phone-numbers/+14155551234/set-primary" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{
  "success": true,
  "phone_number": {
    "id": "+14155551234",
    "phone_number": "+14155551234",
    "display_name": "Support line",
    "channel": "whatsapp",
    "is_active": true,
    "whatsapp_status": "ONLINE"
  }
}
```

`phone_number` هنا هو كائن الرقم الكامل (بنفس شكل `GET /phone-numbers` الذي يتم إرجاعه)، وليس مجرد سلسلة نصية. أي `phoneNumber` غير موجود في الحساب يُرجع `404`.

### إزالة سجل رقم (دون تحريره)

```
DELETE /phone-numbers/{phoneNumber}/record
```

حذف بسيط لسجل الرقم في هذا الحساب - لا يوجد تحرير أو إلغاء تسجيل من جانب المزود، ولا يتم تطبيق فترة تهدئة مدتها 7 أيام كما في خطوة التحرير أعلاه. استخدم هذا لمسح سجلات BYO أو WhatsApp Web أو Telegram أو LINE، أو أي إدخال قديم، دون المرور بمسار التحرير المُدار. على عكس التحرير، حذف رقم غير موجود في الحساب يُرجع `404`، وليس نجاحاً صامتاً.

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/phone-numbers/+14155551234/record" \
  -H "X-API-Key: YOUR_API_KEY"
```

**الاستجابة**

```json
{ "success": true, "phone_number": "+14155551234", "deleted": true }
```

---

## توجيه قناة إلى حملة

يؤدي ربط القناة إلى إدخال الرسائل **إلى** الحساب. ولا يحدد ذلك **وكيل الذكاء الاصطناعي الذي سيرد عليها**.

تتم إدارة التوجيه بواسطة **نقاط الدخول (Entry Points)** في وكيل الذكاء الاصطناعي، وليس بواسطة الحملات. لكل قناة نقطة دخول افتراضية واحدة تحدد الوكيل الذي يرد على جهات الاتصال الجديدة وغير المعروفة على تلك القناة:

| ما تريد القيام به | الاستدعاء |
|---|---|
| توجيه قناة إلى الوكيل الذي يجب أن يرد عليها | `PUT /entry-points/channel-defaults` مع نص `{ "channel": "instagram", "agent_id": "AGENT_ID" }` |
| التحقق مما إذا كان تسلسل نقاط الدخول مفعلاً للحساب | `GET /entry-points/routing-status`، والذي يُرجع `{ "success": true, "cutover_enabled": true }` بمجرد أن تحدد نقاط الدخول توجيه ذلك الحساب |
| ترك قناة بدون وكيل يرد عليها | `DELETE /entry-points/channel-defaults?channel=instagram` |

إلى أن تحتوي القناة على نقطة دخول (Entry Point)، تظل الرسالة الأولى من شخص لم تتحدث معه من قبل مخزنة، ولكن لا يتم التقاطها ولا يرد أي مساعد عليها. هذه هي الخطوة التي تفوتها معظم عمليات التكامل: ربط Instagram وإنشاء وكيل (Agent) ليس كافياً بحد ذاته — بل يجب عليك أيضاً توجيه القناة إلى الوكيل. المجموعة الكاملة من الاستدعاءات — بما في ذلك وكيل واحد لكل رقم WhatsApp، والكلمات المفتاحية، وقواعد التعليقات — موجودة في [واجهة برمجة تطبيقات نقاط الدخول (Entry Points API)](entry-points.md).

لا يزال `POST /channels/campaign` يكتب خريطة توجيه الحملة القديمة لكل قناة، الموثقة أدناه، ولكن لم يعد يتم الرجوع إلى تلك الخريطة لتوجيه الرسائل الواردة في أي حساب؛ يتم الاحتفاظ بها للتراجع فقط. لا تبنِ تطبيقاتك بناءً عليها.

### توجيه قناة واحدة أو أكثر (خريطة توجيه الحملة القديمة)

`POST /channels/campaign`

**حقول الطلب**

| الحقل | مطلوب | الوصف |
|---|---|---|
| `campaign_id` | نعم | الحملة التي يجب أن تجيب على جهات الاتصال الجديدة على هذه القنوات. يجب أن تنتمي إلى الحساب. |
| `channels` | نعم | مصفوفة غير فارغة من القنوات المراد توجيهها. المسموح به: `whatsapp`، `whatsapp_web`، `telegram`، `instagram`، `messenger`، `chat_widget`، `custom_channel`، `sms`، `email`. |

يتم تحديث فتحة التوجيه وقائمة `enabled_channels` الخاصة بالحملة معاً في عملية ذرية واحدة، بحيث لا يمكن أن يختلفا عن بعضهما أبداً. القناة الموجهة بالفعل إلى حملة مختلفة يتم ببساطة إعادة توجيهها إلى هذه الحملة.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/campaign?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "NBCXrhqGPSFsd6MV7pRo",
    "channels": ["instagram", "messenger"]
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/channels/campaign", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    campaign_id: "NBCXrhqGPSFsd6MV7pRo",
    channels: ["instagram", "messenger"],
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/channels/campaign",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "campaign_id": "NBCXrhqGPSFsd6MV7pRo",
        "channels": ["instagram", "messenger"],
    },
)
data = res.json()
```

**الاستجابة**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo",
  "channels": ["instagram", "messenger"]
}
```

### ما الذي يجب أن يتحقق لكي يعمل التوجيه فعلياً

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

| المتطلب | ما يحدث بخلاف ذلك |
|---|---|
| `type` هو `Incoming from Unknown Contacts` أو `Combined` | يتم رفض الطلب مع `400`. لا يمكن لحملات الصادر والكلمات المفتاحية الاحتفاظ بفتحة توجيه. |
| `status` هو `Live` | يتم تخزين التوجيه ولكنه لا يلتقط أي شيء. حملة `Draft` هي السبب الأكثر شيوعاً لـ "لقد قمت بتوجيهها ولا يحدث شيء". |
| `ai_mode` هو `true` | يتم إنشاء جهة الاتصال وتخزين الرسالة، لكن المساعد لا يرد أبداً. |

أصبحت مطابقة الكلمات المفتاحية الآن موجودة في نقاط الدخول — قم بإنشاء نقطة دخول من النوع `keyword` على وكيل الذكاء الاصطناعي الذي يجب أن يرد.

### حملة واحدة لكل قناة

تحتوي كل قناة على فتحة توجيه قديمة واحدة بالضبط. تؤدي إعادة توجيه حملة ثانية إلى نفس القناة إلى إعادة توجيه الفتحة بصمت وإرجاع `200` — لا يوجد خطأ تعارض. تستمر الحملة السابقة في التعامل مع جهات الاتصال التي لديها بالفعل؛ إنها تتوقف فقط عن تلقي جهات اتصال جديدة.

### مسح توجيه القناة

`DELETE /channels/campaign/{channel}`

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

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/channels/campaign/instagram?apiKey=YOUR_API_KEY"
```

**الاستجابة**

```json
{
  "success": true,
  "channel": "instagram",
  "cleared": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo"
}
```

هذه العملية متماثلة (idempotent): مسح قناة لم يتم توجيهها من قبل يعيد أيضاً `200`، مع `cleared: false` و `campaign_id: null`. تتطلب نقطة النهاية هذه ميزة **الحملات الواردة** في الخطة؛ وبدونها ستحصل على `403`.


---

## استخدم تطبيق Meta الخاص بك (Instagram + Messenger)

بشكل افتراضي، يعمل اتصال Instagram + Messenger من خلال تطبيق Meta الخاص بالمنصة، لذا فإن اسم ذلك التطبيق هو ما يراه صاحب الحساب على شاشة الموافقة في Facebook. إذا كنت تريد أن تظهر شاشة الموافقة علامتك التجارية **الخاصة** بدلاً من ذلك، يمكنك تسجيل تطبيق Meta الخاص بك وتوجيه العملية بأكملها من خلاله. بمجرد تكوينه، سيتم تطبيقه على حسابك — لا يتغير شيء في طلبات الاتصال المذكورة أعلاه باستثناء العلامة التجارية.

> **هذا يغطي Instagram + Messenger فقط.** اتصالات WhatsApp وWhatsApp Web وTelegram وLINE لا تتأثر بتطبيق Meta المخصص.

### ما يحتاجه تطبيقك أولاً

هذا هو الجزء الذي يستغرق وقتاً، ويحدث بالكامل من جانب Meta:

1. **تطبيق** من نوع Business، مع إضافة منتجات Messenger وInstagram إليه.
2. **وصول متقدم (Advanced Access)** (عبر مراجعة تطبيق Meta) لكل من: `pages_show_list`، `pages_messaging`، `pages_manage_metadata`، `pages_read_engagement`، `instagram_basic`، `instagram_manage_messages`. بدون الوصول المتقدم، لا يمكن إلا للأشخاص الذين لديهم دور في تطبيقك إكمال الاتصال — ستفشل اتصالات عملائك. تستغرق مراجعة التطبيق عادةً بضعة أسابيع وتتطلب التحقق من النشاط التجاري (Business Verification).
3. **تهيئة تسجيل الدخول عبر Facebook للأعمال (Facebook Login for Business)** التي تم إنشاؤها داخل تطبيقك، مع منح نفس الأذونات. معرف التهيئة الرقمي الخاص بها فريد لكل تطبيق، لذا يجب عليك إنشاء معرف خاص بك.

إذا كان تطبيقك يفتقد أياً من الأذونات المطلوبة، سيفشل الاتصال في وقت الاتصال مع ظهور خطأ واضح يحدد ما هو مفقود (مرئي في استطلاع `/status` كـ `byo_app_missing_permissions`) — بدلاً من أن يبدو وكأنه يعمل ثم يفشل عند إرسال الرسالة الأولى.

### الخطوة 1 - حفظ تطبيقك

`PUT /account-config/meta-app`

| الحقل | مطلوب | الوصف |
|---|---|---|
| `app_id` | نعم | معرف تطبيق Meta الخاص بك (الإعدادات ← أساسي). |
| `app_secret` | نعم | سر تطبيق Meta الخاص بك. يتم التحقق منه مقابل Meta قبل تخزينه، ثم يتم تشفيره. لا يتم إرجاعه أبداً بواسطة أي نقطة نهاية. |
| `config_id` | نعم | المعرف الرقمي لتهيئة تسجيل الدخول عبر Facebook للأعمال داخل تطبيقك. |

الثلاثة جميعها مطلوبة لتدفق تسجيل الدخول عبر Facebook. إذا كنت تقوم فقط بتشغيل مسار دفع رمز تسجيل الدخول عبر Instagram الموصوف أدناه، فيمكنك استبعادها تماماً.

```bash
curl -X PUT "https://api.youraiconnector.com/v1/account-config/meta-app?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "app_id": "1234567890123456",
    "app_secret": "your-app-secret",
    "config_id": "9876543210987654"
  }'
```

**الاستجابة**

```json
{
  "success": true,
  "app_id": "1234567890123456",
  "config_id": "9876543210987654",
  "verify_token": "1f4c…a9",
  "webhook_urls": {
    "instagram": "https://api.youraiconnector.com/v1/incoming-instagram-message/byo/YOUR_ACCOUNT_ID",
    "messenger": "https://api.youraiconnector.com/v1/incoming-messenger-message/byo/YOUR_ACCOUNT_ID"
  }
}
```

### الخطوة 2 - تهيئة تطبيقك للتواصل معنا

في لوحة تحكم تطبيق Meta الخاص بك:

1. **Webhooks** - لكل من منتجي Instagram وMessenger، اضبط عنوان URL للاستدعاء (Callback URL) على قيمة `webhook_urls` المطابقة من الاستجابة، ورمز التحقق (Verify token) على `verify_token`. اشترك في الحقول `messages` و`messaging_postbacks` و`comments`.
2. **عناوين URI لإعادة توجيه OAuth صالحة** - أضف `https://api.youraiconnector.com/v1/auth-meta-callback-handler` حتى يتمكن تدفق الموافقة من العودة.

`GET /account-config/meta-app` تعيد نفس مواد الإعداد في أي وقت؛ `DELETE /account-config/meta-app` تزيل التطبيق (ستعود الاتصالات المستقبلية إلى تطبيق المنصة — قم أيضاً بإزالة اشتراك الويب هوك داخل تطبيقك).

### الخطوة 3 - اتصل كالمعتاد

لا يتغير أي شيء آخر. تستخدم `POST /channels/meta/connect` (وصفحة `connect_url` المستضافة) تطبيقك تلقائياً لحسابك؛ ويؤكد `uses_byo_meta_app: true` الخاص بالاستجابة التطبيق الذي ستعرضه شاشة الموافقة. تعمل عمليات إرسال الرسائل واختيار الصفحة وقطع الاتصال بشكل متطابق.

## أحضر تطبيق تسجيل الدخول الخاص بـ Instagram (دفع الرموز المميزة)

يغطي القسم أعلاه تدفق تسجيل الدخول عبر فيسبوك، حيث يتم ربط الحساب من خلال صفحة فيسبوك. توفر Meta أيضًا **واجهة برمجة تطبيقات Instagram مع تسجيل الدخول عبر Instagram** (تسجيل دخول الأعمال لـ Instagram): حيث يقوم صاحب الحساب بالمصادقة على Instagram نفسه، دون الحاجة إلى حساب فيسبوك أو صفحة فيسبوك.

إذا كانت منصتك تشغل بالفعل تطبيق Meta الخاص بها مع هذا المنتج، فلن تحتاج إلى أي تدفق OAuth من جانبنا على الإطلاق. يقوم عملاؤك بتفويض **تطبيقك**، وتقوم أنت بدفع بيانات الاعتماد الجاهزة لكل حساب إلينا:

1. تقوم بحفظ بيانات اعتماد تطبيق Instagram الخاص بك مرة واحدة (حتى نتمكن من التحقق من خطافات الويب الخاصة بك).
2. لكل حساب، تقوم بدفع معرف حساب Instagram الاحترافي + رمز مستخدم Instagram طويل الأمد الذي حصل عليه تطبيقك.
3. تقوم بتوجيه خطاف ويب مراسلة Instagram الخاص بتطبيقك إلينا. يتم الإقرار بالأحداث الخاصة بالحسابات التي لم تقم بدفعها وتجاهلها.
4. أنت تمتلك دورة حياة الرمز المميز: قم بتحديث الرموز المميزة في نظامك الخاص وادفع كل رمز مميز محدث بنفس الاستدعاء. نحن لا نقوم أبدًا بتحديث رمز مميز تم دفعه.

### ما يحتاجه تطبيقك أولاً

- منتج **Instagram** ("إعداد واجهة برمجة التطبيقات مع تسجيل الدخول عبر Instagram") المضاف إلى تطبيق Meta الخاص بك. يحتوي هذا المنتج على **زوج معرف التطبيق وسر التطبيق الخاص به**، منفصل عن معرف/سر تطبيق فيسبوك — يمكنك العثور عليهما في لوحة إعداد المنتج.
- **وصول متقدم** (عبر مراجعة تطبيق Meta) لـ `instagram_business_basic` و `instagram_business_manage_messages` (أضف `instagram_business_manage_comments` إذا كنت تستخدم أتمتة التعليقات). بدون ذلك، يمكن فقط للأشخاص الذين لديهم دور في تطبيقك تفويضه.

### الخطوة 1 - حفظ بيانات اعتماد تطبيق Instagram الخاص بك

نفس نقطة النهاية المذكورة أعلاه — أرسل زوج Instagram إلى `PUT /account-config/meta-app`. حقول Facebook ليست مطلوبة لهذا المسار: أرسل الزوج بمفرده إذا كنت تشغل تسجيل الدخول عبر Instagram فقط، أو أرسله مع حقول Facebook إذا كنت تشغل كليهما. الحفظ يصف دائماً الإعداد بالكامل، لذا فإن أي مجموعة تتركها سيتم إزالتها.

| الحقل | مطلوب | الوصف |
|---|---|---|
| `instagram_app_id` | معًا | معرف التطبيق الرقمي الخاص بمنتج Instagram (وليس معرف تطبيق فيسبوك). |
| `instagram_app_secret` | معًا | سر التطبيق الخاص بمنتج Instagram. مشفر في حالة السكون، ولا يتم إرجاعه أبدًا. |

```bash
curl -X PUT "https://api.youraiconnector.com/v1/account-config/meta-app?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "instagram_app_id": "1122334455667788",
    "instagram_app_secret": "your-instagram-app-secret"
  }'
```

**الاستجابة** — تحمل رابط webhook الخاص بتسجيل الدخول عبر Instagram (رابطا `instagram` و `messenger` يظهران فقط عند تخزين حقول Facebook أيضاً):

```json
{
  "success": true,
  "instagram_app_id": "1122334455667788",
  "verify_token": "1f4c…a9",
  "webhook_urls": {
    "instagram_login": "https://api.youraiconnector.com/v1/incoming-instagram-login-message/byo/YOUR_ACCOUNT_ID"
  }
}
```

في لوحة **خطافات الويب (Webhooks)** الخاصة بتطبيقك لمنتج Instagram، قم بتعيين عنوان URL للاستدعاء (Callback URL) إلى `webhook_urls.instagram_login`، ورمز التحقق (Verify token) إلى `verify_token`، واشترك في حقلي `messages` و `comments`.

### الخطوة 2 - دفع رمز مميز لكل حساب

`PUT /channels/instagram-login/token`

يعمل مع `sub_account_id` مثل أي مسار آخر، لذا يمكن لمفتاح الوكالة توفير أسطولها بالكامل.

| الحقل | مطلوب | الوصف |
|---|---|---|
| `ig_user_id` | نعم | **معرف حساب Instagram الاحترافي** — حقل `user_id` من `GET https://graph.instagram.com/v21.0/me?fields=user_id,username`. هذا هو نفس المعرف الذي تحمله خطافات ويب Instagram كـ `entry.id`. ⚠️ إنه **ليس** حقل `id` من `/me` — هذا الحقل خاص بالتطبيق ويختلف باختلاف تطبيق Meta. دفع المعرف الخاص بالتطبيق يعيد `400` يوضح الخطأ. |
| `access_token` | نعم | رمز مستخدم Instagram طويل الأمد الذي حصل عليه تطبيقك لهذا الحساب. يتم التحقق منه مباشرة مقابل Instagram قبل تخزينه: يجب أن يعمل الرمز المميز ويجب أن ينتمي إلى `ig_user_id`. |
| `expires_at` | لا | تاريخ انتهاء صلاحية الرمز المميز بتنسيق ISO-8601. بدلاً من ذلك، أرسل `expires_in` (بالثواني). الافتراضي هو 60 يومًا. |
| `username` | لا | اسم المستخدم (@handle) للحساب؛ نقوم بقراءته من Instagram على أي حال. |

```bash
curl -X PUT "https://api.youraiconnector.com/v1/channels/instagram-login/token?apiKey=YOUR_AGENCY_KEY&sub_account_id=CLIENT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "ig_user_id": "17841400000000000",
    "access_token": "IGAAR…",
    "expires_at": "2026-11-01T00:00:00Z"
  }'
```

**الاستجابة**

```json
{
  "success": true,
  "ig_user_id": "17841400000000000",
  "username": "acme.studio",
  "expires_at": "2026-11-01T00:00:00.000Z",
  "webhook_url": "https://api.youraiconnector.com/v1/incoming-instagram-login-message/byo/YOUR_ACCOUNT_ID"
}
```

كجزء من عملية الدفع، نقوم باشتراك تطبيقك في خطافات ويب ذلك الحساب (`subscribed_apps` مع الرمز المميز المدفوع)، بحيث تبدأ الرسائل في التدفق دون أي استدعاء إضافي من جانبك.

**التحديث** - ادفع الرمز المحدّث إلى نفس نقطة النهاية باستخدام نفس `ig_user_id`؛ حيث يقوم بتحديث الرمز المخزن وتاريخ انتهاء صلاحيته في مكانه.

**التعارضات** - لا يمكن أن يكون حساب Instagram نشطاً على اتصالين في نفس الوقت. إذا كان الحساب متصلاً بالفعل في مكان آخر، أو على هذا الحساب نفسه من خلال تدفق صفحة Facebook، فإن عملية الدفع تُرجع `409` يخبرك بالاتصال الذي يجب فصله أولاً. لا يتم استبدال اتصال تدفق Facebook تلقائياً أبداً، لأنه قد يخدم أيضاً Messenger.

### الخطوة 3 - قطع الاتصال عند مغادرة العميل

`DELETE /channels/instagram-login/token` (نفس المصادقة و `sub_account_id`) تلغي اشتراك خطافات الويب (webhooks) بأفضل جهد ممكن وتزيل بيانات الاعتماد المخزنة. تنجح هذه العملية دائماً، حتى عندما يكون الرمز قد انتهت صلاحيته بالفعل - وبمجرد زوال بيانات الاعتماد، يتم تجاهل أحداث خطاف الويب الخاصة بذلك الحساب.

---

## نصائح لبناء غلاف (wrapper) موثوق

- **استخدم الاستطلاع (Polling) بلطف.** بضع ثوانٍ كافية. توقف بمجرد الوصول إلى حالة نهائية (`connected` / `ONLINE`، أو حالة فشل)، وضع مهلة زمنية إجمالية معقولة للحلقة (تنتهي صلاحية خطوات المتصفح/QR، راجع كل `expires_at`).
- **استخدم ترميز URL لأرقام الهواتف في المسار.** يجب إرسال علامة `+` البادئة كـ `%2B`. تستعيد نقاط النهاية الأرقام المجردة أيضاً، ولكن الترميز هو الخيار الآمن الافتراضي.
- **لا تتوقع أبداً استعادة الأسرار.** يتم قبول أو تخزين رموز الوصول (Access tokens)، وأسرار القناة، ورموز الصفحة، ولكن لا يتم إرجاعها أبداً في أي استجابة.
- **تعامل مع بوابة المصادقة.** يعني `403` أن الوصول إلى API غير مشمول في الخطة، أو أن القناة التي تحاول ربطها غير مدرجة في خطة الحساب. راجع [الوصول إلى API](../integrations/api-access.md).
- **انتبه لحدود المعدل (Rate limit).** الطلبات الموثقة محدودة بـ 300 طلب في الدقيقة؛ يعني `429` ضرورة التوقف مؤقتاً وإعادة المحاولة. راجع [المصادقة](authentication.md).

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

- [المصادقة](authentication.md) - نماذج المصادقة الأربعة المقبولة وتنسيق الخطأ.
- [الوصول إلى واجهة برمجة التطبيقات](../integrations/api-access.md) - إنشاء وإدارة مفتاح واجهة برمجة التطبيقات الخاص بك.
