> For the complete documentation index, see [llms.txt](https://docs.suvvy.ai/ru/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.suvvy.ai/ru/kanaly/personalnyi-kanal-api/otpravka-soobshenii.md).

# Отправка сообщений

Для отправки сообщений из персонального канала, используйте следующий метод:

<table data-header-hidden><thead><tr><th width="114"></th><th></th></tr></thead><tbody><tr><td>Метод</td><td><strong>POST</strong></td></tr><tr><td>Адрес</td><td><a href="https://api.suvvy.ai/api/webhook/custom/message">https://api.suvvy.ai/api/webhook/custom/message</a></td></tr></tbody></table>

## Заголовки

<table><thead><tr><th width="406">Заголовок</th><th>Значение</th></tr></thead><tbody><tr><td><code>Authorization</code></td><td><code>Bearer &#x3C;токен></code></td></tr><tr><td><code>Content-Type</code></td><td><code>application/json</code></td></tr></tbody></table>

При запросе необходимо передать токен, полученный при подключении канала.

## Тело запроса

```json
{
  "api_version": 1,
  "message_id": "<ID_сообщения>",
  "chat_id": "<ID_чата>",
  "text": "Привет!",
  "attachments": [
    {
      "file_name": "файл.png",
      "file_type": "image",
      "data": "aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1kUXc0dzlXZ1hjUQ=="
    }
  ],
  "source": "Иванов Иван из Авито",
  "placeholders": {
     "some_id": "123123"
  },
  "link": {
    "type": "chat",
    "hint": "Диалог",
    "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  },
  "message_sender": "customer",
  "client_name": "Иванов Иван",
  "client_phone": "+79001234567"
}
```

<table><thead><tr><th width="191">Поле</th><th width="175">Поле обязательно</th><th>Тип</th><th>Описание</th></tr></thead><tbody><tr><td><code>api_version</code></td><td>да</td><td>целое число (только <code>1</code>)</td><td><p><strong>Версия API.</strong></p><p>В будущем мы будем обновлять наше API, и чтобы у вас ничего не сломалось, какое-то время будем параллельно поддерживать и старые версии.</p></td></tr><tr><td><code>message_id</code></td><td>да</td><td>строка</td><td><p><strong>ID сообщения в вашей системе.</strong></p><p>Необходимо для предотвращения случайных повторных срабатываний</p></td></tr><tr><td><code>chat_id</code></td><td>да</td><td>строка</td><td><p><strong>ID чата в вашей системе.</strong></p><p>Связывающая часть, определяет в какой диалог попадет сообщение</p></td></tr><tr><td><code>text</code></td><td>да, если не указано поле <code>attachments</code></td><td>строка, не меньше 1 символа</td><td><strong>Текст сообщения.</strong></td></tr><tr><td><code>attachments</code></td><td>да, если не указано поле <code>text</code></td><td>массив объектов <code>Attachment</code></td><td><p><strong>Вложения.</strong></p><p>На данный момент поддерживаются только картинки и аудио</p></td></tr><tr><td><code>message_sender</code></td><td>да</td><td>строка (<code>customer</code> или <code>employee</code>)</td><td><p><strong>Отправитель сообщения.</strong></p><p>Клиент или сотрудник из вашей системы</p></td></tr><tr><td><code>source</code></td><td>да</td><td>строка</td><td><p><strong>Источник.</strong></p><p>Значение, которое показывается в колонке "Источник" в личном кабинете Савви.<br><br>Как правило - имя или юзернейм клиента, название сделки</p></td></tr><tr><td><code>link</code></td><td>нет</td><td>объект <code>Link</code></td><td><p><strong>Ссылка на чат в вашей системе.</strong></p><p>Будет отображаться как кнопка в личном кабинете Савви</p></td></tr><tr><td><code>placeholders</code></td><td>нет</td><td>объект, где ключ и значение - строки</td><td><p><strong>Переменные для инструкции.</strong></p><p>Подробнее ниже</p></td></tr><tr><td><code>client_name</code></td><td>нет</td><td>строка</td><td><strong>Имя клиента.</strong></td></tr><tr><td><code>client_phone</code></td><td>нет</td><td>строка</td><td><strong>Номер телефона клиента.</strong></td></tr></tbody></table>

{% content-ref url="/pages/hGIUdcTIrwrwiUmpG21l" %}
[Переменные](/ru/osnovnye-nastroiki/prompts/prompts-1.md)
{% endcontent-ref %}

### Объект `Attachment`

Все поля обязательны.

| Поле        | Тип                          | Описание                                                          |
| ----------- | ---------------------------- | ----------------------------------------------------------------- |
| `file_name` | строка                       | **Имя файла.**                                                    |
| `file_type` | строка (`image` или `audio`) | **Тип файла.**                                                    |
| `data`      | строка, base64 файла         | <p><strong>Файл.</strong></p><p>Допустимые типы указаны ниже.</p> |

Савви принимает файлы следующих типов:

* Для изображений: `image/png`, `image/jpeg`, `image/gif`
* Для аудио: `audio/ogg`, `audio/mpeg`, `audio/wav`, `audio/x-wav`, `audio/webm`, `audio/mp4`, `audio/m4a`, `audio/x-m4a`

Максимальный размер файла - **15 мегабайт**

### Объект `Link`

| Поле   | Тип                                                          | Описание                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| ------ | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type` | строка (`user`, `chat`, `phone`, `lead`, `product`, `other`) | <p><strong>Тип ссылки.</strong></p><p>Влияет на иконку, отображаемую в личном кабинете<br></p><ul><li><code>user</code> - 👤</li><li><code>chat</code> - 💬</li><li><code>phone</code> - 📞</li><li><code>lead</code> - 🤝🏻</li><li><code>product</code> - 🛍️</li><li><code>other</code> - 🔗</li></ul>                                                                                                                                                                                     |
| `hint` | строка или `null`                                            | <p><strong>Текст для кнопки.</strong></p><p>Не обязательно. Если не указано (или <code>null</code>), то используются названия, взависимости от типа:<br></p><ul><li><code>user</code> - <strong>Аккаунт</strong></li><li><code>chat</code> - <strong>Чат</strong></li><li><code>phone</code> - <strong>Телефон</strong></li><li><code>lead</code> - <strong>Лид</strong></li><li><code>product</code> - <strong>Товар</strong></li><li><code>other</code> - <strong>Ссылка</strong></li></ul> |
| `url`  | строка                                                       | **Ссылка.**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |

## Ответ

При успехе вебхук возвращает тело следующего вида:

```json
{
  "message": "Successful"
}
```

Его можно игнорировать, оно не несет никакой полезной информации.

## Ошибки

### Неверный токен

Вернет тело следующего вида и код **401:**

```json
{
  "detail": "Invalid token.",
  "status_code": 401,
  "error_code": "auth_invalid_token"
}
```

### Канал отключен

Возвращается, если канал не подключен или выключен в настройках.\
Вернет тело следующего вида и код **424:**

```json
{
  "detail": "Channel is disabled.",
  "status_code": 424,
  "error_code": "instance_channel_is_disabled"
}
```

### Неподдерживаемый тип файла

Возвращается, если переданный файл не поддерживается Савви. Возвращает поддерживаемые типы.\
Вернет тело следующего вида и код **415:**

```json
{
  "detail": "File type is not supported or invalid.",
  "status_code": 415,
  "error_code": "file_invalid_type",
  "allowed_mime_types": [
    "image/png",
    "text/csv",
    "audio/ogg"
  ]
}
```

### Отрицательный баланс

Возвращается, если ваш баланс Савви меньше нуля.\
Вернет тело следующего вида и код **402:**

```json
{
  "detail": "Your balance is below zero, so you can't perform this action.'",
  "status_code": 402,
  "error_code": "user_balance_below_zero"
}
```

### Ошибка валидации

Возвращает код **422** и тело, в котором подробно описано, что было передано не так.

## Пример кода для отправки

{% tabs %}
{% tab title="Python (requests)" %}

```python
import requests

response = requests.post(
    'https://api.suvvy.ai/api/webhook/custom/message',
    headers={
        'Authorization': 'Bearer ваш_токен',
        'Content-Type': 'application/json'
    },
    json={
        'api_version': 1,
        'message_id': 'уникальный_айди_сообщения',
        'chat_id': 'уникальный_айди_чата',
        'text': 'Привет!',
        'attachments': [
            {
                'file_name': 'файл.png',
                'file_type': 'image',
                'data': 'base64_данные_файла'
            }
        ],
        'source': 'Иванов Иван из Авито',
        'placeholders': {
            'some_id': '123123'
        },
        'link': {
            'type': 'chat',
            'hint': 'Диалог',
            'url': 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
        },
        'message_sender': 'customer',
        'client_name': 'Иванов Иван',
        'client_phone': '+79001234567'
    }
)
```

{% endtab %}

{% tab title="JavaScript (fetch)" %}

```javascript
fetch('https://api.suvvy.ai/api/webhook/custom/message', {
    method: 'POST',
    headers: {
        'Authorization': 'Bearer ваш_токен',
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({
        api_version: 1,
        message_id: 'уникальный_айди_сообщения',
        chat_id: 'уникальный_айди_чата',
        text: 'Привет!',
        attachments: [
            {
                file_name: 'файл.png',
                file_type: 'image',
                data: 'base64_данные_файла'
            }
        ],
        source: 'Иванов Иван из Авито',
        placeholders: {
            some_id: '123123'
        },
        link: {
            type: 'chat',
            hint: 'Диалог',
            url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
        },
        message_sender: 'customer',
        client_name: 'Иванов Иван',
        client_phone: '+79001234567'
    })
})
```

{% endtab %}

{% tab title="PHP (cURL)" %}

```php
$ch = curl_init('https://api.suvvy.ai/api/webhook/custom/message');
$data = [
    'api_version' => 1,
    'message_id' => 'уникальный_айди_сообщения',
    'chat_id' => 'уникальный_айди_чата',
    'text' => 'Привет!',
    'attachments' => [
        [
            'file_name' => 'файл.png',
            'file_type' => 'image',
            'data' => 'base64_данные_файла'
        ]
    ],
    'source' => 'Иванов Иван из Авито',
    'placeholders' => [
        'some_id' => '123123'
    ],
    'link' => [
        'type' => 'chat',
        'hint' => 'Диалог',
        'url' => 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
    ],
    'message_sender' => 'customer',
    'client_name' => 'Иванов Иван',
    'client_phone' => '+79001234567'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ваш_токен',
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
```

{% endtab %}

{% tab title="Ruby (net/http)" %}

```ruby
require 'net/http'
require 'uri'
require 'json'

uri = URI.parse('https://api.suvvy.ai/api/webhook/custom/message')
header = {
  'Authorization' => 'Bearer ваш_токен',
  'Content-Type' => 'application/json'
}
data = {
  api_version: 1,
  message_id: 'уникальный_айди_сообщения',
  chat_id: 'уникальный_айди_чата',
  text: 'Привет!',
  attachments: [
    {
      file_name: 'файл.png',
      file_type: 'image',
      data: 'base64_данные_файла'
    }
  ],
  source: 'Иванов Иван из Авито',
  placeholders: {
    some_id: '123123'
  },
  link: {
    type: 'chat',
    hint: 'Диалог',
    url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
  },
  message_sender: 'customer',
  client_name: 'Иванов Иван',
  client_phone: '+79001234567'
}

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = data.to_json

response = http.request(request)
```

{% endtab %}

{% tab title="Rust (reqwest)" %}

```rust
use reqwest::blocking::Client;
use serde_json::json;
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    let client = Client::new();
    let res = client.post("https://api.suvvy.ai/api/webhook/custom/message")
        .header("Authorization", "Bearer ваш_токен")
        .header("Content-Type", "application/json")
        .json(&json!({
            "api_version": 1,
            "message_id": "уникальный_айди_сообщения",
            "chat_id": "уникальный_айди_чата",
            "text": "Привет!",
            "attachments": [
                {
                    "file_name": "файл.png",
                    "file_type": "image",
                    "data": "base64_данные_файла"
                }
            ],
            "source": "Иванов Иван из Авито",
            "placeholders": {
                "some_id": "123123"
            },
            "link": {
                "type": "chat",
                "hint": "Диалог",
                "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
            },
            "message_sender": "customer",
            "client_name": "Иванов Иван",
            "client_phone": "+79001234567"
        }))
        .send()?;

    Ok(())
}
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.suvvy.ai/ru/kanaly/personalnyi-kanal-api/otpravka-soobshenii.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
