WebSockets
Поток почтовых событий в реальном времени с низкой задержкой
WebSocket даёт постоянное двунаправленное соединение с Agent Inbox для событий почты в реальном времени. В отличие от вебхуков, не нужен публичный URL и инструменты вроде ngrok.
Зачем WebSocket?
| Возможность | Webhook | WebSocket |
|---|---|---|
| Настройка | Нужен публичный URL + ngrok | Дополнительные инструменты не нужны |
| Соединение | HTTP на каждое событие | Постоянное соединение |
| Направление | Agent Inbox → ваш сервер | Двунаправленно |
| Файрвол | Нужно открыть порт | Только исходящие |
| Задержка | HTTP round-trip | Поток «сразу» |
Python SDK
В Python SDK есть синхронный и асинхронный клиенты WebSocket.
Асинхронное использование
1 import asyncio 2 from agentinbox import AsyncAgentinbox, Subscribe, Subscribed, MessageReceivedEvent 3 4 client = AsyncAgentinbox(api_key="YOUR_API_KEY") 5 6 async 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 19 asyncio.run(main())
Синхронное использование
1 from agentinbox import Agentinbox, Subscribe, Subscribed, MessageReceivedEvent 2 3 client = Agentinbox(api_key="YOUR_API_KEY") 4 5 with 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}")
Обработчики событий
Можно использовать колбэки вместо итерации:
1 import asyncio 2 from agentinbox import AsyncAgentinbox, Subscribe, EventType 3 4 client = AsyncAgentinbox(api_key="YOUR_API_KEY") 5 6 async 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 18 asyncio.run(main())
Для синхронного режима с обработчиками запустите слушатель в фоновом потоке:
1 import threading 2 from agentinbox import Agentinbox, Subscribe, EventType 3 4 client = Agentinbox(api_key="YOUR_API_KEY") 5 6 with 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 с автоматическим переподключением.
Базовое использование
1 import { AgentinboxClient, Agentinbox } from "agentinbox"; 2 3 const client = new AgentinboxClient({ 4 apiKey: process.env.AGENTINBOX_API_KEY, 5 }); 6 7 async 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 39 main();
React / Next.js
1 import { useEffect, useState } from "react"; 2 import { AgentinboxClient, Agentinbox } from "agentinbox"; 3 4 function 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:
1 from agentinbox import Subscribe 2 3 # Конкретные inbox 4 Subscribe(inbox_ids=["inbox1@agentinbox.space", "inbox2@agentinbox.space"]) 5 6 # Pod 7 Subscribe(pod_ids=["pod-id-1", "pod-id-2"]) 8 9 # Типы событий 10 Subscribe( 11 inbox_ids=["agent@agentinbox.space"], 12 event_types=["message.received", "message.sent"] 13 )
TypeScript:
1 // Конкретные inbox 2 socket.sendSubscribe({ 3 type: "subscribe", 4 inboxIds: ["inbox1@agentinbox.space", "inbox2@agentinbox.space"], 5 }); 6 7 // Pod 8 socket.sendSubscribe({ 9 type: "subscribe", 10 podIds: ["pod-id-1", "pod-id-2"], 11 }); 12 13 // Типы событий 14 socket.sendSubscribe({ 15 type: "subscribe", 16 inboxIds: ["agent@agentinbox.space"], 17 eventTypes: ["message.received", "message.sent"], 18 });
Типы событий
События соединения
| Событие | Python | TypeScript | Описание |
|---|---|---|---|
subscribed | Subscribed | Agent Inbox.Subscribed | Подписка подтверждена |
События сообщений
| Событие | Python | TypeScript | Описание |
|---|---|---|---|
message_received | MessageReceivedEvent | Agent Inbox.MessageReceivedEvent | Новое входящее письмо |
message_sent | MessageSentEvent | Agent Inbox.MessageSentEvent | Письмо отправлено |
message_delivered | MessageDeliveredEvent | Agent Inbox.MessageDeliveredEvent | Письмо доставлено |
message_bounced | MessageBouncedEvent | Agent Inbox.MessageBouncedEvent | Отскок |
message_complained | MessageComplainedEvent | Agent Inbox.MessageComplainedEvent | Пометка как спам |
message_rejected | MessageRejectedEvent | Agent Inbox.MessageRejectedEvent | Письмо отклонено |
События доменов
| Событие | Python | TypeScript | Описание |
|---|---|---|---|
domain_verified | DomainVerifiedEvent | Agent Inbox.DomainVerifiedEvent | Верификация домена завершена |
Поля сообщения
Объект event.message содержит:
| Python | TypeScript | Описание |
|---|---|---|
inbox_id | inboxId | Inbox, куда пришло письмо |
message_id | messageId | Уникальный ID сообщения |
thread_id | threadId | ID треда |
from_ | from_ | Адрес отправителя |
to | to | Список получателей |
subject | subject | Тема |
text | text | Текстовое тело |
html | html | HTML-тело (если есть) |
attachments | attachments | Вложения |
Обработка ошибок
Python:
1 from agentinbox import AsyncAgentinbox, Subscribe, MessageReceivedEvent 2 from agentinbox.core.api_error import ApiError 3 4 client = AsyncAgentinbox(api_key="YOUR_API_KEY") 5 6 async 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:
1 import { AgentinboxClient, Agentinbox, AgentinboxError } from "agentinbox"; 2 3 const client = new AgentinboxClient({ 4 apiKey: process.env.AGENTINBOX_API_KEY, 5 }); 6 7 async 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 40 main();
Скопировать в Cursor / Claude
1 """ 2 Agent Inbox WebSockets — copy into Cursor/Claude. Real-time events, no public URL needed. 3 4 Sync: with client.websockets.connect() as socket: socket.send_subscribe(Subscribe(inbox_ids=[...])); for event in socket: ... 5 Async: async with client.websockets.connect() as socket: await socket.send_subscribe(...); async for event in socket: ... 6 Subscribe(inbox_ids=[...], pod_ids=[...], event_types=[...]) 7 Event types: Subscribed, MessageReceivedEvent, MessageSentEvent, MessageDeliveredEvent, MessageBouncedEvent, MessageComplainedEvent, MessageRejectedEvent, DomainVerifiedEvent 8 """ 9 from agentinbox import Agentinbox, Subscribe, Subscribed, MessageReceivedEvent 10 11 client = Agentinbox(api_key="YOUR_API_KEY") 12 with 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)
