WebSockets

Поток почтовых событий в реальном времени с низкой задержкой

WebSocket даёт постоянное двунаправленное соединение с Agent Inbox для событий почты в реальном времени. В отличие от вебхуков, не нужен публичный URL и инструменты вроде ngrok.

Зачем WebSocket?

ВозможностьWebhookWebSocket
НастройкаНужен публичный URL + ngrokДополнительные инструменты не нужны
СоединениеHTTP на каждое событиеПостоянное соединение
НаправлениеAgent Inbox → ваш серверДвунаправленно
ФайрволНужно открыть портТолько исходящие
ЗадержкаHTTP round-tripПоток «сразу»

Python SDK

В Python SDK есть синхронный и асинхронный клиенты WebSocket.

Асинхронное использование

1import asyncio
2from agentinbox import AsyncAgentinbox, Subscribe, Subscribed, MessageReceivedEvent
3
4client = AsyncAgentinbox(api_key="YOUR_API_KEY")
5
6async def main():
7 async with client.websockets.connect() as socket:
8 # Подписка на inbox
9 await socket.send_subscribe(Subscribe(inbox_ids=["agent@agentinbox.space"]))
10
11 # Обработка событий по мере поступления
12 async for event in socket:
13 if isinstance(event, Subscribed):
14 print(f"Subscribed to: {event.inbox_ids}")
15 elif isinstance(event, MessageReceivedEvent):
16 print(f"New email from: {event.message.from_}")
17 print(f"Subject: {event.message.subject}")
18
19asyncio.run(main())

Синхронное использование

1from agentinbox import Agentinbox, Subscribe, Subscribed, MessageReceivedEvent
2
3client = Agentinbox(api_key="YOUR_API_KEY")
4
5with client.websockets.connect() as socket:
6 # Подписка на inbox
7 socket.send_subscribe(Subscribe(inbox_ids=["agent@agentinbox.space"]))
8
9 # Обработка событий по мере поступления
10 for event in socket:
11 if isinstance(event, Subscribed):
12 print(f"Subscribed to: {event.inbox_ids}")
13 elif isinstance(event, MessageReceivedEvent):
14 print(f"New email from: {event.message.from_}")
15 print(f"Subject: {event.message.subject}")

Обработчики событий

Можно использовать колбэки вместо итерации:

1import asyncio
2from agentinbox import AsyncAgentinbox, Subscribe, EventType
3
4client = AsyncAgentinbox(api_key="YOUR_API_KEY")
5
6async def main():
7 async with client.websockets.connect() as socket:
8 # Регистрация обработчиков
9 socket.on(EventType.OPEN, lambda _: print("Connected"))
10 socket.on(EventType.MESSAGE, lambda msg: print("Received:", msg))
11 socket.on(EventType.CLOSE, lambda _: print("Disconnected"))
12 socket.on(EventType.ERROR, lambda err: print("Error:", err))
13
14 # Подписка и прослушивание
15 await socket.send_subscribe(Subscribe(inbox_ids=["agent@agentinbox.space"]))
16 await socket.start_listening()
17
18asyncio.run(main())

Для синхронного режима с обработчиками запустите слушатель в фоновом потоке:

1import threading
2from agentinbox import Agentinbox, Subscribe, EventType
3
4client = Agentinbox(api_key="YOUR_API_KEY")
5
6with client.websockets.connect() as socket:
7 socket.on(EventType.OPEN, lambda _: print("Connected"))
8 socket.on(EventType.MESSAGE, lambda msg: print("Received:", msg))
9 socket.on(EventType.CLOSE, lambda _: print("Disconnected"))
10 socket.on(EventType.ERROR, lambda err: print("Error:", err))
11
12 socket.send_subscribe(Subscribe(inbox_ids=["agent@agentinbox.space"]))
13
14 # Слушатель в фоне
15 listener = threading.Thread(target=socket.start_listening, daemon=True)
16 listener.start()
17 listener.join()

TypeScript SDK

В TypeScript SDK клиент WebSocket с автоматическим переподключением.

Базовое использование

1import { AgentinboxClient, Agentinbox } from "agentinbox";
2
3const client = new AgentinboxClient({
4 apiKey: process.env.AGENTINBOX_API_KEY,
5});
6
7async function main() {
8 const socket = await client.websockets.connect();
9
10 // Обработка событий
11 socket.on("open", () => {
12 console.log("Connected");
13
14 // Подписка после открытия соединения
15 socket.sendSubscribe({
16 type: "subscribe",
17 inboxIds: ["agent@agentinbox.space"],
18 });
19 });
20
21 socket.on("message", (event: Agent Inbox.Subscribed | Agent Inbox.MessageReceivedEvent) => {
22 if (event.type === "subscribed") {
23 console.log("Subscribed to:", event.inboxIds);
24 } else if (event.type === "message_received") {
25 console.log("New email from:", event.message.from_);
26 console.log("Subject:", event.message.subject);
27 }
28 });
29
30 socket.on("close", (event) => {
31 console.log("Disconnected:", event.code, event.reason);
32 });
33
34 socket.on("error", (error) => {
35 console.error("Error:", error);
36 });
37}
38
39main();

React / Next.js

1import { useEffect, useState } from "react";
2import { AgentinboxClient, Agentinbox } from "agentinbox";
3
4function useAgentinboxWebSocket(apiKey: string, inboxIds: string[]) {
5 const [lastMessage, setLastMessage] = useState<Agent Inbox.MessageReceivedEvent | null>(null);
6 const [isConnected, setIsConnected] = useState(false);
7
8 useEffect(() => {
9 const client = new AgentinboxClient({ apiKey });
10
11 let socket: Awaited<ReturnType<typeof client.websockets.connect>>;
12
13 async function connect() {
14 socket = await client.websockets.connect();
15
16 socket.on("open", () => {
17 setIsConnected(true);
18 socket.sendSubscribe({
19 type: "subscribe",
20 inboxIds,
21 });
22 });
23
24 socket.on("message", (event) => {
25 if (event.type === "message_received") {
26 setLastMessage(event);
27 }
28 });
29
30 socket.on("close", () => setIsConnected(false));
31 }
32
33 connect();
34 return () => socket?.close();
35 }, [apiKey, inboxIds.join(",")]);
36
37 return { lastMessage, isConnected };
38}

Параметры подписки

Можно фильтровать по inbox, pod или типу события:

Python:

1from agentinbox import Subscribe
2
3# Конкретные inbox
4Subscribe(inbox_ids=["inbox1@agentinbox.space", "inbox2@agentinbox.space"])
5
6# Pod
7Subscribe(pod_ids=["pod-id-1", "pod-id-2"])
8
9# Типы событий
10Subscribe(
11 inbox_ids=["agent@agentinbox.space"],
12 event_types=["message.received", "message.sent"]
13)

TypeScript:

1// Конкретные inbox
2socket.sendSubscribe({
3 type: "subscribe",
4 inboxIds: ["inbox1@agentinbox.space", "inbox2@agentinbox.space"],
5});
6
7// Pod
8socket.sendSubscribe({
9 type: "subscribe",
10 podIds: ["pod-id-1", "pod-id-2"],
11});
12
13// Типы событий
14socket.sendSubscribe({
15 type: "subscribe",
16 inboxIds: ["agent@agentinbox.space"],
17 eventTypes: ["message.received", "message.sent"],
18});

Типы событий

События соединения

СобытиеPythonTypeScriptОписание
subscribedSubscribedAgent Inbox.SubscribedПодписка подтверждена

События сообщений

СобытиеPythonTypeScriptОписание
message_receivedMessageReceivedEventAgent Inbox.MessageReceivedEventНовое входящее письмо
message_sentMessageSentEventAgent Inbox.MessageSentEventПисьмо отправлено
message_deliveredMessageDeliveredEventAgent Inbox.MessageDeliveredEventПисьмо доставлено
message_bouncedMessageBouncedEventAgent Inbox.MessageBouncedEventОтскок
message_complainedMessageComplainedEventAgent Inbox.MessageComplainedEventПометка как спам
message_rejectedMessageRejectedEventAgent Inbox.MessageRejectedEventПисьмо отклонено

События доменов

СобытиеPythonTypeScriptОписание
domain_verifiedDomainVerifiedEventAgent Inbox.DomainVerifiedEventВерификация домена завершена

Поля сообщения

Объект event.message содержит:

PythonTypeScriptОписание
inbox_idinboxIdInbox, куда пришло письмо
message_idmessageIdУникальный ID сообщения
thread_idthreadIdID треда
from_from_Адрес отправителя
totoСписок получателей
subjectsubjectТема
texttextТекстовое тело
htmlhtmlHTML-тело (если есть)
attachmentsattachmentsВложения

Обработка ошибок

Python:

1from agentinbox import AsyncAgentinbox, Subscribe, MessageReceivedEvent
2from agentinbox.core.api_error import ApiError
3
4client = AsyncAgentinbox(api_key="YOUR_API_KEY")
5
6async def main():
7 try:
8 async with client.websockets.connect() as socket:
9 await socket.send_subscribe(Subscribe(inbox_ids=["agent@agentinbox.space"]))
10
11 async for event in socket:
12 if isinstance(event, MessageReceivedEvent):
13 await process_email(event.message)
14
15 except ApiError as e:
16 print(f"API error: {e.status_code} - {e.body}")
17 except Exception as e:
18 print(f"Connection error: {e}")

TypeScript:

1import { AgentinboxClient, Agentinbox, AgentinboxError } from "agentinbox";
2
3const client = new AgentinboxClient({
4 apiKey: process.env.AGENTINBOX_API_KEY,
5});
6
7async function main() {
8 try {
9 const socket = await client.websockets.connect();
10
11 socket.on("open", () => {
12 socket.sendSubscribe({
13 type: "subscribe",
14 inboxIds: ["agent@agentinbox.space"],
15 });
16 });
17
18 socket.on("message", (event: Agent Inbox.MessageReceivedEvent) => {
19 if (event.type === "message_received") {
20 processEmail(event.message);
21 }
22 });
23
24 socket.on("error", (error) => {
25 console.error("WebSocket error:", error);
26 });
27
28 socket.on("close", (event) => {
29 console.log("Disconnected:", event.code, event.reason);
30 });
31 } catch (err) {
32 if (err instanceof AgentinboxError) {
33 console.error(`API error: ${err.statusCode} - ${err.message}`);
34 } else {
35 console.error("Connection error:", err);
36 }
37 }
38}
39
40main();

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

1"""
2Agent Inbox WebSockets — copy into Cursor/Claude. Real-time events, no public URL needed.
3
4Sync: with client.websockets.connect() as socket: socket.send_subscribe(Subscribe(inbox_ids=[...])); for event in socket: ...
5Async: async with client.websockets.connect() as socket: await socket.send_subscribe(...); async for event in socket: ...
6Subscribe(inbox_ids=[...], pod_ids=[...], event_types=[...])
7Event types: Subscribed, MessageReceivedEvent, MessageSentEvent, MessageDeliveredEvent, MessageBouncedEvent, MessageComplainedEvent, MessageRejectedEvent, DomainVerifiedEvent
8"""
9from agentinbox import Agentinbox, Subscribe, Subscribed, MessageReceivedEvent
10
11client = Agentinbox(api_key="YOUR_API_KEY")
12with client.websockets.connect() as socket:
13 socket.send_subscribe(Subscribe(inbox_ids=["agent@agentinbox.space"]))
14 for event in socket:
15 if isinstance(event, Subscribed): print(event.inbox_ids)
16 elif isinstance(event, MessageReceivedEvent): print(event.message.subject)