Перейти к документации
Python

Рассылки

`broadcasts.preview`, `send`, `list`, `list_all`, `iterate`, `get`, `list_recipients`, `list_all_recipients`, `iterate_recipients`, `get_recipient`, `stats`, `analytics` и `cancel`.

Все методы

broadcasts.py
import time from openemail import openemailfrom openemail.types import BroadcastCreate draft: BroadcastCreate = {    'audienceIds': ['aud_4c1b8e2a7d9f05c36b4e8a71'],    'from': 'Acme <[email protected]>',    'subject': '{{firstName|Hello}}, the September release is out',    'html': '<p>Hi {{firstName|there}},</p><p>Here is what changed this month.</p>',    'text': 'Hi {{firstName|there}}, here is what changed this month. Unsubscribe: {{unsubscribeUrl}}',    'tags': {'campaign': 'release-2026-09'},} reach = openemail.broadcasts.preview(draft)print(reach['recipients'], reach['unsubscribed'], reach['suppressed']) broadcast = openemail.broadcasts.send(draft) latest = openemail.broadcasts.get(broadcast['id'])while latest['status'] in ('scheduled', 'queued', 'sending'):    time.sleep(5)    latest = openemail.broadcasts.get(broadcast['id']) for copy in openemail.broadcasts.iterate_recipients(broadcast['id']):    print(copy['email'], copy['status'], copy['opens'], copy['clicks']) bounced = openemail.broadcasts.list_recipients(broadcast['id'], filter='bounced')if bounced['items']:    content = openemail.broadcasts.get_recipient(broadcast['id'], bounced['items'][0]['emailId'])    print(content['subject'], content['bouncedAt']) stats = openemail.broadcasts.stats(broadcast['id'], grain='day')print(stats['totals']['opened'], stats['totals']['clicked'], stats['totals']['unsubscribed']) lately = openemail.broadcasts.stats(broadcast['id'], days=1)print(lately['window']['opened'] if lately['window'] else None) month = openemail.broadcasts.analytics(days=30)for row in month['broadcasts']:    print(row['subject'], row['sent'], row['opened']) later = openemail.broadcasts.send({**draft, 'scheduledAt': 'P1D'})openemail.broadcasts.cancel(later['id']) history = openemail.broadcasts.list(audience_id=draft['audienceIds'][0])print(latest['status'], latest['counts']['sent'], len(history['items']))

Рассылка отправляет одно сообщение всем в одной или нескольких аудиториях, отдельной копией каждому человеку. У каждой копии ровно один получатель и нет cc или bcc, поэтому никто не видит, кому ещё она ушла, и каждая копия является обычным письмом со своим id msg_, событиями, отслеживанием и вебхуками. list_recipients выводит их вместе с тем, что стало с каждой. Копии не складываются в папку «Отправленные», потому что записью служит сама рассылка.

send сразу возвращает рассылку в состоянии queued или scheduled, если передан scheduledAt, а отправка идёт в фоне. send требует emails:send и audiences:read, preview требует audiences:read, list, list_all, iterate, get, list_recipients, list_all_recipients, iterate_recipients, get_recipient, stats и analytics требуют emails:read, а cancel требует emails:send.

Каждый send несёт Idempotency-Key: ваш через idempotency_key= или созданный SDK, поэтому повтор после сетевого сбоя отвечает рассылкой, созданной первой попыткой, а не отправляет дважды. preview, get, cancel и любое чтение безопасно повторять, и они повторяются.

Поля слияния

subject, html и text заполняются для каждого человека из его контакта. {{firstName}} обозначает первое слово имени контакта, {{lastName}} остальную часть имени, {{name}} полное имя, {{email}} адрес, куда уходит копия, а {{unsubscribeUrl}} ссылку, которая его отписывает.

Каждое поле принимает запасное значение после черты, которое используется, если у контакта нет значения, поэтому {{firstName|there}} превращается в "there" для контакта без имени. Значения экранируются в html, а любое другое {{…}} остаётся ровно таким, как написано.

Передайте template вместо html и text, чтобы отправить сохранённый шаблон. Те же пять значений приходят в него как пропсы, но только те, что объявляет шаблон, поэтому шаблон с firstName его получит, а шаблон без него никогда из-за этого не будет отклонён. Всё в template.props уходит во все копии одинаково.

Отписка

Каждая копия несёт заголовки отписки в один щелчок, благодаря которым почтовый клиент показывает собственную кнопку отписки, чего крупные почтовые сервисы требуют от массовых рассылок. Текст html или text, который сам не ставит {{unsubscribeUrl}}, получает однострочный колонтитул со ссылкой. Шаблон отправляется ровно таким, как есть, поэтому поставьте {{unsubscribeUrl}} в шаблон.

Отписка помечает человека как отписанного во всех аудиториях, куда ушла эта рассылка, и AudienceContactResource.unsubscribedAt показывает это в audiences.list_contacts. Он остаётся в аудитории и в адресной книге, другие его аудитории не затрагиваются, а письма, отправляемые ему по одному, продолжают уходить. Если убрать его из аудитории и добавить снова, он снова подписан.

Кого пропускают

Рассылка достигает каждого контакта хотя бы одной из audienceIds, один раз, в скольких бы аудиториях он ни был. Она пропускает контакт, отписавшийся от каждой из этих аудиторий, в которых состоит, и адрес из списка подавления после отказа или жалобы или потому, что его туда добавили. Контакт, добавленный в одну из аудиторий после send, но до того, как рассылка до него дошла, её получит.

preview возвращает те же числа без отправки: recipients, unsubscribed и suppressed. send, который никого бы не достиг, выбрасывает 422 no_recipients.

Вся отправка сверяется с месячным лимитом отправок тарифа до того, как что-либо будет записано, поэтому рассылка, которую лимит не покрывает, выбрасывает 429 send_quota_exceeded и ничего после себя не оставляет. Каждая копия считается одной отправкой.

Статус и ход

get читает counts напрямую из копий, поэтому опрашивайте его, пока рассылка идёт. status переходит из scheduled или queued в sending и останавливается на sent, когда каждая переданная копия ушла или не удалась. Он остаётся sending, пока копии ещё ждут, даже если completedAt уже говорит, что последний человек достигнут. failed значит, что вся рассылка остановилась, а lastError говорит почему: с адреса from больше нельзя отправлять, шаблон перестал разрешаться, тариф закончился посередине, сама отправка раз за разом не удавалась, или не удалось записать ни одной копии.

cancel останавливает рассылку в состоянии scheduled, queued или sending. Больше никто не добавляется, и каждая ещё ждущая копия отменяется, а ушедшие копии вернуть нельзя. Когда все копии ушли, cancel выбрасывает 409 broadcast_not_cancellable, а отмена уже отменённой рассылки возвращает её как есть.

Кого она достигла

list_recipients возвращает одну страницу людей, которым ушла рассылка, по строке на копию, с сортировкой по адресу, в виде словаря с items, hasMore и nextCursor. list_all_recipients проходит все страницы в один список, а iterate_recipients выдаёт по одной копии, запрашивая следующую страницу только тогда, когда цикл её просит. limit принимает значения от 1 до 200, по умолчанию 50, а cursor передаётся обратно с теми же filter и q.

filterОставляет
pendingКопии, которые ещё в очереди, запланированы или отправляются.
sentКопии, которые ушли.
deliveredКопии, принятые сервером получателя.
openedКопии, открытые хотя бы раз.
not_openedКопии, отправленные и ни разу не открытые.
clickedКопии хотя бы с одним отслеженным кликом.
bouncedКопии, получившие отказ доставки.
complainedКопии, которые человек отметил как спам.
failedКопии с ошибкой или отменённые.
unsubscribedЛюди, отписавшиеся после отправки рассылки.

BROADCAST_RECIPIENT_FILTERS перечисляет все фильтры по именам, а q ищет по адресу и имени без учёта регистра. Открытия и клики не учитывают прокси изображений и сканеры ссылок и остаются равными 0, если рассылка ушла с выключенным отслеживанием.

get_recipient(id, email_id) возвращает одну копию: ту же строку плюс subject, html и text ровно в том виде, в каком их получил этот человек, с заполненными полями подстановки и его собственной ссылкой для отписки. HTML взят до добавления отслеживания открытий и кликов. email_id, который не является копией этой рассылки, выбрасывает 404 recipient_not_found, а неизвестная рассылка выбрасывает 404 broadcast_not_found.

stats возвращает итоги и ряд. totals считает копии sent, delivered, bounced, complained и failed, с pending для ещё ожидающих, и людей, которые opened, clicked и unsubscribed, с opens и clicks как счётчиками событий. series разрежен и идёт от старых к новым, по одному интервалу на каждый grain (minute, hour или day, по умолчанию hour), в котором что-то произошло, со смещением offset_minutes к востоку от UTC. Каждый человек учитывается один раз, в момент, когда это впервые с ним произошло, поэтому сумма совпадает с итогами.

Ключ, ограниченный определёнными адресами или доменами, достаёт только до рассылок, отправленных с адреса или домена, который у него есть. list, list_all и iterate пропускают остальные, а get, методы получателей, stats и cancel выбрасывают для них 404 broadcast_not_found.

Ответ: BroadcastResource

get и cancel возвращают по одному такому объекту, а send возвращает SentBroadcastResource: те же поля плюс replayed, равное True, когда ответом служит рассылка, созданная более ранним вызовом с тем же ключом идемпотентности. list возвращает их страницу, словарь с items, hasMore и nextCursor, от новых к старым, а list_all и iterate проходят все страницы. preview возвращает BroadcastPreviewResource с audienceIds, recipients, unsubscribed и suppressed. list_recipients возвращает страницу строк BroadcastRecipientResource, get_recipient возвращает BroadcastRecipientContentResource, а stats возвращает BroadcastStatsResource.

idstr
Постоянный идентификатор: `brd_` и 24 шестнадцатеричных символа.
statusBroadcastStatus
`scheduled`, `queued`, `sending`, `sent`, `cancelled` или `failed`. `BROADCAST_STATUSES` называет каждый.
modeApiKeyMode
`live` или `test`, по ключу, который её создал. Копии тестовой рассылки помечаются как отправленные и никому не доставляются.
sourceEmailSource | str
Откуда она запущена: `api` для ключа, `oauth` для подключённого приложения, `composer` для приложения, `mcp` для ассистента.
audienceIdslist[str]
Аудитории, которым она ушла, каждая один раз.
fromstr
Адрес, с которого отправляется каждая копия.
subjectstr
Тема в том виде, как написана, вместе с полями слияния. Пусто, если тему задаёт шаблон.
countsBroadcastCounts
`recipients` содержит оценку, сделанную при `send`. `created` считает записанные копии, `skipped` считает людей, пропущенных потому, что к тому моменту их адрес был подавлен, а `failedToQueue` считает людей, чью копию не удалось записать. `queued`, `sending`, `sent`, `failed` и `cancelled` считают копии по состоянию, в котором каждая находится сейчас.
lastErrorstr | None
Почему рассылка не удалась, или последняя копия, которую не удалось записать, и почему. `None`, пока всё в порядке.
scheduledAtstr | None
ISO-8601 UTC, когда должна начаться отправка. `None` для рассылки, отправленной сразу.
startedAtstr | None
ISO-8601 UTC, когда рассылка достигла первых людей.
completedAtstr | None
ISO-8601 UTC, когда достигнут последний человек. После этого копии ещё могут ждать отправки.
cancelledAtstr | None
ISO-8601 UTC, когда её остановил `cancel`.
createdAtstr
ISO-8601 UTC, когда был вызван `send`. Задаёт порядок в списке.
updatedAtstr
ISO-8601 UTC, обновляется по мере продвижения отправки.

Ответ: BroadcastRecipientResource

Каждая строка list_recipients, list_all_recipients и iterate_recipients. BroadcastRecipientContentResource из get_recipient добавляет subject, html и text.

emailIdstr
Id `msg_` копии этого человека. `get_recipient` читает её вместе с содержимым, а `emails.get` читает её как отправленное письмо.
contactIdstr | None
Контакт, которому она ушла, или `None`, если контакт с тех пор удалён.
emailstr
Адрес, на который ушла копия.
namestr | None
Имя в контакте.
statusstr
Состояние копии: `queued`, `scheduled`, `sending`, `sent`, `failed` или `cancelled`.
sentAtstr | None
ISO-8601 UTC, когда копия ушла.
deliveredAtstr | None
ISO-8601 UTC, когда сервер получателя её принял, первое `email.delivered`.
bouncedAtstr | None
ISO-8601 UTC, когда она получила отказ доставки, первое `email.bounced`.
complainedAtstr | None
ISO-8601 UTC, когда человек отметил её как спам, первое `email.complained`.
failurestr | None
Почему копия завершилась ошибкой, если это случилось.
opensint
Зафиксированные открытия без тех, что создают прокси изображений и сканеры. 0, если отслеживание было выключено.
firstOpenAtstr | None
ISO-8601 UTC, первое открытие.
clicksint
Клики по отслеживаемым ссылкам, без сканеров.
firstClickAtstr | None
ISO-8601 UTC, первый клик.
unsubscribedAtstr | None
ISO-8601 UTC, когда этот человек отписался от одной из аудиторий рассылки после её отправки, по её ссылке или иначе.

Справочник