Skip to navigation

Руководство: отправка и получение почты

Первый рабочий сценарий диалогового агента.

В этом руководстве разобран полный практический цикл, когда агент ведёт переписку. Разделы «Основные концепции» описывают отдельные вызовы API; здесь показано, как связать их в рабочий диалоговый цикл.

Основа: HTML и текст

Как напоминание из документации по сообщениям: лучше всегда передавать и html, и text. Так письмо нормально отображается в разных клиентах и заметно лучше доходит до получателя (доставляемость).

# Always provide both html and text when possible
client.inboxes.messages.send(
inbox_id="outreach@agentinbox.space",
to=["potential-customer@example.com"],
subject="Following up",
text="Hi Jane,\n\nThis is a plain-text version of our email.",
html="<p>Hi Jane,</p><p>This is a <strong>rich HTML</strong> version of our email.</p>",
labels=["outreach-campaign"]
)

Диалоговый цикл

Типичная задача агента — проверить ящик на ответы и ответить. Эффективнее всего для этого подходят вебхуки, но можно собрать и простой опрос (polling).

Ниже логика агента на опросе.

1

1. Найти цепочку, на которую нужно ответить

Сначала нужно понять, в каких разговорах есть новые сообщения, на которые агент ещё не ответил. Удобно помечать такие письма метками. Можно получить список цепочек в ящике с меткой unreplied.

# Find all threads in this inbox that are marked as unreplied
threadsRes = client.threads.list(
labels = ["unreplied"]
)
if threadsRes.count == 0:
print("No threads need a reply.")
else:
# Let's work on the first unreplied thread
thread_to_reply_to = threadsRes.thread[0]
2

2. Взять ID последнего сообщения в цепочке

Чтобы ответить в переписке, нужно ответить на самое последнее сообщение в цепочке. По ID цепочки можно получить объект с полным списком сообщений; ID нужного — у последнего сообщения в списке.

# Get the full thread object to access its messages
thread_details = client.threads.get(thread_to_reply_to.thread_id)
# The last message in the list is the one we want to reply to
last_message = thread_details.messages[-1]
message_id_to_reply_to = last_message.message_id

Используйте last_message.extracted_text (или extracted_html), если нужен только новый текст ответа без цитируемой истории.

3

3. Отправить ответ и обновить метки

Когда есть message_id, можно отправить ответ агента. Хорошая практика — сразу обновить метки у исходного сообщения: снять unreplied и добавить replied, чтобы агент не ответил дважды на одно письмо.

# Send the reply
client.inboxes.messages.reply(
inbox_id="info@patternautomation.com",
message_id=message_id_to_reply_to,
text="This is our agent's helpful reply!"
)
# Update the labels on the original message
client.inboxes.messages.update(
inbox_id="info@patternautomation.com",
message_id=message_id_to_reply_to,
add_labels=["replied"],
remove_labels=["unreplied"]
)
Обработка в реальном времени через вебхуки

В продакшене опрос неэффективен. Надёжнее обрабатывать входящие ответы через вебхуки: Agent Inbox сразу уведомит агента о новом сообщении, и ответ можно строить в реальном времени.

Как настроить вебхуки →

Отложенная отправка

Вместо мгновенной отправки можно запланировать письмо на будущее — удобно для рабочих часов или равномерного аутрича.

Создайте черновик с полем send_at — дальше Agent Inbox отправит письмо в указанное время.

from datetime import datetime, timedelta
# Schedule for tomorrow at 9 AM UTC
send_time = (datetime.utcnow() + timedelta(days=1)).replace(hour=9, minute=0, second=0)
client.inboxes.drafts.create(
inbox_id="outreach@agentinbox.space",
to=["prospect@example.com"],
subject="Quick question about your workflow",
text="Hi, I noticed you're using...",
html="<p>Hi, I noticed you're using...</p>",
send_at=send_time.isoformat() + "Z"
)

Подробнее об отложенной отправке — отмена, перенос, список запланированных черновиков и условные напоминания — на странице Черновики.