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

# Настройка вебхуков

> Создание вебхуков с ngrok и Agent Inbox: аккаунт, inbox, регистрация вебхука и пример кода.

В этом руководстве вы настроите вебхуки для уведомлений от Agent Inbox в реальном времени: аккаунт ngrok, inbox, регистрация вебхука и простой приёмник на Python.

## Требования

Перед началом убедитесь, что есть:

* Python 3.8+
* [Ключ API Agent Inbox](https://agentinbox.space/quickstart#step-3-create-an-api-key)
* менеджер пакетов `pip`
* базовые навыки Python и терминала

## Установка

```bash
pip install agentinbox flask ngrok
```

## Шаг 1: Аккаунт ngrok

Ngrok поднимает безопасный туннель с публичного URL на ваш локальный сервер — Agent Inbox сможет слать вебхуки на вашу машину при разработке.

### 1.1 Регистрация

Зайдите на [ngrok.com](https://ngrok.com/) и зарегистрируйтесь.

![Главная страница Ngrok](/_fern-files/_img/2d257d7065229b8ebd74abd4f96802eb8eb4f5b04041bbf28a5015a9d171a4ab.webp)

### 1.2 Установка под вашу ОС

После входа ngrok подскажет установку под вашу систему.

![Инструкции по установке Ngrok](/_fern-files/_img/f1ecdd69a4ef981c9e2f04c4118cad618f81b7dde98cb6de3c6f4f9a69311c79.webp)

На macOS через Homebrew:

```bash
brew install ngrok
```

Затем авторизация токеном из дашборда ngrok:

```bash
ngrok config add-authtoken YOUR_AUTHTOKEN
```

## Шаг 2: Inbox в Agent Inbox

Нужен ящик для входящей почты. Создайте через API:

```python
from agentinbox import Agentinbox

client = Agentinbox()

# Inbox для демо-агента вебхуков
inbox = client.inboxes.create(
    username="webhook-demo",
    client_id="webhook-demo-inbox"  # Идемпотентность
)

print(f"Inbox created: {inbox.inbox_id}")
```

`client_id` гарантирует, что повторный запуск не создаст дубликат — вернётся существующий ящик.

## Шаг 3: Регистрация вебхука в Agent Inbox

### 3.1 Запуск туннеля ngrok

В терминале (порт 3000):

```bash
ngrok http 3000
```

В выводе будет что-то вроде:

Скопируйте **Forwarding URL** (например `https://your-subdomain.ngrok-free.app`) — его укажете при регистрации вебхука.

> **Для просмотра в браузере — localhost**
>
> Для проверки страницы приёмника используйте `http://127.0.0.1:3000` из строки Web Interface, а не URL ngrok. Ngrok нужен внешним сервисам вроде Agent Inbox.
>
> **Почему localhost?** Safari строже Chrome/Firefox к dev-серверам через HTTPS-туннель ngrok: блокирует локальные WebSocket и часть скриптов, страница может «крутиться» из-за HMR. Это нормально для разработки. Localhost или статическая сборка обходят проблему.

### 3.2 Регистрация вебхука

```python
# URL из ngrok
webhook_url = "https://your-subdomain.ngrok-free.app/webhooks"

webhook = client.webhooks.create(
    url=webhook_url,
    event_types=["message.received"],  # при необходимости добавьте message.sent и др.
    client_id="webhook-demo-webhook"  # Идемпотентность
)

print(f"Webhook created: {webhook.webhook_id}")
```

## Шаг 4: Пример приёма вебхуков

Файл `webhook_receiver.py`:

```python
from flask import Flask, request, Response

app = Flask(__name__)

@app.route('/')
def home():
    """Страница статуса"""
    return """
    <html>
    <body style="font-family: sans-serif; max-width: 800px; margin: 50px auto; padding: 20px;">
        <h1>Agent Inbox Webhook Receiver</h1>
        <div style="background: #4CAF50; color: white; padding: 10px 20px;
                    border-radius: 4px; display: inline-block; margin: 20px 0;">
            Server is running
        </div>
        <div style="background: #e3f2fd; padding: 15px; border-radius: 4px;
                    border-left: 4px solid #2196F3;">
            <h3>Webhook Endpoint Ready</h3>
            <p>Your webhook endpoint is listening at: <code>POST /webhooks</code></p>
        </div>
        <h3>How to use:</h3>
        <ul>
            <li>Start ngrok: <code>ngrok http 3000</code></li>
            <li>Register your webhook with Agent Inbox using the ngrok URL</li>
            <li>Send a test email to your Agent Inbox inbox</li>
            <li>Watch the console for incoming webhook events</li>
        </ul>
    </body>
    </html>
    """

@app.route('/webhooks', methods=['POST'])
def receive_webhook():
    """Приём событий от Agent Inbox"""
    payload = request.json

    event_type = payload.get('event_type')
    message = payload.get('message', {})

    print(f"\nWebhook received: {event_type}")
    print(f"From: {message.get('from_')}")
    print(f"Subject: {message.get('subject')}\n")

    return Response(status=200)

if __name__ == '__main__':
    print("Starting webhook receiver on http://127.0.0.1:3000")
    app.run(port=3000)
```

### Запуск приёмника

1. Ngrok в одном терминале.
2. В другом:

```bash
python webhook_receiver.py
```

3. Отправьте тестовое письмо на inbox.
4. Смотрите вывод в консоли.

### Проверка в браузере

Откройте `http://127.0.0.1:3000` — страница статуса.

## Проверка настройки

1. Письмо на адрес ящика (например `webhook-demo@agentinbox.space`).
2. Консоль приёмника — должны появиться поля события.

> **Дальше**
>
> Расширьте `receive_webhook()`:
>
> * автоответы
> * обработка вложений
> * маршрутизация по содержимому
> * связка с агентами
>
> См. пример [событийного агента](/webhook-agent).

## Устранение неполадок

#### События не приходят

* Ngrok запущен и URL совпадает с зарегистрированным вебхуком
* Flask слушает нужный порт (3000)
* URL вебхука заканчивается на `/webhooks`
* Ошибки в консоли Flask и в веб-интерфейсе ngrok

#### Туннель ngrok обрывается

На бесплатном плане сессии ограничены (\~2 часа). Перезапустите ngrok и обновите URL вебхука в Agent Inbox.

#### Порт занят

Выберите другой порт:

* в `app.run(port=XXXX)`
* в команде: `ngrok http XXXX`

## Скопировать в Cursor / Claude

**`Python`**

```python title="Python"
"""
Agent Inbox Webhook Setup — copy into Cursor/Claude.

Flow: 1) ngrok http 3000 → copy URL. 2) inboxes.create(client_id=...) 3) webhooks.create(url=ngrok+/webhooks, event_types=[...], client_id=...)
4) Flask POST /webhooks: return 200 immediately, process request.json in background.
Local: use http://127.0.0.1:3000 in browser, not ngrok URL.
"""
from flask import Flask, request, Response
from agentinbox import Agentinbox

app = Flask(__name__)
client = Agentinbox()

inbox = client.inboxes.create(username="webhook-demo", client_id="webhook-demo-inbox")
wh = client.webhooks.create(url="https://YOUR_NGROK.ngrok-free.app/webhooks", event_types=["message.received"], client_id="webhook-demo-webhook")

@app.route("/webhooks", methods=["POST"])
def receive():
  payload = request.json
  print(payload.get("event_type"), payload.get("message", {}).get("subject"))
  return Response(status=200)
```

**`TypeScript`**

```typescript title="TypeScript"
/**
 * Agent Inbox Webhook Setup — copy into Cursor/Claude.
 *
 * Flow: 1) ngrok http 3000. 2) inboxes.create({ clientId }). 3) webhooks.create({ url, eventTypes, clientId })
 * 4) Express POST /webhooks: res.status(200).send(), process req.body async.
 * Use express.raw() if you add Svix verification later.
 */
import express from "express";
import { AgentinboxClient } from "agentinbox";

const client = new AgentinboxClient({ apiKey: process.env.AGENTINBOX_API_KEY! });
const inbox = await client.inboxes.create({ username: "webhook-demo", clientId: "webhook-demo-inbox" });
await client.webhooks.create({
  url: "https://YOUR_NGROK.ngrok-free.app/webhooks",
  eventTypes: ["message.received"],
  clientId: "webhook-demo-webhook",
});

const app = express();
app.post("/webhooks", express.json(), (req, res) => {
  console.log(req.body.event_type, req.body.message?.subject);
  res.status(200).send();
});
app.listen(3000);
```

## Продакшен

* **Отдельный сервер:** облако (AWS, GCP, Heroku и т.д.), не ngrok.
* **Проверка подписи:**[проверяйте запросы](/webhook-verification).
* **Ошибки и ретраи:** логирование, алерты.
* **Асинхронность:** сразу `200`, тяжёлую работу — в фон.
* **Догрузка через API:** тело вебхука ограничено 1 МБ; при превышении поля `text`/`html` могут быть опущены. Полное письмо — через [Get Message](/api-reference/messages/get). Подробнее: [лимит размера полезной нагрузки](/overview#payload-size-limit).
* **Мониторинг:** логи и алерты по сбоям доставки.

#### [Проверка вебхуков](/webhook-verification)

Подписи Svix для безопасных эндпоинтов.

#### [Обзор вебхуков](/overview)

Как устроены вебхуки и структура payload.

#### [События вебхуков](/events)

Полный список типов событий.