> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs-parschat.parstechai.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs-parschat.parstechai.com/_mcp/server.

# مرجع رویدادهای وب‌هوک

> همه رویدادهایی که می‌فرستیم، هر کدام با یک نمونه کامل از محتوای رویداد.

> **Warning**
>
> **نسخه پیش‌انتشار `v1`، منتشرشده در 2026-09-14.** این صفحه به شکل API متعهد است،
> نه به تاریخ مشخصی. دقیقاً همان چیزی را می‌سازیم که اینجا مستند شده است. شکل API تا
> **2026-10-14** هنوز ممکن است تغییر کند؛ پس از آن، تغییرات از [نسخه‌بندی و پایداری](/documentation/reference/versioning-stability) پیروی می‌کنند.
>
> این بنر با راه‌اندازی هر مسیر، صفحه به صفحه برداشته می‌شود. تا وقتی اینجاست، بر اساس قرارداد
> پیاده‌سازی کنید و فرض کنید آن مسیر هنوز قابل فراخوانی نیست.

> **Info**
>
> همه رویدادهای زیر در **API Reference** هم آمده‌اند، در بخش **Webhook events**؛ آنجا هر حالت
> را می‌توانید از فهرست کشویی کنار محتوای رویداد انتخاب کنید.

تحویل، تأیید امضا و تلاش دوباره: [رویدادهای وب‌هوک](/documentation/guides/webhook-events).

همه رویدادها پوشش یکسانی دارند؛ فقط `data` فرق می‌کند.

## `message`

پوشش رویداد در همه کانال‌ها یکسان است. تفاوت در داخل `data` است: اینستاگرام یک `source` و یک
`sender` اینستاگرامی دارد، و تلگرام شناسه کاربر تلگرام دارد و `source` ندارد.

#### دایرکت اینستاگرام

```json
{
  "schema_version": "1.0.0",
  "event": "message",
  "delivery_id": "dlv_9fK2mQ",
  "occurred_at": "2026-09-20T11:09:02Z",
  "robot_id": "rbt_8fK2mQ",
  "external_id": "shop_10422",
  "channel_id": "chn_3pQ7xL",
  "data": {
    "conversation_id": "cnv_4dR8nW",
    "message_id": "msg_1aB2cD",
    "external_id": "cli_msg_1",
    "source": "direct",
    "role": "client",
    "type": "text",
    "text": "Hi, do you have these roses in stock?",
    "markdown_content": null,
    "reply_to_id": null,
    "form_data": null,
    "attachments": [],
    "is_edited": false,
    "sender": { "id": "iguser_88213", "username": "sara.k" },
    "created_at": "2026-09-20T11:09:02Z"
  }
}
```

#### تلگرام

```json
{
  "schema_version": "1.0.0",
  "event": "message",
  "delivery_id": "dlv_4nP8sT",
  "occurred_at": "2026-09-20T11:11:30Z",
  "robot_id": "rbt_8fK2mQ",
  "external_id": "shop_10422",
  "channel_id": "chn_7bT4kM",
  "data": {
    "conversation_id": "cnv_9xR3mK",
    "message_id": "msg_7hJ8kL",
    "external_id": "cli_msg_2",
    "role": "client",
    "type": "text",
    "text": "Do you deliver on Fridays?",
    "markdown_content": null,
    "reply_to_id": null,
    "form_data": null,
    "attachments": [],
    "is_edited": false,
    "sender": { "id": "tg_5512340", "username": "sara_k" },
    "created_at": "2026-09-20T11:11:30Z"
  }
}
```

در تلگرام `source` وجود ندارد. این فیلد نقطه ورود اینستاگرام را توصیف می‌کند، پس نبودن `source` را
به معنای «برای این کانال کاربرد ندارد» بگیرید، نه کمبود داده.

#### پاسخ هوش مصنوعی

```json
{
  "schema_version": "1.0.0",
  "event": "message",
  "delivery_id": "dlv_6kM2nQ",
  "occurred_at": "2026-09-20T11:09:07Z",
  "robot_id": "rbt_8fK2mQ",
  "external_id": "shop_10422",
  "channel_id": "chn_3pQ7xL",
  "data": {
    "conversation_id": "cnv_4dR8nW",
    "message_id": "msg_3cE4fG",
    "external_id": null,
    "source": "direct",
    "role": "ai",
    "type": "text",
    "text": "Yes, Dutch roses are in stock today.",
    "markdown_content": "Yes, **Dutch roses** are in stock today.",
    "reply_to_id": "msg_1aB2cD",
    "form_data": null,
    "attachments": [],
    "is_edited": false,
    "sender": null,
    "created_at": "2026-09-20T11:09:07Z"
  }
}
```

پاسخ هوش مصنوعی یا اپراتور `sender: null` دارد. `reply_to_id` به پیامی اشاره می‌کند که به آن پاسخ داده شده است.

| فیلد               | توضیح                                                                                           |
| ------------------ | ----------------------------------------------------------------------------------------------- |
| `role`             | `client`، `ai` یا `operator`. برای `ai` و `operator` مقدار `sender` برابر `null` است            |
| `type`             | `text` · `voice` · `image` · `video` · `multimedia` · `document` · `poll` · `form` · `template` |
| `source`           | فقط اینستاگرام: `direct` · `comment` · `story_reply` · `story_mention` · `reel`                 |
| `external_id`      | **کلید idempotency شما**                                                                        |
| `reply_to_id`      | `message_id` پیامی که این پیام به آن پاسخ می‌دهد، یا `null`                                     |
| `markdown_content` | نسخه با قالب‌بندی غنی؛ `text` ساده می‌ماند. هر کدام ممکن است `null` باشد                        |
| `form_data`        | وقتی `type` برابر `form` است وجود دارد                                                          |

### آغازشده با کامنت، همراه با پیوست \[#triggered-by-a-comment-with-an-attachment]

```json
{
  "schema_version": "1.0.0",
  "event": "message",
  "delivery_id": "dlv_2xK8pL",
  "occurred_at": "2026-09-20T11:14:20Z",
  "robot_id": "rbt_8fK2mQ",
  "external_id": "shop_10422",
  "channel_id": "chn_3pQ7xL",
  "data": {
    "conversation_id": "cnv_7mN2qS",
    "message_id": "msg_5eF6gH",
    "source": "comment",
    "media_id": "17895695668004550",
    "role": "client",
    "type": "image",
    "text": "",
    "attachments": [
      { "type": "image", "url": "https://cdn.parstechai.com/m/9fK2mQ.jpg", "mime": "image/jpeg" }
    ],
    "sender": { "id": "iguser_44190", "username": "ali.m" },
    "created_at": "2026-09-20T11:14:20Z"
  }
}
```

`media_id` فقط وقتی می‌آید که رویداد از یک پست یا ریل آغاز شده باشد.

### یک پیام صوتی \[#a-voice-message]

پیوست‌ها به صورت رویدادهای عادی `message` با `type` غیرمتنی می‌رسند، هرگز به صورت رویداد جداگانه.
`text` خالی است و محتوا در `attachments` قرار دارد.

```json
{
  "schema_version": "1.0.0",
  "event": "message",
  "delivery_id": "dlv_6vB3nK",
  "occurred_at": "2026-09-20T11:31:12Z",
  "robot_id": "rbt_8fK2mQ",
  "external_id": "shop_10422",
  "channel_id": "chn_3pQ7xL",
  "data": {
    "conversation_id": "cnv_4dR8nW",
    "message_id": "msg_2vC5xN",
    "source": "direct",
    "role": "client",
    "type": "voice",
    "text": "",
    "attachments": [
      {
        "type": "voice",
        "url": "https://cdn.parstechai.com/m/2vC5xN.ogg",
        "mime": "audio/ogg",
        "duration_seconds": 14
      }
    ],
    "sender": { "id": "iguser_88213", "username": "sara.k" },
    "created_at": "2026-09-20T11:31:12Z"
  }
}
```

> **Warning**
>
> آدرس پیوست‌ها مدت اعتبار محدودی دارد. به جای ذخیره آدرس و دریافت فایل در زمانی دیگر، فایل را
> همان وقتی که رویداد می‌رسد دانلود کنید.

### ارسال فرم \[#a-form-submission]

```json
{
  "schema_version": "1.0.0",
  "event": "message",
  "delivery_id": "dlv_4jH7sV",
  "occurred_at": "2026-09-20T11:40:00Z",
  "robot_id": "rbt_8fK2mQ",
  "external_id": "shop_10422",
  "channel_id": "chn_3pQ7xL",
  "data": {
    "conversation_id": "cnv_4dR8nW",
    "message_id": "msg_8kP1rT",
    "role": "client",
    "type": "form",
    "text": null,
    "form_data": [
      { "type": "text", "situation": "question", "key": "Your name", "value": "Sara" },
      { "type": "single_select", "situation": "rate", "key": "Service rating", "value": "excellent" }
    ],
    "attachments": [],
    "created_at": "2026-09-20T11:40:00Z"
  }
}
```

---

## `message.generating`

هوش مصنوعی نوشتن پاسخ را شروع کرده است. **نشانگر «در حال نوشتن» را نمایش دهید.**

```json
{
  "schema_version": "1.0.0",
  "event": "message.generating",
  "delivery_id": "dlv_5kL3nP",
  "occurred_at": "2026-09-20T11:09:03Z",
  "robot_id": "rbt_8fK2mQ",
  "external_id": "shop_10422",
  "channel_id": "chn_3pQ7xL",
  "data": { "conversation_id": "cnv_4dR8nW" }
}
```

> **Info**
>
> وقتی `message` متناظر رسید، نشانگر را پنهان کنید. **رویداد صریحی برای «متوقف شد» وجود ندارد.**
> تولید پاسخی که شکست بخورد هیچ پیامی نمی‌سازد، پس پس از چند ثانیه آن را timeout در نظر بگیرید.

---

## `chat`

وضعیت یک گفتگو تغییر کرد. `status` یکی از `answered`، `operator_attention`،
`not_answered`، `closed` یا `pending` است، و `previous_status` وضعیت قبلی آن است.

هر کدام برای سمت شما معنای متفاوتی دارد، پس به جای ذخیره صرف این رشته، هر کدام را جداگانه مدیریت کنید.

#### answered

هوش مصنوعی یا یک اپراتور پاسخ داد. چیزی منتظر کسی نیست.

```json
{
  "schema_version": "1.0.0",
  "event": "chat",
  "delivery_id": "dlv_6hJ4kM",
  "occurred_at": "2026-09-20T11:09:08Z",
  "robot_id": "rbt_8fK2mQ",
  "external_id": "shop_10422",
  "channel_id": "chn_3pQ7xL",
  "data": {
    "conversation_id": "cnv_4dR8nW",
    "status": "answered",
    "previous_status": "not_answered",
    "changed_at": "2026-09-20T11:09:08Z"
  }
}
```

#### operator\_attention

به یک انسان نیاز است. این همان رویدادی است که باید رویش هشدار بدهید: گفتگو را در صف بگذارید، به
تیم پشتیبانی‌تان اطلاع دهید، یا نشانی را در پنل خودتان روشن کنید.

```json
{
  "schema_version": "1.0.0",
  "event": "chat",
  "delivery_id": "dlv_7kL5nQ",
  "occurred_at": "2026-09-20T11:20:44Z",
  "robot_id": "rbt_8fK2mQ",
  "external_id": "shop_10422",
  "channel_id": "chn_3pQ7xL",
  "data": {
    "conversation_id": "cnv_4dR8nW",
    "status": "operator_attention",
    "previous_status": "answered",
    "changed_at": "2026-09-20T11:20:44Z"
  }
}
```

#### not\_answered

پیامی از مشتری منتظر است و هنوز هیچ پاسخی داده نشده. برای چند ثانیه عادی است؛ اگر ادامه پیدا کند،
مشکلی وجود دارد.

```json
{
  "schema_version": "1.0.0",
  "event": "chat",
  "delivery_id": "dlv_2mN6pR",
  "occurred_at": "2026-09-20T11:09:02Z",
  "robot_id": "rbt_8fK2mQ",
  "external_id": "shop_10422",
  "channel_id": "chn_3pQ7xL",
  "data": {
    "conversation_id": "cnv_4dR8nW",
    "status": "not_answered",
    "previous_status": "pending",
    "changed_at": "2026-09-20T11:09:02Z"
  }
}
```

#### pending

گفتگو وجود دارد اما هنوز فعال نیست. معمولاً این مقدار را در `previous_status` می‌بینید، نه به‌تنهایی.

```json
{
  "schema_version": "1.0.0",
  "event": "chat",
  "delivery_id": "dlv_9pQ3sT",
  "occurred_at": "2026-09-20T11:08:59Z",
  "robot_id": "rbt_8fK2mQ",
  "external_id": "shop_10422",
  "channel_id": "chn_3pQ7xL",
  "data": {
    "conversation_id": "cnv_4dR8nW",
    "status": "pending",
    "previous_status": null,
    "changed_at": "2026-09-20T11:08:59Z"
  }
}
```

#### closed

گفتگو پایان یافت. این حالت دو فیلد اضافه دارد: `context_reset` و `message_count`.
پیش از هر اقدامی، بخش زیر را بخوانید.

```json
{
  "schema_version": "1.0.0",
  "event": "chat",
  "delivery_id": "dlv_8mN3qR",
  "occurred_at": "2026-09-20T12:02:11Z",
  "robot_id": "rbt_8fK2mQ",
  "external_id": "shop_10422",
  "channel_id": "chn_3pQ7xL",
  "data": {
    "conversation_id": "cnv_4dR8nW",
    "status": "closed",
    "previous_status": "answered",
    "context_reset": true,
    "message_count": 14,
    "changed_at": "2026-09-20T12:02:11Z"
  }
}
```

### بستن گفتگو، زمینه را از نو شروع می‌کند \[#closing-starts-a-fresh-context]

وقتی گفتگویی بسته می‌شود، تاریخچه قبلی دیگر به عنوان زمینه (context) برای هوش مصنوعی فرستاده
نمی‌شود. گفتگوی بعدی با همان کاربر نهایی از صفر شروع می‌شود.

> **Warning**
>
> **`context_reset` پرچم حذف نیست.** چیزی حذف نمی‌شود. پیام‌ها باقی می‌مانند و فقط دیگر در زمینه
> گفتگوی بعدی بازپخش نمی‌شوند. شریکی که این را دستور حذف تلقی کند، رونوشتی را دور می‌ریزد که ما
> هنوز نگه داشته‌ایم.

|                             |                             |
| --------------------------- | --------------------------- |
| رونوشتی که ذخیره کرده‌اید   | تغییری نمی‌کند. نگهش دارید  |
| خواندن گفتگو پس از بسته شدن | همچنان کار می‌کند           |
| گفتگوی بعدی با همان کاربر   | بدون زمینه قبلی شروع می‌شود |

---

## `reaction`

کسی واکنشی را روی یک پیام اضافه یا حذف کرد. `action` می‌گوید کدام، پس یک پردازشگر هر دو حالت را
پوشش می‌دهد: با `added` اعمالش کنید و با `removed` برش گردانید.

#### added

```json
{
  "schema_version": "1.0.0",
  "event": "reaction",
  "delivery_id": "dlv_3pQ9rT",
  "occurred_at": "2026-09-20T11:22:05Z",
  "robot_id": "rbt_8fK2mQ",
  "external_id": "shop_10422",
  "channel_id": "chn_3pQ7xL",
  "data": {
    "conversation_id": "cnv_4dR8nW",
    "message_id": "msg_1aB2cD",
    "action": "added",
    "emoji": "❤️",
    "by": { "id": "iguser_88213", "username": "sara.k" }
  }
}
```

#### removed

```json
{
  "schema_version": "1.0.0",
  "event": "reaction",
  "delivery_id": "dlv_5rT1vW",
  "occurred_at": "2026-09-20T11:23:40Z",
  "robot_id": "rbt_8fK2mQ",
  "external_id": "shop_10422",
  "channel_id": "chn_3pQ7xL",
  "data": {
    "conversation_id": "cnv_4dR8nW",
    "message_id": "msg_1aB2cD",
    "action": "removed",
    "emoji": "❤️",
    "by": { "id": "iguser_88213", "username": "sara.k" }
  }
}
```

محتوای رویداد جز در `action` یکسان است، پس برای پیدا کردن واکنشی که ذخیره کرده‌اید، روی ترکیب
(`message_id`، `emoji`، `by.id`) تطبیق دهید.

---

## `is_typing`

یک **انسان** شروع به نوشتن کرد یا متوقف شد. این با `message.generating` که مربوط به هوش مصنوعی است
فرق دارد. شاید بخواهید آن‌ها را متفاوت نمایش دهید: «سارا در حال نوشتن است» در برابر «در حال تولید پاسخ».

#### شروع

```json
{
  "schema_version": "1.0.0",
  "event": "is_typing",
  "delivery_id": "dlv_7rS2tU",
  "occurred_at": "2026-09-20T11:25:10Z",
  "robot_id": "rbt_8fK2mQ",
  "external_id": "shop_10422",
  "channel_id": "chn_3pQ7xL",
  "data": {
    "conversation_id": "cnv_4dR8nW",
    "is_typing": true,
    "by": { "id": "iguser_88213", "username": "sara.k", "role": "client" }
  }
}
```

#### توقف

```json
{
  "schema_version": "1.0.0",
  "event": "is_typing",
  "delivery_id": "dlv_8sT4uV",
  "occurred_at": "2026-09-20T11:25:18Z",
  "robot_id": "rbt_8fK2mQ",
  "external_id": "shop_10422",
  "channel_id": "chn_3pQ7xL",
  "data": {
    "conversation_id": "cnv_4dR8nW",
    "is_typing": false,
    "by": { "id": "iguser_88213", "username": "sara.k", "role": "client" }
  }
}
```

#### تایپ اپراتور

`by.role` می‌گوید چه کسی است. نمایش تایپ اپراتور به مشتری نهایی ارزشمند است؛ نمایش تایپ مشتری به
اپراتور.

```json
{
  "schema_version": "1.0.0",
  "event": "is_typing",
  "delivery_id": "dlv_9uV5wX",
  "occurred_at": "2026-09-20T11:26:02Z",
  "robot_id": "rbt_8fK2mQ",
  "external_id": "shop_10422",
  "channel_id": "chn_3pQ7xL",
  "data": {
    "conversation_id": "cnv_4dR8nW",
    "is_typing": true,
    "by": { "id": "opr_4412", "username": "reza.h", "role": "operator" }
  }
}
```

> **Info**
>
> ارسال رویداد توقف تضمینی نیست. ممکن است اتصال در میانه تایپ قطع شود، پس به جای انتظار برای
> `is_typing: false`، خودتان نشانگر را پس از چند ثانیه منقضی کنید.