Toplu gönderimler
`broadcasts->preview`, `send`, `list`, `listAll`, `iterate`, `get`, `listRecipients`, `listAllRecipients`, `iterateRecipients`, `getRecipient`, `stats`, `analytics` ve `cancel`.
Her yöntem
use OpenEmail\Constants\BroadcastRecipientFilters;use OpenEmail\Constants\BroadcastStatuses; $draft = [ '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 = $client->broadcasts->preview($draft);echo $reach['recipients'], ' ', $reach['unsubscribed'], ' ', $reach['suppressed'], PHP_EOL; $broadcast = $client->broadcasts->send($draft); $latest = $client->broadcasts->get($broadcast['id']); while (in_array($latest['status'], [BroadcastStatuses::SCHEDULED, BroadcastStatuses::QUEUED, BroadcastStatuses::SENDING], true)) { sleep(5); $latest = $client->broadcasts->get($broadcast['id']);} foreach ($client->broadcasts->iterateRecipients($broadcast['id']) as $copy) { echo $copy['email'], ' ', $copy['status'], ' ', $copy['opens'], ' ', $copy['clicks'], PHP_EOL;} $bounced = $client->broadcasts->listRecipients($broadcast['id'], filter: BroadcastRecipientFilters::BOUNCED); foreach ($bounced as $row) { echo $row['emailId'], ' ', $row['email'], PHP_EOL;} $copy = $client->broadcasts->getRecipient($broadcast['id'], 'msg_01dad25067bc4dac966d515d');echo $copy['subject'], ' ', $copy['bouncedAt'] ?? 'not bounced', PHP_EOL; $stats = $client->broadcasts->stats($broadcast['id'], grain: 'day');echo $stats['totals']['opened'], ' ', $stats['totals']['clicked'], ' ', $stats['totals']['unsubscribed'], PHP_EOL; $lately = $client->broadcasts->stats($broadcast['id'], days: 1);echo $lately['window']['opened'] ?? 0, PHP_EOL; $later = $client->broadcasts->send([...$draft, 'scheduledAt' => 'P1D']);$client->broadcasts->cancel($later['id']); $history = $client->broadcasts->list(audienceId: $draft['audienceIds'][0]);echo $latest['status'], ' ', $latest['counts']['sent'], ' ', count($history), PHP_EOL; $month = $client->broadcasts->analytics(days: 30); foreach ($month['broadcasts'] as $row) { echo $row['subject'], ' ', $row['sent'], ' ', $row['opened'], PHP_EOL;}Toplu gönderim, bir ya da daha fazla kitledeki herkese her kişi için ayrı bir kopya olarak tek bir ileti gönderir. Her kopyanın tam olarak bir alıcısı vardır, cc ya da bcc yoktur; bu yüzden kimse başka kime gittiğini görmez ve her kopya kendi msg_ kimliği, olayları, izlemesi ve webhook'ları olan sıradan bir e-postadır. listRecipients onları her birine ne olduğuyla birlikte listeler. Kopyalar Gönderilenler klasörüne kaydedilmez, çünkü toplu gönderim kayıttır.
send, toplu gönderim queued durumunda (ya da gövde scheduledAt taşıdığında scheduled durumunda) olarak hemen döner ve gönderim arka planda çalışır. send, emails:send ve audiences:read gerektirir; preview ise audiences:read gerektirir. list, listAll, iterate, get, listRecipients, listAllRecipients, iterateRecipients, getRecipient, stats ve analytics emails:read, cancel ise emails:send gerektirir.
Her send bir Idempotency-Key taşır: idempotencyKey: ile verdiğiniz ya da istemcinin ürettiği. Bu yüzden bir ağ hatasından sonraki yeniden deneme iki kez göndermek yerine, ilk denemenin oluşturduğu toplu gönderimle ve replayed değeri true olarak yanıt verir. preview, get, cancel ve her okuma tekrarlanmaya güvenlidir ve yeniden denenir.
$broadcast = $client->broadcasts->send([ 'audienceIds' => ['aud_4c1b8e2a7d9f05c36b4e8a71'], 'from' => 'Acme <[email protected]>', 'subject' => 'Doors open on Friday', 'text' => 'Hi {{firstName|there}}, doors open at nine. Unsubscribe: {{unsubscribeUrl}}', 'scheduledAt' => new \DateTimeImmutable('+1 hour'),], idempotencyKey: 'doors-open-2026-10'); echo $broadcast['id'], ' ', $broadcast['status'], ' ', $broadcast['replayed'] ? 'replayed' : 'new', PHP_EOL;Bir toplu gönderimin alanları, API'nin camelCase adlarıyla tek bir dizinin anahtarlarıdır (audienceIds, scheduledAt). idempotencyKey: ve apiKey: çağrının adlandırılmış argümanlarıdır ve asla alan olarak gönderilmez. Bir taslağı bir alanın yanında yeni bir diziye yaymak, aynı taslağı yalnızca o değişiklikle gönderir; bu yüzden send([...$draft, 'scheduledAt' => 'P1D']) onu bir gün sonra gönderir. scheduledAt bir DateTimeInterface, bir ISO 8601 dizesi ya da PT2H gibi bir süre alır ve bir DateTimeInterface bir UTC anı olarak gider. preview ona verdiklerinizden yalnızca audienceIds gönderir; bu yüzden send ile aynı diziyi alır. Bir yanıt camelCase anahtarlı bir dizidir; bu yüzden $broadcast['status'] durumu okur.
Birleştirme alanları
subject, html ve text her kişi için kendi kişi kaydından doldurulur. {{firstName}} kişi adının ilk sözcüğü, {{lastName}} geri kalanı, {{name}} tam ad, {{email}} kopyanın gittiği adres ve {{unsubscribeUrl}} onun aboneliğini sonlandıran bağlantıdır.
Her alan çizgiden sonra bir yedek değer alır; kişinin o alan için değeri yoksa kullanılır, bu yüzden {{firstName|there}} adsız kaydedilmiş bir kişi için "there" olur. Değerler html içinde kaçırılır ve diğer her {{…}} tam yazıldığı gibi bırakılır.
Kayıtlı bir şablonu göndermek için html ve text yerine, id ve isteğe bağlı version, props ve slots içeren bir dizi olarak template geçirin. Aynı beş değer ona props olarak ulaşır, ancak yalnızca şablonun bildirdiği props; bu yüzden firstName bildiren bir şablon onu alır, bildirmeyen ise bu yüzden asla reddedilmez. props içindeki her şey her kopyaya aynı şekilde gider.
Abonelikten çıkma
Her kopya, bir posta istemcisinin kendi abonelikten çıkma düğmesini göstermesini sağlayan tek tık abonelikten çıkma başlıklarını taşır; büyük posta kutusu sağlayıcılarının toplu postadan istediği de budur. {{unsubscribeUrl}}'i kendisi yerleştirmeyen bir html ya da text gövdesine bağlantıyı içeren tek satırlık bir alt bilgi eklenir. Şablon tam olduğu gibi gönderilir, bu yüzden {{unsubscribeUrl}}'i şablona koyun.
Abonelikten çıkmak, kişiyi o toplu gönderimin gittiği her kitlede abonelikten çıkmış olarak işaretler ve Kitleler sayfasında anlatıldığı gibi audiences->listContacts bunu kişinin satırındaki unsubscribedAt alanında gösterir. Kişi kitlede ve adres defterinde kalır, diğer kitlelerine dokunulmaz ve ona tek tek gönderilen postalar gitmeye devam eder. Onu kitleden çıkarıp yeniden eklemek yeniden abone yapar.
Kimler atlanır
Toplu gönderim, audienceIds içindekilerden en az birinde bulunan her kişiye, kaçında bulunursa bulunsun bir kez ulaşır. İçinde bulunduğu bu kitlelerin her birinden abonelikten çıkmış kişiyi ve bir geri dönme ya da şikâyet sonrasında veya biri eklediği için engelleme listesinde olan adresi atlar. send'den sonra ama gönderim ona ulaşmadan önce kitlelerden birine eklenen kişi dahil edilir.
preview göndermeden aynı sayıları döndürür: recipients, unsubscribed ve suppressed. Hiç kimseye ulaşmayacak bir send, ValidationException olarak 422 no_recipients fırlatır.
Herhangi bir şey yazılmadan önce gönderimin tamamı planın aylık gönderim sayısıyla karşılaştırılır; bu yüzden kotanın karşılayamadığı bir toplu gönderim RateLimitException olarak 429 send_quota_exceeded fırlatır ve geride hiçbir şey bırakmaz. Her kopya bir gönderim sayılır.
Durum ve ilerleme
get, counts değerini kopyalardan canlı okur; bu yüzden bir toplu gönderim sürerken, yukarıdaki örnekte olduğu gibi çağrılar arasında sleep() ile onu yoklayın. status, scheduled ya da queued durumundan sending durumuna geçer ve devredilen her kopya gittiğinde ya da başarısız olduğunda sent durumuna oturur. completedAt son kişiye ulaşıldığını söyledikten sonra bile kopyalar hâlâ bekliyorsa sending olarak kalır. failed toplu gönderimin tamamının durduğu anlamına gelir ve lastError nedenini söyler: from adresinden artık gönderim yapılamıyordur, şablon çözümlenemez olmuştur, plan yarı yolda tükenmiştir, gönderimin kendisi sürekli başarısız olmuştur ya da tek bir kopya bile yazılamamıştır.
cancel, scheduled, queued ya da sending durumundaki bir toplu gönderimi durdurur. Başka kimse eklenmez ve hâlâ bekleyen her kopya iptal edilir; gitmiş kopyalar ise geri çağrılamaz. Her kopya gittikten sonra cancel, ConflictException olarak 409 broadcast_not_cancellable fırlatır; iptal edilmiş bir toplu gönderimi iptal etmek ise onu olduğu gibi döndürür.
Kime ulaştı
listRecipients, bir toplu gönderimin gittiği kişilerden oluşan, kopya başına bir satır içeren, adrese göre sıralanmış ve items, hasMore ile nextCursor içeren bir OpenEmail\Result\Page döndürür. listAllRecipients her sayfayı dolaşarak tek bir dizi oluşturur, iterateRecipients ise kopyaları birer birer veren ve bir sonraki sayfayı yalnızca döngü istediğinde getiren bir Generator döndürür. limit: 1 ile 200 arasıdır ve varsayılanı 50'dir; bir cursor: aynı filter: ve q: ile geri gönderilir.
| `filter:` | Tuttukları |
|---|---|
| pending | Hâlâ kuyrukta, zamanlanmış ya da gönderilmekte olan kopyalar. |
| sent | Gönderilen kopyalar. |
| delivered | Alıcı sunucunun kabul ettiği kopyalar. |
| opened | En az bir kez açılan kopyalar. |
| not_opened | Gönderilmiş ve hiç açılmamış kopyalar. |
| clicked | En az bir izlenen tıklaması olan kopyalar. |
| bounced | Geri dönen kopyalar. |
| complained | Kişinin spam olarak bildirdiği kopyalar. |
| failed | Başarısız olan ya da iptal edilen kopyalar. |
| unsubscribed | Toplu gönderimden sonra abonelikten çıkan kişiler. |
OpenEmail\Constants\BroadcastRecipientFilters her filtreyi adlandırır; q: ise büyük/küçük harfi yok sayarak adreste ve adda arar. Açılmalar ve tıklamalar görsel proxy'lerini ve bağlantı tarayıcılarını dışarıda bırakır ve toplu gönderim izleme kapalıyken gittiyse 0 olarak kalır.
getRecipient($id, $emailId) tek bir kopya döndürür: aynı satır ve ek olarak, birleştirme alanları doldurulmuş ve kişinin kendi abonelikten çıkma bağlantısıyla, o kişinin aldığı hâliyle subject, html ve text. Bir satırın emailId değerini ikinci argüman olarak geçirin. HTML, açılma ve tıklama izlemesi eklenmeden önceki hâlidir. Bu toplu gönderimin kopyası olmayan bir emailId 404 recipient_not_found, bilinmeyen bir toplu gönderim ise 404 broadcast_not_found fırlatır; ikisi de NotFoundException olarak.
stats toplamları ve bir seri döndürür. totals; sent, delivered, bounced, complained ve failed kopyalarını, hâlâ bekleyenler için pending değerini ve opened, clicked ve unsubscribed olan kişileri sayar; opens ve clicks ise olay sayılarıdır. series seyrektir ve en eskiden başlar: bir şey olan her grain: (minute, hour ya da day, varsayılanı hour) için bir aralık; aralıklar UTC'nin offsetMinutes: kadar doğusundaki saat dilimine göre kesilir. Yerel saat dilimi için intdiv((int) date('Z'), 60) geçirin. Her kişiyi, olay onun başına ilk geldiği anda bir kez sayar; bu yüzden toplamı totals ile tutar.
Son zamanlarda ne olduğunu da okumak için stats çağrısına days: ya da minutes: geçirin. Bu durumda window, pencere içinde teslim edileni, geri döneni, spam olarak bildirileni, açılanı, tıklananı ve abonelikten çıkılanı sayar; series yalnızca o pencerenin aralıklarını tutar, totals ise yine toplu gönderimin tamamını kapsar. İkisi de yoksa window null'dır.
Belirli adreslerle ya da alan adlarıyla sınırlı bir anahtar, yalnızca sahip olduğu bir adresten ya da alan adından gönderilen toplu gönderimlere ulaşır. list, listAll ve iterate diğerlerini dışarıda bırakır; get, alıcı metotları, stats ve cancel ise onlar için 404 broadcast_not_found fırlatır.
Yanıt: bir toplu gönderim
send, get ve cancel her biri bunlardan birini camelCase anahtarlı bir dizi olarak döndürür; send ayrıca replayed ekler. list bunlardan oluşan, en yeniden eskiye bir OpenEmail\Result\Page döndürür; listAll hepsini tek bir dizide döndürür, iterate ise bunlar üzerinde bir Generator döndürür. preview, audienceIds, recipients, unsubscribed ve suppressed içeren bir dizi döndürür. listRecipients alıcı satırlarından oluşan bir Page, getRecipient içeriğiyle birlikte tek bir satır, stats ise broadcastId, grain, totals, window ve series içeren bir dizi döndürür. analytics, totals, series ve broadcasts içinde her toplu gönderim için bir satır içeren bir dizi döndürür. Zamanlar, new \DateTimeImmutable() ile okunabilen ISO 8601 dizeleridir.
idstring- Kalıcı tanıtıcı, `brd_` ardından 24 onaltılık karakter.
statusstring- `scheduled`, `queued`, `sending`, `sent`, `cancelled` ya da `failed`. `OpenEmail\Constants\BroadcastStatuses` her birini adlandırır.
modestring- Onu oluşturan anahtara göre `live` ya da `test`. Bir test toplu gönderiminin kopyaları gönderildi olarak işaretlenir ve kimseye teslim edilmez.
sourcestring- Nereden başlatıldığı: anahtar için `api`, bağlı bir uygulama için `oauth`, uygulama için `composer`, bir asistan için `mcp`.
audienceIdsarray- Gönderildiği kitleler, her biri bir kez.
fromstring- Her kopyanın gönderildiği adres.
subjectstring- Yazıldığı gibi konu, birleştirme alanlarıyla birlikte. Konuyu bir şablon sağladığında boştur.
countsarray- `recipients`, `send` sırasında alınan tahmindir. `created` yazılan kopyaları, `skipped` o zamana kadar adresleri engellendiği için atlanan kişileri, `failedToQueue` ise kopyası yazılamayan kişileri sayar. `queued`, `sending`, `sent`, `failed` ve `cancelled` kopyaları her birinin şu anki durumuna göre sayar.
lastErrorstring or null- Toplu gönderimin neden başarısız olduğu ya da yazılamayan en son kopya ve nedeni. Hiçbir sorun olmadığı sürece null.
scheduledAtstring or null- ISO-8601 UTC; gönderimin başlaması gereken an. Hemen gönderilen bir toplu gönderim için null.
startedAtstring or null- ISO-8601 UTC, gönderimin ilk kişilere ulaştığı zaman.
completedAtstring or null- ISO-8601 UTC, son kişiye ulaşıldığı zaman. Bundan sonra da kopyalar gitmeyi bekliyor olabilir.
cancelledAtstring or null- ISO-8601 UTC, `cancel`'ın onu durdurduğu zaman.
createdAtstring- ISO-8601 UTC, `send`'in çağrıldığı zaman. Liste sırasını belirler.
updatedAtstring- ISO-8601 UTC, gönderim ilerledikçe güncellenir.
Yanıt: bir alıcı satırı
listRecipients, listAllRecipients ve iterateRecipients çağrılarının her satırı, camelCase anahtarlı bir dizi olarak. getRecipient çağrısının döndürdüğü dizi ayrıca subject, html ve text ekler.
emailIdstring- Bu kişinin kopyasının `msg_` kimliği. `getRecipient` onu içeriğiyle birlikte okur; `emails->get` ise Listeleme ve getirme sayfasında anlatıldığı gibi gönderilmiş bir e-posta olarak okur.
contactIdstring or null- Gittiği kişi ya da kişi o zamandan beri silindiyse null.
emailstring- Kopyanın gittiği adres.
namestring or null- Kişi kaydındaki ad.
statusstring- Kopyanın durumu: `queued`, `scheduled`, `sending`, `sent`, `failed` ya da `cancelled`.
sentAtstring or null- ISO-8601 UTC, kopyanın gönderildiği zaman.
deliveredAtstring or null- ISO-8601 UTC, alıcı sunucunun onu kabul ettiği zaman, ilk `email.delivered`.
bouncedAtstring or null- ISO-8601 UTC, geri döndüğü zaman, ilk `email.bounced`.
complainedAtstring or null- ISO-8601 UTC, kişinin onu spam olarak bildirdiği zaman, ilk `email.complained`.
failurestring or null- Başarısız olduysa kopyanın neden başarısız olduğu.
opensint- Kaydedilen açmalar, görsel proxy'lerinin ve tarayıcıların oluşturdukları hariç. İzleme kapalıysa 0.
firstOpenAtstring or null- ISO-8601 UTC, ilk açma.
clicksint- İzlenen bağlantılarda kaydedilen tıklamalar, tarayıcılar hariç.
firstClickAtstring or null- ISO-8601 UTC, ilk tıklama.
unsubscribedAtstring or null- ISO-8601 UTC; bu kişinin, toplu gönderim gittikten sonra onun bağlantısı aracılığıyla ya da başka bir yolla, toplu gönderimin kitlelerinden birinden abonelikten çıktığı an.