
# הודעות ושיחות

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

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

> **כיצד פועלת המסירה:** שליחת הודעה **אינה** ממתינה להגעתה. ה-API מקבל את ההודעה שלך, מחזיר מיד מזהה הודעה, ולאחר מכן מוסר אותה ברקע בערוץ של איש הקשר (WhatsApp, SMS, Instagram וכן הלאה). כדי לעקוב אם הודעה אכן נמסרה או נקראה, האזן לעדכוני סטטוס באמצעות [Webhooks](webhooks.md) — אל תבצע סקר (polling). תגובת השליחה מאשרת רק שההודעה התקבלה.

---

## שליחת הודעה

קיימות שתי דרכים לשלוח הודעה. בחר את הדרך המתאימה לאופן שבו אתה כבר מזהה את איש הקשר:

- **שליחה לפי מזהה איש קשר** — אתה כבר מכיר את המזהה של איש הקשר (למשל, יצרת את איש הקשר דרך ה-API או קיבלת אותו מ-webhook). השתמש ב-`POST /contacts/{contactId}/send-message`.
- **שליחה לפי זהות איש קשר** — אתה מכיר את מספר הטלפון של איש הקשר, מזהה ה-Instagram שלו וכו', אך לא את המזהה הפנימי שלו. השתמש ב-`POST /contacts/send` ותן לפלטפורמה למצוא את איש הקשר הנכון.

שתי הדרכים מכניסות את ההודעה לתור באותו אופן ומוסרות אותה בערוץ שבו נמצא איש הקשר. אתה לא בוחר את אמצעי התעבורה — הפלטפורמה מנתבת אנשי קשר של WhatsApp דרך WhatsApp, אנשי קשר של SMS דרך SMS, וכן הלאה.

### שליחה לפי מזהה איש קשר

`POST /contacts/{contactId}/send-message`

| שדה | נדרש | תיאור |
|---|---|---|
| `body` | כן | טקסט ההודעה לשליחה. |
| `mediaUrl` | לא | כתובת URL של קובץ מדיה (תמונה, מסמך וכו') לצירוף. |
| `mediaContentType` | לא | סוג MIME של המדיה המצורפת, לדוגמה `image/jpeg`. |
| `pauseBot` | לא | `true` משהה את ה-AI עבור איש קשר זה בעת שליחת ההודעה — עבור השתלטות אנושית. ראו [השהיה או חידוש של ה-AI](#pause-or-resume-the-ai-for-one-contact). |
| `clearIncompleteReply` | לא | `true` מבטל תשובת בוט חצי-גמורה כך שלא תתחדש לאחר ההודעה שלך. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/send-message" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Hi! Your appointment is confirmed for tomorrow at 10:00."
  }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/send-message",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      body: "Hi! Your appointment is confirmed for tomorrow at 10:00.",
    }),
  }
);
const data = await res.json();
console.log(data.messageId);
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/send-message",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"body": "Hi! Your appointment is confirmed for tomorrow at 10:00."},
)
print(res.json()["messageId"])
```

**תגובה** (`200 OK`):

```json
{
  "success": true,
  "messageId": "aB3dE5fG7hI9jK1lM2nO",
  "contactId": "contact123",
  "channel": "whatsapp",
  "message": "Message created successfully. Delivery is being processed."
}
```

### שליחה לפי זהות איש קשר

`POST /contacts/send`

השתמש בזה כאשר אין לך את המזהה הפנימי של איש הקשר. ספק את `body` ההודעה פלוס **או** `contact_id`, **או** `channel` יחד עם שדה הזהות התואם לאותו ערוץ.

| שדה | חובה | תיאור |
|---|---|---|
| `body` | כן | טקסט ההודעה לשליחה. |
| `contact_id` | לא | מזהה של איש קשר קיים. כאשר מוגדר, שדות הזהות להלן אינם נחוצים. |
| `channel` | לא | ערוץ לשליחה. נדרש כאשר `contact_id` לא סופק. אחד מ-14 הערוצים שניתן לשלוח בהם הודעות יוצאות: `whatsapp`, `whatsapp_web`, `sms`, `instagram`, `instagram_private`, `messenger`, `telegram`, `chat-widget`, `custom`, `email`, `line`, `imessage`, `linkedin`, `viber`. |
| `phone_number` | לא | מספר הטלפון של איש הקשר בפורמט בינלאומי. בשימוש עם `whatsapp`, `whatsapp_web`, ו-`sms`. |
| `instagram_id` | לא | מזהה המשתמש של איש הקשר באינסטגרם. בשימוש עם `instagram`. |
| `messenger_id` | לא | מזהה המשתמש של איש הקשר במסנג'ר. בשימוש עם `messenger`. |
| `telegram_user_id` | לא | מזהה המשתמש של איש הקשר בטלגרם. בשימוש עם `telegram`. |
| `media_url` | לא | כתובת URL של קובץ מדיה לצירוף. |
| `media_content_type` | לא | סוג MIME של המדיה המצורפת, למשל `image/jpeg`. |

**אילו ערוצים ניתנים לפתרון לפי זהות.** רק שישה מתוך ה-14 מקבלים שדה זהות במקום `contact_id`: `whatsapp`, `whatsapp_web` ו-`sms` מאותרים לפי `phone_number`, `instagram` לפי `instagram_id`, `messenger` לפי `messenger_id`, ו-`telegram` לפי `telegram_user_id`. שמונת האחרים — `instagram_private`, `chat-widget`, `custom`, `email`, `line`, `imessage`, `linkedin` ו-`viber` — הם ללא זהות ציבורית לאיתור, לכן שליחה בערוצים אלו דורשת `contact_id`; העברת `channel` בלבד תחזיר `400` המציין ש-`contact_id` נדרש.

**cURL** (באמצעות טופס השאילתה `?apiKey=`)

```bash
curl -X POST "https://api.youraiconnector.com/v1/contacts/send?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "whatsapp",
    "phone_number": "+31612345678",
    "body": "Hi! Your appointment is confirmed."
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/contacts/send", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    channel: "whatsapp",
    phone_number: "+31612345678",
    body: "Hi! Your appointment is confirmed.",
  }),
});
const data = await res.json();
console.log(data.message_id, data.channel);
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/send",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "channel": "whatsapp",
        "phone_number": "+31612345678",
        "body": "Hi! Your appointment is confirmed.",
    },
)
data = res.json()
print(data["message_id"], data["channel"])
```

**תגובה** (`201 Created`):

```json
{
  "success": true,
  "message_id": "aB3dE5fG7hI9jK1lM2nO",
  "contact_id": "contact123",
  "channel": "whatsapp"
}
```

> **מדוע הודעה עלולה להידחות:** איש קשר עם מצב 'נא לא להפריע' או מצב פרטי מופעל אינו יכול לקבל הודעות יוצאות — הבקשה תיכשל עם `422`. אם אף איש קשר אינו תואם למזהה או לזהות שסיפקת, תקבל `404`.

---

## הצגת הודעות של איש קשר

`GET /contacts/{contactId}/messages`

מחזיר את ההודעות של איש קשר, מהחדשה לישנה, עם דפדוף מבוסס סמן (cursor).

| פרמטר שאילתה | נדרש | תיאור |
|---|---|---|
| `limit` | לא | גודל עמוד. ברירת מחדל `50`, מקסימום `100`. |
| `cursor` | לא | הערך `next_cursor` מתגובה קודמת. מחזיר הודעות ישנות יותר מהסמן. |
| `filter` | לא | סינון לפי סוג תוכן: `all` (ברירת מחדל), `text`, `media`, או `tool_use`. |
| `direction` | לא | סינון לפי כיוון: `all` (ברירת מחדל), `inbound` (התקבל מאיש הקשר), או `outbound` (נשלח על ידך). |

> **הערה על סינון ודפדוף:** המסננים `filter` ו-`direction` מוחלים על כל עמוד לאחר קריאתו, לכן עמוד מסונן יכול להכיל פחות פריטים מ-`limit`. ה-`next_cursor` עדיין מתקדם לאורך כל השיחה, לכן המשך לדפדף עד ש-`next_cursor` יהיה `null`.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/contacts/contact123/messages?limit=50&direction=inbound" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({ limit: "50", direction: "inbound" });
const res = await fetch(
  `https://api.youraiconnector.com/v1/contacts/contact123/messages?${params}`,
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.messages, data.next_cursor);
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"limit": 50, "direction": "inbound"},
)
data = res.json()
print(data["messages"], data["next_cursor"])
```

**תגובה** (`200 OK`):

```json
{
  "success": true,
  "contact_id": "contact123",
  "messages": [
    {
      "id": "aB3dE5fG7hI9jK1lM2nO",
      "body": "Hi! Thanks for reaching out.",
      "direction": "inbound",
      "channel": "whatsapp",
      "status": "delivered",
      "type": null,
      "timestamp": "2026-06-01T10:00:00.000Z",
      "media_url": null,
      "media_content_type": null,
      "bot_reply": false
    }
  ],
  "next_cursor": "cD4eF6gH8iJ0kL2mN3oP"
}
```

### שדות הודעה

| שדה | תיאור |
|---|---|
| `id` | מזהה ייחודי של ההודעה. |
| `body` | תוכן הטקסט של ההודעה. |
| `direction` | `inbound` (התקבל מאיש הקשר) או `outbound` (נשלח על ידי החשבון שלך). |
| `channel` | הערוץ שדרכו ההודעה נשלחה או התקבלה (למשל `whatsapp`, `sms`, `instagram`). |
| `status` | סטטוס משלוח נוכחי, למשל `Created`, `sent`, `delivered`, `read`, `failed`. |
| `type` | סוג הודעה. להודעות טקסט רגילות יש סוג `null`; פעילות כלי עזר אוטומטי מסומנת כ-`tool_use`. |
| `timestamp` | זמן ISO 8601 שבו נוצרה ההודעה. |
| `media_url` | כתובת URL של קובץ מדיה מצורף, אם קיים. |
| `media_content_type` | סוג MIME של המדיה המצורפת, אם קיימת. |
| `bot_reply` | `true` כאשר ההודעה נוצרה על ידי העוזר ה-AI. |
| `score` | הדירוג שלך להודעה: `1` אגודל למעלה, `-1` אגודל למטה, `0` כאשר היא לא דורגה. ראה [דרג או סמן הודעה בכוכב](#rate-or-star-a-message). |
| `is_important` | `true` כאשר ההודעה סומנה בכוכב. |
| `is_deleted` | `true` כאשר ההודעה נמחקה. הודעות שנמחקו נשארות ברשימה אך ה-`body` וה-`media_url` שלהן ריקים. |
| `reactions` | תגובות אימוג'י על ההודעה, משני הצדדים. תמיד מערך — ריק כשאין כאלה. לכל רשומה יש `emoji`, `from_phone_number`, `from_me` (`true` כאשר התגובה היא שלך) ו-`reacted_at`. |

---

## רשימת סשנים של צ'אט

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

### סשנים אחרונים בכל אנשי הקשר

`GET /chat-sessions/recent`

מחזיר את הסשנים שהחלו ב-X השעות האחרונות, מהחדש לישן, עבור כל איש קשר בחשבון.

| פרמטר שאילתה | נדרש | תיאור |
|---|---|---|
| `hours` | כן | כמה שעות אחורה לבדוק. חייב להיות מספר שלם חיובי. |
| `status` | לא | החזר רק סשנים עם סטטוס זה: `ChatSessionOpened` או `ChatSessionClosed`. |
| `limit` | לא | מספר מקסימלי של סשנים להחזרה. ברירת מחדל `100`, מקסימום `100`. |
| `includeMessages` | לא | `true` מוסיף מערך `messages` לכל סשן. כבוי כברירת מחדל מכיוון שהוא הופך את התגובה להרבה יותר גדולה. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/chat-sessions/recent?hours=24&status=ChatSessionClosed" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({ hours: "24", status: "ChatSessionClosed" });
const res = await fetch(`https://api.youraiconnector.com/v1/chat-sessions/recent?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.data.total_sessions, data.data.sessions);
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/chat-sessions/recent",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"hours": 24, "status": "ChatSessionClosed"},
)
data = res.json()["data"]
print(data["total_sessions"], data["sessions"])
```

**תגובה** (`200 OK`):

```json
{
  "success": true,
  "data": {
    "hours_ago": 24,
    "total_sessions": 2,
    "sessions": [
      {
        "session_id": "session456",
        "contact_id": "contact123",
        "contact_name": "Jane Doe",
        "contact_phone": "+31612345678",
        "contact_email": "jane@example.com",
        "start_date_time": "2026-06-01T09:55:00.000Z",
        "end_date_time": "2026-06-01T10:20:00.000Z",
        "status": "ChatSessionClosed",
        "tag": "Booking enquiry"
      }
    ]
  }
}
```

### כל הסשנים עבור איש קשר אחד

`GET /chat-sessions/{contactId}`

מחזיר כל סשן צ'אט עבור איש קשר בודד. אותם פרמטרים `status`, `limit` ו-`includeMessages` כמו לעיל — `hours` לא חל כאן.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/chat-sessions/contact123?limit=20" \
  -H "X-API-Key: YOUR_API_KEY"
```

**תגובה** (`200 OK`):

```json
{
  "success": true,
  "data": {
    "contact_id": "contact123",
    "contact_name": "Jane Doe",
    "total_sessions": 2,
    "sessions": [
      {
        "id": "session456",
        "start_date_time": "2026-06-01T09:55:00.000Z",
        "end_date_time": "2026-06-01T10:20:00.000Z",
        "status": "ChatSessionClosed",
        "tag": "Booking enquiry"
      }
    ]
  }
}
```

> **שמות שדות מזהה הסשן שונים בין שני נקודות הקצה.** רשימת הסשנים האחרונים קוראת לו `session_id` (הוא גם נושא את פרטי איש הקשר, מכיוון שסשנים מגיעים מאנשי קשר רבים); הרשימה לפי איש קשר קוראת לו `id`. כל ערך הוא מה שאתה מעביר כ-`{sessionId}` בעת משיכת השרשור המלא להלן.

כאשר `includeMessages=true`, כל סשן מקבל מערך `messages` שהרשומות בו נושאות `id`, `body`, `direction`, `timestamp`, `type`, `channel` ו-`status`.

---

## שליפת שרשור שיחה

`GET /contacts/{contactId}/chat-sessions/{sessionId}/messages`

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

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.session, data.messages);
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["session"], data["messages"])
```

**תגובה** (`200 OK`):

```json
{
  "success": true,
  "contact_id": "contact123",
  "session": {
    "id": "session456",
    "status": "ChatSessionClosed",
    "start_date_time": "2026-06-01T09:55:00.000Z",
    "end_date_time": "2026-06-01T10:20:00.000Z",
    "tag": "Booking enquiry"
  },
  "messages": [
    {
      "id": "aB3dE5fG7hI9jK1lM2nO",
      "body": "Hi! Thanks for reaching out.",
      "direction": "inbound",
      "channel": "whatsapp",
      "status": "delivered",
      "type": null,
      "timestamp": "2026-06-01T09:55:00.000Z",
      "media_url": null,
      "media_content_type": null,
      "bot_reply": false
    }
  ]
}
```

האובייקט `session` מדווח על `status` (`ChatSessionOpened` בזמן פעילות, `ChatSessionClosed` לאחר סיום), `start_date_time`, `end_date_time`, ו-`tag` קריא לבני אדם. המערך `messages` משתמש באותם [שדות הודעה](#message-fields) כמו נקודת הקצה של הרשימה.

---

## עריכה, מחיקה ותגובה להודעות

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

**מה כל ערוץ מאפשר**

| פעולה | ערוצים שיכולים לשנות את העותק של איש הקשר | מגבלת זמן |
|---|---|---|
| עריכת הודעה שנשלחה | ווידג'ט צ'אט, WhatsApp Web, טלגרם, לינקדאין | אין בווידג'ט צ'אט, 15 דקות ב-WhatsApp Web, 48 שעות בטלגרם, 60 דקות בלינקדאין |
| מחיקה עבור כולם | ווידג'ט צ'אט, WhatsApp Web, טלגרם, לינקדאין | 60 דקות בלינקדאין; לאחרים אין מגבלה מפורסמת |
| תגובה עם אימוג'י | WhatsApp Web, טלגרם | אין |

בכל ערוץ אחר — WhatsApp Business API, SMS, אינסטגרם, מסנג'ר, אימייל, LINE, ערוצים מותאמים אישית — מחיקה עדיין מסירה את ההודעה מתיבת הדואר הנכנס שלך, אך איש הקשר שומר על העותק שלו, ועריכה או תגובה אינן אפשריות כלל.

### עריכת הודעה

`POST /contacts/{contactId}/messages/{messageId}/edit`

משכתב הודעה שכבר שלחת, במכשיר של איש הקשר ובעותק שלך.

| שדה | נדרש | תיאור |
|---|---|---|
| `body` | כן | טקסט ההודעה החדש. אסור שיהיה ריק ויכול להכיל לכל היותר 4096 תווים. |

בניגוד למחיקה, פעולה זו **נכשלת בקול רעש** כאשר הערוץ מסרב: אתה מקבל `409` והעותק שלך נשאר בדיוק כפי שהוא אצל איש הקשר, מכיוון שהצגת עריכה שהם מעולם לא קיבלו תוציא את שני הצדדים מסנכרון. השדה `edit_reason` אומר לך מדוע — חלון העריכה של הערוץ נסגר, הערוץ מנותק, או שמשהו אחר השתבש.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "body": "Sorry - I meant Thursday at 3pm." }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ body: "Sorry - I meant Thursday at 3pm." }),
  }
);
const data = await res.json();
console.log(data.edited, data.edit_reason);
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"body": "Sorry - I meant Thursday at 3pm."},
)
data = res.json()
print(data.get("edited"), data.get("edit_reason"))
```

**תגובה** (`200 OK`):

```json
{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "edited": true,
  "edit_reason": "edit_dispatched"
}
```

אם הערוץ לא יקבל את העריכה, תקבל במקום זאת `409`, ושום דבר לא ישתנה:

```json
{
  "success": false,
  "error": "The message could not be edited",
  "edit_reason": "channel_disconnected"
}
```

הודעה שכבר נמחקה, ערוץ שלא יכול לערוך כלל, והודעה ישנה מדי עבור הערוץ שלה, כולם מחזירים `400` — הבקשה לעולם לא מגיעה לערוץ.

### מחיקת הודעה אחת

`DELETE /contacts/{contactId}/messages/{messageId}`

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

פעולה זו תמיד עונה `200` כאשר ההודעה הייתה קיימת, גם אם לא ניתן היה למשוך בחזרה את העותק של איש הקשר — העותק שלך **אכן** נמחק, כך ששגיאה תהיה מטעה. קרא את שלושת השדות בתגובה כדי לומר למשתמש מה קרה בפועל:

| שדה | תיאור |
|---|---|
| `revoke_supported` | האם ערוץ זה יכול למשוך הודעות בחזרה בכלל. |
| `revoked` | האם העותק במכשיר של איש הקשר הוסר. |
| `revoke_reason` | מדוע הוא לא הוסר, כאשר `revoked` הוא `false` — לדוגמה `revoke_window_closed` או `already_deleted`. |

**cURL**

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
  { method: "DELETE", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.revoked, data.revoke_reason);
```

**Python**

```python
import requests

res = requests.delete(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["revoked"], data["revoke_reason"])
```

**תגובה** (`200 OK`):

```json
{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "revoke_supported": true,
  "revoked": true,
  "revoke_reason": "revoke_dispatched"
}
```

> הודעות שנמחקו אינן מוסרות מהיסטוריית השיחה. הן נשארות ב-`GET /contacts/{contactId}/messages` עם `is_deleted: true` ו-`body` ריק ו-`media_url`.

### מחיקת מספר הודעות בבת אחת

`POST /contacts/{contactId}/messages/bulk-delete`

מנקה קבוצת הודעות מהצד שלך בלבד. גוף ההודעות והקבצים המצורפים מתרוקנים, אך **דבר אינו נמשך חזרה ממכשיר איש הקשר** — כדי למשוך הודעה חזרה גם משם, מחק אותה אחת אחת באמצעות נקודת הקצה להודעה בודדת שלעיל.

| שדה | נדרש | תיאור |
|---|---|---|
| `message_ids` | כן | מערך לא ריק של מזהי הודעות, עד 500 לבקשה. `messageIds` מתקבל ככינוי. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "message_ids": ["msg_1", "msg_2"] }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ message_ids: ["msg_1", "msg_2"] }),
  }
);
console.log((await res.json()).deleted);
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"message_ids": ["msg_1", "msg_2"]},
)
print(res.json()["deleted"])
```

**תגובה** (`200 OK`):

```json
{
  "success": true,
  "contact_id": "contact123",
  "deleted": 2
}
```

### הגב להודעה

`POST /contacts/{contactId}/messages/{messageId}/react`

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

| שדה | נדרש | תיאור |
|---|---|---|
| `emoji` | כן | האימוג'י להגבה, או `""` להסרת התגובה שלך. חייב להיות מחרוזת בודדת ללא רווחים, באורך של עד 16 תווים. |

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

- `422` — לא ניתן להעביר זאת לעולם בשיחה זו: הערוץ אינו תומך בתגובות, להודעה אין מזהה בצד הערוץ, או שהאימוג'י נמצא מחוץ לקבוצה שהערוץ מאפשר.
- `409` — הערוץ לא היה זמין לרגע. ניסיון חוזר עשוי להצליח.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "emoji": "👍" }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ emoji: "👍" }),
  }
);
const data = await res.json();
console.log(data.reactions);
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"emoji": "👍"},
)
print(res.json()["reactions"])
```

**תגובה** (`200 OK`):

```json
{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "reaction_supported": true,
  "reaction_reason": "reaction_dispatched",
  "reactions": [
    {
      "emoji": "👍",
      "from_phone_number": "+31612345678",
      "from_me": true,
      "reacted_at": "2026-06-01T10:05:00.000Z"
    }
  ]
}
```

המערך `reactions` הוא קבוצת התגובות המלאה שקיימת כעת על ההודעה, שלך ושל איש הקשר. ב-`409` או ב-`422` הוא מוחזר ללא שינוי, כך שלקוח המרנדר ישירות ממנו לעולם לא יציג תגובה שלא הועברה.

### דירוג או סימון הודעה בכוכב

`PATCH /contacts/{contactId}/messages/{messageId}`

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

| שדה | נדרש | תיאור |
|---|---|---|
| `score` | לא | `1` לייק, `-1` דיסלייק, `0` מנקה את הדירוג. |
| `is_important` | לא | `true` מסמן את ההודעה בכוכב, `false` מסיר את הסימון. חייב להיות בוליאני אמיתי, לא המחרוזת `"true"`. |

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

**cURL**

```bash
curl -X PATCH "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "score": 1, "is_important": true }'
```

**JavaScript**

```javascript
await fetch("https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1", {
  method: "PATCH",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ score: 1, is_important: true }),
});
```

**Python**

```python
import requests

requests.patch(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"score": 1, "is_important": True},
)
```

**תגובה** (`200 OK`):

```json
{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "score": 1,
  "is_important": true
}
```

---

## סימון הודעות כנקראו

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

### סימון הודעות ספציפיות כנקראו

`POST /contacts/{contactId}/messages/mark-read`

העבר את המזהים של ההודעות שברצונך לסמן כנקראו.

| שדה | נדרש | תיאור |
|---|---|---|
| `message_ids` | כן | מערך לא ריק של מזהי הודעות (עד 500 לבקשה). |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message_ids": ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"]
  }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      message_ids: ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"],
    }),
  }
);
const data = await res.json();
console.log(data.marked_read);
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"message_ids": ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"]},
)
print(res.json()["marked_read"])
```

**תגובה** (`200 OK`):

```json
{
  "success": true,
  "contact_id": "contact123",
  "marked_read": 2
}
```

### סימון כל הצ'אט כנקרא

`POST /contacts/{contactId}/mark-read`

מנקה את תגית ה'לא נקרא' עבור כל השיחה של איש הקשר בתיבת הדואר הנכנס. אין צורך בגוף בקשה.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/mark-read" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/mark-read",
  { method: "POST", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.success);
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/mark-read",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["success"])
```

**תגובה** (`200 OK`):

```json
{
  "success": true,
  "contact_id": "contact123"
}
```

### סימון כל הצ'אט כלא נקרא

`POST /contacts/{contactId}/mark-unread`

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

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

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/mark-unread" \
  -H "X-API-Key: YOUR_API_KEY"
```

**תגובה** (`200 OK`):

```json
{
  "success": true,
  "contact_id": "contact123"
}
```

---

## ייצוא שיחה

ייצוא נותן לך שיחה שלמה כתמליל קריא, במקום לדפדף בין הודעות. כל נקודת קצה של ייצוא מקבלת `filter` של `all` (ברירת מחדל), `text`, `media` או `tool_use`, בהתאם למסנן ברשימת ההודעות.

### ייצוא צ'אט של איש קשר אחד

`GET /chat-exports/{contactId}`

| פרמטר שאילתה | נדרש | תיאור |
|---|---|---|
| `format` | לא | `txt` (ברירת מחדל) מחזיר קישור להורדה של תמליל בטקסט פשוט. `json` מחזיר את ההודעות כנתונים מובנים בתגובה. |
| `filter` | לא | `all` (ברירת מחדל), `text`, `media` או `tool_use`. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/chat-exports/contact123?format=json" \
  -H "X-API-Key: YOUR_API_KEY"
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/chat-exports/contact123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"format": "json"},
)
print(res.json()["data"]["messages"])
```

**תגובה עם `format=json`** (`200 OK`):

```json
{
  "success": true,
  "data": {
    "contact": {
      "id": "contact123",
      "name": "Jane Doe",
      "phone": "+31612345678",
      "email": "jane@example.com"
    },
    "messages": [
      {
        "body": "Hi! I have a question about my order.",
        "direction": "inbound",
        "timestamp": "2026-06-01T09:55:00.000Z",
        "type": "text",
        "media_url": null,
        "media_content_type": null,
        "name": null,
        "args": null
      }
    ]
  }
}
```

עם `format=txt` (ברירת המחדל), `data` הוא במקום זאת קישור להורדה של קובץ התמליל שנוצר:

```json
{
  "success": true,
  "data": "https://storage.googleapis.com/.../chat-export-contact123-....txt"
}
```

> **קישור ההורדה הוא לזמן קצר.** משוך את הקובץ ברגע שאתה מקבל את הקישור במקום לאחסן אותו — בקש ייצוא חדש כאשר תזדקק לתמליל שוב.

### ייצוא כל השיחות האחרונות

`GET /chat-exports/recent`

מייצא את השיחות של כל אנשי הקשר שהיו פעילים ב-X השעות האחרונות, בקריאה אחת.

| פרמטר שאילתה | נדרש | תיאור |
|---|---|---|
| `hours` | כן | כמה שעות פעילות לבדוק לאחור. חייב להיות מספר שלם וחיובי. |
| `format` | לא | `json` (ברירת מחדל) מחזיר רשומה אחת לכל איש קשר. `txt` מחזיר קובץ טקסט יחיד להורדה המכיל את כל השיחות. |
| `limit` | לא | מספר מרבי של אנשי קשר לייצוא. ברירת מחדל `50`, מקסימום `100`. |
| `filter` | לא | `all` (ברירת מחדל), `text`, `media` או `tool_use`. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/chat-exports/recent?hours=24&limit=25" \
  -H "X-API-Key: YOUR_API_KEY"
```

**תגובה** (`200 OK`):

```json
{
  "success": true,
  "data": {
    "hours_ago": 24,
    "total_contacts": 2,
    "exports": [
      {
        "contactId": "contact123",
        "contactName": "Jane Doe",
        "phoneNumber": "+31612345678",
        "email": "jane@example.com",
        "messageCount": 12,
        "chatExport": "Acme Export - Jane Doe\nPhone: +31612345678\n..."
      }
    ]
  }
}
```

עם `format=txt` התגובה היא קובץ הטקסט עצמו, שנשלח כהורדה במקום כ-JSON.

> קריאה זו מושכת את ההיסטוריה המלאה של כל איש קשר תואם, לכן יש לשמור על `hours` ו-`limit` צנועים בחשבונות עמוסים.

### שליחת תמליל בדוא"ל לאיש הקשר

`POST /chat-exports/{contactId}/email`

שולח לאיש הקשר את תמליל השיחה שלו בדוא"ל — תהליך ה-"שלח לי את הצ'אט הזה במייל", המופעל מהמערכת שלך.

| שדה | נדרש | תיאור |
|---|---|---|
| `recipient_email` | לא | לאן לשלוח. כברירת מחדל משתמש בכתובת הדוא"ל השמורה של איש הקשר. |
| `via` | לא | `auto` (ברירת מחדל) בוחר את הנתיב הטוב ביותר, `transactional` שולח כדוא"ל מערכת, `email_channel` שולח מערוץ הדוא"ל המחובר שלך. |
| `note` | לא | שורה קצרה ממך שתוצג מעל התמליל. עד 1000 תווים. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/chat-exports/contact123/email" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "note": "Here is a copy of our chat, as promised." }'
```

**תגובה** (`200 OK`):

```json
{
  "success": true,
  "data": {
    "via": "transactional",
    "recipientEmail": "jane@example.com",
    "messageCount": 42,
    "omittedCount": 0
  }
}
```

`omittedCount` מציין כמה מההודעות הישנות ביותר הושמטו כדי לשמור על אורך סביר של הדוא"ל. `200` פירושו שהתמליל נוצר והוכנס לתור לשליחה, לא שהוא כבר הגיע לתיבת הדואר הנכנס.

---

## השהיה או חידוש של ה-AI עבור איש קשר בודד

`PUT /contacts/{contactId}`

הגדירו את `is_bot_active` ל-`false` כדי לעצור את ה-AI מלהשיב לאיש קשר בודד, וחזרה ל-`true` כדי להחזיר את השיחה. זהו מתג ההשתלטות שתרצו כאשר אדם נכנס לשיחה: הודעות יוצאות שאתם שולחים באמצעות ה-API עדיין נשלחות בזמן שהבוט מושהה.

**cURL**

```bash
curl -X PUT "https://api.youraiconnector.com/v1/contacts/contact123" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "is_bot_active": false }'
```

**JavaScript**

```javascript
await fetch("https://api.youraiconnector.com/v1/contacts/contact123", {
  method: "PUT",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ is_bot_active: false }),
});
```

**Python**

```python
import requests

requests.put(
    "https://api.youraiconnector.com/v1/contacts/contact123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"is_bot_active": False},
)
```

**תגובה**

```json
{
  "success": true,
  "contact_id": "contact123"
}
```

**השהיה כחלק מהתשובה**

אם אדם משתלט על השיחה על ידי שליחת תשובה, ניתן להשהות את הבוט באותה בקשה במקום לבצע קריאה שנייה. `POST /contacts/{contactId}/send-message` מקבל שני דגלים אופציונליים:

| שדה | תיאור |
|---|---|
| `pauseBot` | `true` משהה את ה-AI עבור איש קשר זה בעת שליחת ההודעה. |
| `clearIncompleteReply` | `true` מבטל תשובת בוט חצי-גמורה כך שלא תתחדש לאחר מכן. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/send-message" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Hi, Sarah here - taking over from the assistant.",
    "pauseBot": true,
    "clearIncompleteReply": true
  }'
```

התגובה כוללת את `"botPaused": true` כאשר ההשהיה הוחלה.

> סימון איש קשר כפרטי באמצעות [`POST /contacts/bulk-flag`](contacts.md) משהה גם את הבוט עבורו. ראו [אנשי קשר](contacts.md) לרשימת השדות המלאה.

---

## בניית תיבת דואר נכנס משלכם

כל מה שתיבת דואר נכנס צריכה נמצא בדף זה וב-[אנשי קשר](contacts.md):

| מה אתה צריך | נקודת קצה (Endpoint) |
|---|---|
| רשימת שיחות | `GET /contacts` |
| קריאת שיחה | `GET /contacts/{contactId}/messages` |
| רשימת סשנים של צ'אט של איש קשר | `GET /chat-sessions/{contactId}` |
| לראות מה הגיע לאחרונה | `GET /chat-sessions/recent` |
| קריאת סשן צ'אט אחד | `GET /contacts/{contactId}/chat-sessions/{sessionId}/messages` |
| שליחת תשובה ידנית | `POST /contacts/{contactId}/send-message` |
| תיקון תשובה ששלחת זה עתה | `POST /contacts/{contactId}/messages/{messageId}/edit` |
| הסרת הודעה | `DELETE /contacts/{contactId}/messages/{messageId}` |
| מחיקת מספר הודעות | `POST /contacts/{contactId}/messages/bulk-delete` |
| תגובה עם אימוג'י | `POST /contacts/{contactId}/messages/{messageId}/react` |
| דירוג או סימון הודעה בכוכב | `PATCH /contacts/{contactId}/messages/{messageId}` |
| סימון כנקרא | `POST /contacts/{contactId}/mark-read` |
| החזרת צ'אט לצוות | `POST /contacts/{contactId}/mark-unread` |
| ייצוא תמליל | `GET /chat-exports/{contactId}` |
| השהיה או חידוש של ה-AI | `PUT /contacts/{contactId}` עם `is_bot_active` |

לקבלת עדכונים בזמן אמת, הירשמו לאירועי `New Message`, `Replies`, `Human Alerted` ו-`Chat Concluded` באמצעות [Webhooks](webhooks.md) במקום לבצע סקר (polling) ל-API זה לפי טיימר.

---

## שגיאות ב-API של הודעות

נקודות קצה של הודעות מחזירות את מעטפת השגיאה הסטנדרטית:

```json
{
  "success": false,
  "error": "Contact not found"
}
```

| סטטוס | מתי זה קורה בנקודת קצה של הודעה |
|---|---|
| `400` | שדה נדרש חסר או פרמטר לא תקין (`limit`, `hours`, `filter`, `direction`, `status` שגויים, מערך `message_ids` ריק או מעל 500, `cursor` לא תקין, עריכה `body` ריקה או ארוכה מדי, `score` מחוץ ל-`-1`/`0`/`1`, או אימוג'י עם רווחים או מעל 16 תווים). מוחזר גם כאשר לא ניתן לערוך הודעה כלל — היא נמחקה, לערוץ שלה אין אפשרות עריכה, או שהיא מעבר לחלון העריכה של אותו ערוץ. |
| `404` | איש הקשר, סשן הצ'אט או אחד ממזהי ההודעות שסופקו לא נמצאו. |
| `409` | הערוץ לא יקבל את השינוי כרגע. דבר לא נכתב: בעריכה, `edit_reason` מסביר מדוע; בתגובה, הערוץ לא היה זמין לרגע וניסיון חוזר עשוי לעבוד. |
| `422` | איש הקשר אינו יכול לקבל הודעות יוצאות (נא לא להפריע, פרטי, או ערוץ שאינו נתמך), או שלא ניתן להעביר תגובה בשיחה זו (`reaction_reason` מציין איזו). |

הקודים המשותפים שכל נקודת קצה יכולה להחזיר — `401`, `403` (התוכנית שלך אינה כוללת גישת API), `429` (מגבלת קצב) ו-`500` — מפורטים עם הנחיות לניסיון חוזר ב-[שגיאות ועימוד](errors-and-pagination.md).

---

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

- [Webhooks](webhooks.md) — קבל עדכוני סטטוס משלוח בדחיפה במקום לבצע תשאול (polling).
- [אנשי קשר](contacts.md) — צור וחפש את אנשי הקשר שאליהם אתה שולח הודעות.
- [פגישות](appointments.md) — קבע ונהל פגישות עבור אנשי הקשר שלך.
