
# API לחיבור ערוצים

מדריך זה מראה כיצד לחבר ערוצי הודעות לחשבון באמצעות ה-API. הוא נכתב עבור מפתח שבונה אינטגרציה או מעטפת (wrapper), ולכן הוא מתמקד בבקשות המדויקות, בסדר שבו יש לבצע אותן, ובתגובות שמתקבלות בחזרה.

יש תבנית אחת שצריך להבין מראש, כיוון שהיא חלה על כמעט כל ערוץ כאן.

## תבנית החיבור-ואז-סקר (connect-then-poll)

את רוב הערוצים לא ניתן לחבר באמצעות קריאת API בודדת. חיבור WhatsApp, Instagram או Messenger אומר שבעל החשבון צריך להתחבר לחשבון הספק שלו ולאשר גישה. **אין מסלול ללא ממשק (אוטומטי לחלוטין)** עבור אישור זה - אדם אמיתי חייב לפתוח כתובת URL בדפדפן, או לסרוק קוד QR עם הטלפון שלו.

לכן התהליך הוא תמיד:

1. **התחלת החיבור** עם `POST`. התגובה נותנת לך או כתובת URL לפתיחה, או קוד QR להצגה.
2. **העברת המידע למשתמש הקצה** - פתיחת ה-URL בדפדפן שלו, או הצגת קוד ה-QR על המסך כדי שיסרוק אותו.
3. **סקר (Polling) של נקודת הקצה של הסטטוס** עם `GET` במרווחי זמן קצרים (כל כמה שניות) עד שהסטטוס מגיע למצב מחובר.

התפקיד של האינטגרציה שלך הוא להניע את הלולאה הזו: להציג את ה-URL או ה-QR, ואז לבצע סקר עד לסיום. תכנן את ממשק המשתמש שלך סביב הסקר - ספינר עם הודעה כמו "ממתין שתסיים בדפדפן" עובד היטב.

::: note
**הערה:** לפני שתתחיל, ודא שגישת API מופעלת בתוכנית שלך ושיש ברשותך מפתח API. עיין ב-[גישת API](../integrations/api-access.md) כדי ללמוד כיצד ליצור אחד. כל הבקשות להלן משתמשות בכתובת ה-URL הבסיסית `https://api.youraiconnector.com/v1` ועליך לאמת כל בקשה. עיין ב-[אימות](authentication.md) עבור ארבעת הסוגים המקובלים - הדוגמאות כאן משתמשות בכותרת `X-API-Key`, כאשר בכל עמוד מופיעה דוגמת cURL אחת המציגה את צורת השאילתה הפשוטה יותר `?apiKey=`.
:::


---

## אינסטגרם + מסנג'ר (Meta)

אינסטגרם ומסנג'ר מחוברים יחד בתהליך אחד, כיוון ששניהם פועלים על דף פייסבוק. בעל החשבון מאשר דרך פייסבוק, אתה מושך את רשימת הדפים שהוא מנהל, ואתה בוחר איזה דף לחבר.

### שלב 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` בדפדפן של משתמש הקצה כדי שיוכל להתחבר לפייסבוק ולאשר גישה. ניסיון החיבור יפוג ב-`expires_at` (כ-30 דקות) - אם הוא פג, התחל מחדש. התייחס ל-`state_token` כאל סוד לטווח קצר ואל תתעד אותו בלוגים.

### האפשרות הקלה ביותר עבור Instagram + Messenger: העברת `connect_url`

התגובה כוללת גם `connect_url` מוכן לשימוש: דף מאוחסן שמריץ את כל התהליך עבור בעל החשבון. הם פותחים אותו, מתחברים ל-Facebook, וכאשר יש להם יותר מדף אחד, הוא מציג את הרשימה ומאפשר להם לבחור איזה מהם לחבר - לאחר מכן הוא מדווח על הצלחה בעצמו. תנו קישור זה לבעל החשבון במקום לפתוח את `oauth_url` בעצמכם, לבנות בורר דפים ולבצע סקר (polling). הקישור עובד למשך כ-30 דקות (`connect_url_expires_at`); אם הוא פג, התחילו חיבור חדש. השלבים הידניים להלן מיועדים לאינטגרציות שרוצות להוביל את התהליך ולהציג את בורר הדפים בעצמן.

### שלב 2 - בצע סקר (poll) אחר הסטטוס עד לטעינת הדפים

```
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. זהו המקור שממנו תציג בורר (picker) כאשר תגדיר נקודת כניסה (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` | מה לעשות |
|---|---|
| _(absent)_ | שום דף אינו מחובר עדיין - הרץ תחילה את תהליך החיבור. |
| `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 }
```

פעולה זו עוצרת את ניתוב הנכנסים עבור אינסטגרם ומסנג'ר כאחד. היא אידמפוטנטית - קריאה לה כאשר שום דבר אינו מחובר עדיין תצליח.

---

## WhatsApp Business

פעולה זו מחברת מספר WhatsApp Business רשמי. המספר חייב להיות קיים בחשבון לפני שתקרא לחיבור. בדומה ל-Meta, בעל החשבון מאשר בדפדפן שלו, ולאחר מכן עליך לבצע סקר (poll) עד שהמספר מדווח על `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 - ביצוע סקר (poll) לסטטוס עד למצב ONLINE

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

בצע סקר (poll) לזה עד ש-`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` פירושו שהוא הגיע מהמצב השמור האחרון (cached state).

### ניתוק מספר 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 והצגתו, ולאחר מכן ביצוע סקר (polling) עד שהסטטוס הוא `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/כפתור) ובקש מהם לסרוק אותו באמצעות WhatsApp - אינך צריך להביא את ה-QR או לבצע סקר (poll) בעצמך. הקישור עובד למשך כ-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` הוא ה-payload הגולמי אם אתה מעדיף ליצור את התמונה בעצמך.

קוד ה-QR הוא בעל תוקף קצר. אם תקרא לזה מיד לאחר התחלת הסשן, ייתכן שתקבל `404` עם "QR code not available yet" - פשוט המתן רגע ונסה שוב. אם קיבלת `410` ("QR code expired"), התחל את החיבור מחדש כדי לקבל קוד טרי.

### שלב 3 - ביצוע סקר (polling) לסטטוס עד לחיבור

```
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" }
```

פעולה זו מנתקת את המכשיר ומסירה את החיבור. היא תמיד מנקה את המצב המקומי, לכן היא אידמפוטנטית גם אם הסשן הבסיסי כבר לא היה קיים.

---

## 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" }
```

אידמפוטנטי - קריאות חוזרות יצליחו.

---

## Instagram (חשבון אישי)

> בטא בזמינות מוגבלת, מופעלת לפי חשבון. זה מחבר חשבון Instagram אישי על ידי התחברות עם שם המשתמש והסיסמה שלו (לא ה-Business API הרשמי). אם החשבון אינו מופעל עבור הבטא, קריאת החיבור מחזירה שגיאת הרשאה.

מכיוון שזה דורש את פרטי ההתחברות ל-Instagram של בעל החשבון עצמו, הדרך הפשוטה ביותר היא לתת להם את ה-`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 מציגה נקודת ביקורת (checkpoint), `status` יחזור כ-`two_factor_required` או `challenge_required` - שלח את הקוד ל-`/connect/{id}/verify-2fa` או `/connect/{id}/verify-challenge` להלן, ולאחר מכן בצע סקר (poll) ל-`/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
```

בצע סקר (poll) לזה עד ש-`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` אומר שזה נקרא בשידור חי מ-worker החיבור ולא כערך שנשמר במטמון.

### האפשרות הקלה ביותר עבור Instagram (אישי): העברת `connect_url`

התגובה כוללת `connect_url`: דף מאוחסן שבו בעל החשבון מזין את שם המשתמש והסיסמה שלו ל-Instagram (וקוד אימות דו-שלבי או קוד נקודת ביקורת אם Instagram מבקשת זאת), והוא מדווח על הצלחה בעצמו. פרטי ההתחברות עוברים ישירות ל-Instagram ואינם נשמרים. תנו קישור זה לבעל החשבון במקום לאסוף את הסיסמה שלו בממשק שלכם. הקישור עובד למשך כ-30 דקות (`connect_url_expires_at`).

### ניתוק אינסטגרם (אישי)

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

אידמפוטנטי - קריאות חוזרות יצליחו.

### סנכרון עוקבים

```
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, מעתיק שני ערכים, ואתה מגיש אותם בקריאה אחת. לאחר מכן אתה נותן לו בחזרה כתובת URL של 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` | כן | אסימון הגישה (access token) ארוך הטווח של ערוץ ה-Messaging API של החשבון הרשמי. משמש לשליחה וקבלה של הודעות. |
| `channel_secret` | כן | ה-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 Official Account Manager. התנה את תהליך ה-onboarding שלך בדגל זה והנחה את הלקוח להחליף את המצב.

> ה-`channel_access_token` וה-`channel_secret` לעולם לא יוחזרו על ידי אף נקודת קצה (endpoint). שמור אותם בצד שלך אם תזדקק להם שוב; אחרת, העתק אותם מחדש מקונסולת 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

Viber מתחבר באותה דרך שבה LINE מתחבר - הדבקת אסימון האימות (auth token) של הבוט מלוח הבקרה של Viber בקריאה אחת - עם הבדל אחד שכדאי לדעת: החיבור גם רושם את ה-webhook שלנו בבוט שלך באותו רגע, כך שאין צעד נפרד בקונסולה לאחר מכן. זה גם אומר שניסיון חיבור יכול להיכשל אם ה-ingress שלנו לא יכול לענות לבדיקת ה-webhook הסינכרונית של Viber, ולא רק אם האסימון עצמו שגוי.

### שלב 1 - התחברות עם אסימון האימות של הבוט

```
POST /channels/viber
```

| שדה | נדרש | תיאור |
|---|---|---|
| `auth_token` | כן | אסימון האימות של הבוט, מלוח הבקרה של Viber (הגדרות הבוט שלי). |

```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` הוא מזהה החיבור המשמש את קריאות הסטטוס, האימות והניתוק להלן.

### בדיקת סטטוס Viber

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

מדווח על מצב החיבור השמור. הוסף את `?live=true` כדי לבצע בדיקה חוזרת של הבוט מול Viber ולרענן את רישום ה-webhook השמור במטמון - שימושי לפני שמניחים שבוט שקט הוא אכן תקול.

```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` אומר שה-webhook של הבוט כבר לא מצביע עלינו - הודעות נכנסות אובדות. זה בדרך כלל אומר שכלי אחר חיבר את אותו בוט לאחר מכן (רישום ה-webhook של Viber הוא בשיטת "האחרון שכותב מנצח"). תקן זאת עם קריאת האימות מחדש להלן, אין צורך לבקש מהלקוח להדביק מחדש את האסימון שלו. `live` הוא `false` כאשר התגובה היא המצב האחרון שנשמר במטמון במקום בדיקה רעננה מול Viber.

### רישום מחדש של ה-webhook

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

פעולת התיקון עבור `webhook_ok: false` - רושמת מחדש את ה-webhook שלנו בבוט באמצעות אסימון האימות שכבר נשמר.

```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 Business Messaging הוא ערוץ OAuth מלא בדומה ל-Meta, אך פשוט יותר בצד ה-polling: אין שלב ייעודי של בדיקת סטטוס (status-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 Business, הידוע לאחר שהתבצע ה-callback של ה-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` כאן - השדות משקפים את מה ש-connect (או רענון האסימון האחרון) כתב. `status: "reauth_required"` עם `status_reason` מוגדר אומר שהחשבון צריך לעבור שוב דרך connect; אסימוני 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` | לא | באיזו רשימת Marketplace של GHL לבצע את האישור. ברירת המחדל היא הרשימה הסטנדרטית - רלוונטי רק אם לפריסה שלך מוגדרת יותר מאפליקציית 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 ולאשר גישה. המצב (state) יפוג ב-`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}
```

מוחק את החיבור כאן, מה שעוצר כל סנכרון וטריגר עבור אותו מיקום. פעולה זו אינה מסירה את האפליקציה מצד GHL - הלקוח מסיר אותה מהתקנות ה-Marketplace של GHL אם הוא מעוניין בכך גם כן.

```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 ישירות. חפש מספרים זמינים, רכוש אחד, ולאחר מכן בצע סקר (poll) עד לסיום ההקצאה.

::: note
**הערה:** מספרים שנרכשים כאן תומכים ב-WhatsApp. רישום השולח ב-WhatsApp מתבצע ברקע לאחר הרכישה, לכן עליך לבצע סקר (poll) על הסטטוס עד שהוא מגיע ל-`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 - סקר (Poll) עד למצב 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 משלו, חשבון WhatsApp Business של Meta משלו, או שער SMS של Android) במקום לשכור אחד דרך הפלטפורמה. פעולה זו רק מתעדת את המספר - לא נגבים קרדיטים, ושום דבר לא מוקצה עם ספק כאן. המספר נשאר לא פעיל עד שבעל החשבון ישלים את תהליך ה-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 }
```

---

## ניתוב ערוץ לקמפיין

חיבור ערוץ מכניס הודעות **אל תוך** החשבון. הוא לא קובע **איזה סוכן AI יענה להן**.

ניתוב מנוהל על ידי **נקודות כניסה** (Entry Points) בסוכן AI, ולא על ידי קמפיינים. לכל ערוץ יש נקודת כניסה אחת המוגדרת כברירת מחדל לערוץ, המציינת את הסוכן שיענה לאנשי קשר חדשים ולא מוכרים בערוץ זה:

| מה ברצונך לעשות | קריאה |
|---|---|
| הפניית ערוץ לסוכן שאמור לענות לו | `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), הודעה ראשונה ממישהו שמעולם לא דיברת איתו עדיין נשמרת, אך דבר לא מושך אותה ואף עוזר לא משיב. זהו השלב שרוב האינטגרציות מפספסות: חיבור אינסטגרם ויצירת סוכן (Agent) אינם מספיקים כשלעצמם — עליך גם להפנות את הערוץ אל הסוכן. מערך הקריאות המלא — כולל סוכן אחד לכל מספר WhatsApp, מילות מפתח וכללי תגובות — נמצא ב-[Entry Points API](entry-points.md).

`POST /channels/campaign` עדיין כותב את מפת ניתוב הקמפיינים הישנה (legacy) לכל ערוץ, המתועדת להלן, אך מפה זו אינה נבדקת יותר עבור ניתוב נכנס באף חשבון; היא נשמרת לצורך שחזור בלבד. אל תבנה על בסיס זה.

### ניתוב ערוץ אחד או יותר (מפת ניתוב קמפיינים ישנה)

`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` בסוכן ה-AI שאמור לענות.

### קמפיין אחד לכל ערוץ

כל ערוץ מחזיק בדיוק משבצת ניתוב ישנה אחת. ניתוב קמפיין שני לאותו ערוץ מפנה מחדש את המשבצת בשקט ומחזיר `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"
}
```

פעולה זו היא אידמפוטנטית: ניקוי ערוץ שמעולם לא נותב מחזיר גם הוא `200`, עם `cleared: false` ו-`campaign_id: null`. נקודת קצה זו דורשת את התכונה **קמפיינים נכנסים** (incoming campaigns) בתוכנית; ללא תכונה זו תקבל `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 App Review) עבור: `pages_show_list`, `pages_messaging`, `pages_manage_metadata`, `pages_read_engagement`, `instagram_basic`, `instagram_manage_messages`. ללא גישה מתקדמת, רק אנשים שמחזיקים בתפקיד באפליקציה שלך יוכלו להשלים את החיבור — החיבורים של הלקוחות שלך ייכשלו. סקירת אפליקציה (App Review) אורכת בדרך כלל כמה שבועות ודורשת אימות עסק (Business Verification).
3. **הגדרת Facebook Login for Business** שנוצרה בתוך האפליקציה שלך, המעניקה את אותן הרשאות. מזהה ההגדרה המספרי שלה הוא לכל אפליקציה, לכן עליך ליצור משלך.

אם לאפליקציה שלך חסרות הרשאות נדרשות כלשהן, החיבור ייכשל בזמן החיבור עם שגיאה ברורה המציינת מה חסר (ניתן לראות ב-`/status` poll כ-`byo_app_missing_permissions`) — במקום להיראות כאילו הוא עובד ולהיכשל בהודעה הראשונה.

### שלב 1 - שמור את האפליקציה שלך

`PUT /account-config/meta-app`

| שדה | נדרש | תיאור |
|---|---|---|
| `app_id` | כן | מזהה אפליקציית Meta שלך (הגדרות ← בסיסי). |
| `app_secret` | כן | ה-Secret של אפליקציית Meta שלך. מאומת מול Meta לפני שהוא נשמר, ולאחר מכן מוצפן. לעולם לא מוחזר על ידי אף נקודת קצה. |
| `config_id` | כן | המזהה המספרי של הגדרת Facebook Login for Business בתוך האפליקציה שלך. |

כל השלושה נדרשים עבור תהליך ההתחברות לפייסבוק. אם אתה מריץ רק את נתיב דחיפת האסימון (token-push) של התחברות לאינסטגרם המתואר בהמשך, באפשרותך להשמיט אותם לחלוטין.

```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, הגדר את ה-Callback URL לערך ה-`webhook_urls` התואם מהתגובה, ואת ה-Verify token ל-`verify_token`. הירשם לשדות `messages`, `messaging_postbacks` ו-`comments`.
2. **Valid OAuth Redirect URIs** - הוסף את `https://api.youraiconnector.com/v1/auth-meta-callback-handler` כדי שתהליך האישור יוכל לחזור.

`GET /account-config/meta-app` מחזיר את אותו חומר הגדרה בכל עת; `DELETE /account-config/meta-app` מסיר את האפליקציה (חיבורים עתידיים יחזרו לאפליקציית הפלטפורמה — יש להסיר גם את הרישום ל-webhook בתוך האפליקציה שלך).

### שלב 3 - התחבר כרגיל

שום דבר אחר לא משתנה. `POST /channels/meta/connect` (ודף ה-`connect_url` המתארח) משתמשים באופן אוטומטי באפליקציה שלך עבור החשבון שלך; ה-`uses_byo_meta_app: true` של התגובה מאשר איזו אפליקציה תוצג במסך ההסכמה. שליחת הודעות, בחירת דפים וניתוקים עובדים באופן זהה.

## הבא את אפליקציית ההתחברות לאינסטגרם שלך (דחיפת אסימון)

הסעיף לעיל מכסה את תהליך ההתחברות לפייסבוק, שבו החשבון מתחבר דרך דף פייסבוק. מטא מציעה גם את **Instagram API עם התחברות לאינסטגרם** (התחברות עסקית לאינסטגרם): בעל החשבון מבצע אימות באינסטגרם עצמו, ללא מעורבות של חשבון פייסבוק או דף.

אם הפלטפורמה שלך כבר מריצה אפליקציית מטא משלה עם המוצר הזה, אינך זקוק כלל לתהליך OAuth מצידנו. הלקוחות שלך מאשרים את האפליקציה **שלך**, ואתה דוחף לנו את אישור הכניסה המוכן עבור כל חשבון:

1. אתה שומר את אישורי האפליקציה שלך לאינסטגרם פעם אחת (כדי שנוכל לאמת את ה-webhooks שלך).
2. עבור כל חשבון, אתה דוחף את מזהה החשבון המקצועי של אינסטגרם + אסימון המשתמש ארוך הטווח של אינסטגרם שהאפליקציה שלך השיגה.
3. אתה מפנה את ה-webhook של הודעות האינסטגרם של האפליקציה שלך אלינו. אירועים עבור חשבונות שלא דחפת יאושרו ויתעלמו מהם.
4. אתה הבעלים של מחזור החיים של האסימון: רענן אסימונים במערכת שלך ודחוף כל אסימון רענן באותה קריאה. אנחנו לעולם לא מרעננים אסימון שנדחף.

### מה האפליקציה שלך צריכה קודם

- מוצר ה-**Instagram** ("הגדרת API עם התחברות לאינסטגרם") שנוסף לאפליקציית המטא שלך. למוצר זה יש **זוג מזהה אפליקציה וסוד אפליקציה משלו**, נפרדים ממזהה/סוד האפליקציה של פייסבוק — מצא אותם בלוח ההגדרות של המוצר.
- **גישה מתקדמת** (דרך בדיקת אפליקציות של מטא) עבור `instagram_business_basic` ו-`instagram_business_manage_messages` (הוסף את `instagram_business_manage_comments` אם אתה משתמש באוטומציות של תגובות). ללא גישה זו, רק אנשים בעלי תפקיד באפליקציה שלך יוכלו לאשר אותה.

### שלב 1 - שמור את אישורי אפליקציית האינסטגרם שלך

אותו נקודת קצה (endpoint) כמו לעיל — שלח את זוג האינסטגרם אל `PUT /account-config/meta-app`. השדות של פייסבוק אינם נחוצים עבור נתיב זה: שלח את הזוג לבדו אם התחברות לאינסטגרם היא כל מה שאתה מריץ, או יחד עם השדות של פייסבוק אם אתה מריץ את שניהם. שמירה תמיד מתארת את ההגדרה המלאה, לכן כל קבוצה שתשמיט תוסר.

| שדה | חובה | תיאור |
|---|---|---|
| `instagram_app_id` | יחד | מזהה האפליקציה המספרי של מוצר האינסטגרם עצמו (לא מזהה האפליקציה של פייסבוק). |
| `instagram_app_secret` | יחד | סוד האפליקציה של מוצר האינסטגרם עצמו. מוצפן במנוחה, לעולם לא מוחזר. |

```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"
  }'
```

**תגובה** — נושאת את כתובת ה-URL של ה-webhook להתחברות לאינסטגרם (כתובות ה-URL `instagram` ו-`messenger` מופיעות רק כאשר השדות של פייסבוק מאוחסנים גם הם):

```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** של האפליקציה שלך עבור מוצר האינסטגרם, הגדר את כתובת ה-Callback ל-`webhook_urls.instagram_login`, את אסימון האימות ל-`verify_token`, והירשם לשדות `messages` ו-`comments`.

### שלב 2 - דחוף אסימון לכל חשבון

`PUT /channels/instagram-login/token`

עובד עם `sub_account_id` כמו כל נתיב אחר, כך שמפתח סוכנות יכול לספק את כל הצי שלו.

| שדה | חובה | תיאור |
|---|---|---|
| `ig_user_id` | כן | **מזהה החשבון המקצועי של אינסטגרם** — השדה `user_id` מתוך `GET https://graph.instagram.com/v21.0/me?fields=user_id,username`. זהו אותו מזהה ש-webhooks של אינסטגרם נושאים כ-`entry.id`. ⚠️ זה **לא** השדה `id` מתוך `/me` — זה מוגבל לאפליקציה ומשתנה בין אפליקציות מטא. דחיפת המזהה המוגבל לאפליקציה תחזיר `400` המציין את הטעות. |
| `access_token` | כן | אסימון המשתמש ארוך הטווח של אינסטגרם שהאפליקציה שלך השיגה עבור אותו חשבון. מאומת בשידור חי מול אינסטגרם לפני שהוא נשמר: האסימון חייב לעבוד וחייב להיות שייך ל-`ig_user_id`. |
| `expires_at` | לא | תאריך תפוגה ISO-8601 של האסימון. לחלופין שלח `expires_in` (שניות). ברירת המחדל היא 60 יום. |
| `username` | לא | ה-@handle של החשבון; אנחנו קוראים אותו מאינסטגרם בכל מקרה. |

```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"
}
```

כחלק מהדחיפה, אנחנו רושמים את האפליקציה שלך ל-webhooks של אותו חשבון (`subscribed_apps` עם האסימון שנדחף), כך שהודעות מתחילות לזרום ללא כל קריאה נוספת מצידך.

**רענון** - שלחו את האסימון (token) המרוענן לאותו נקודת קצה (endpoint) עם אותו `ig_user_id`; הפעולה מעדכנת את האסימון השמור ואת תוקפו במקומו.

**התנגשויות** - חשבון אינסטגרם אחד לעולם לא יכול להיות פעיל בשני חיבורים בו-זמנית. אם החשבון כבר מחובר במקום אחר, או בחשבון זה דרך תהליך דף הפייסבוק, הפעולה תחזיר `409` המציין איזה חיבור יש לנתק תחילה. חיבור שנוצר דרך תהליך פייסבוק לעולם לא יוחלף באופן אוטומטי, מכיוון שהוא עשוי לשרת גם את Messenger.

### שלב 3 - ניתוק כאשר לקוח עוזב

`DELETE /channels/instagram-login/token` (אותו אימות ו-`sub_account_id`) מבטל את הרישום ל-webhooks כמיטב המאמצים ומסיר את האישור השמור. הפעולה תמיד מצליחה, גם כאשר האסימון כבר פג תוקף — וברגע שהאישור הוסר, אירועי ה-webhook של אותו חשבון יתעלמו.

---

## טיפים לבניית מעטפת (Wrapper) אמינה

- **בצע סקר בעדינות.** כל כמה שניות זה מספיק. עצור ברגע שאתה מגיע למצב סופי (`connected` / `ONLINE`, או סטטוס כשל), והגדר פסק זמן כללי הגיוני ללולאה (שלבי הדפדפן/QR פגים, ראה כל `expires_at`).
- **קודד מספרי טלפון ב-URL בנתיב.** ה-`+` המוביל צריך להישלח כ-`%2B`. נקודות הקצה משחזרות גם ספרות חשופות, אך קידוד הוא ברירת המחדל הבטוחה.
- **לעולם אל תצפה לקבל סודות בחזרה.** אסימוני גישה, סודות ערוץ ואסימוני דף מתקבלים או נשמרים אך לעולם אינם מוחזרים באף תגובה.
- **טפל בשער האימות.** `403` אומר שגישת API אינה כלולה בתוכנית, או שהערוץ שאתה מחבר אינו כלול בתוכנית של החשבון. ראה [גישת API](../integrations/api-access.md).
- **שים לב למגבלת הקצב.** בקשות מאומתות מוגבלות ל-300 לדקה; `429` אומר להמתין ולנסות שוב. ראה [אימות](authentication.md).

## צעדים הבאים

- [אימות](authentication.md) - ארבע צורות האימות המקובלות ופורמט השגיאות.
- [גישת API](../integrations/api-access.md) - יצירה וניהול של מפתח ה-API שלך.
