ارسالهای گروهی
`broadcasts.preview`، `send`، `list`، `list_all`، `iterate`، `get`، `list_recipients`، `list_all_recipients`، `iterate_recipients`، `get_recipient`، `stats`، `analytics` و `cancel`.
همهٔ متدها
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)puts reach[:recipients], reach[:unsubscribed], reach[:suppressed] broadcast = client.broadcasts.send(draft) latest = client.broadcasts.get(broadcast[:id])while %w[scheduled queued sending].include?(latest[:status]) sleep 5 latest = client.broadcasts.get(broadcast[:id])end client.broadcasts.iterate_recipients(broadcast[:id]) do |copy| puts copy[:email], copy[:status], copy[:opens], copy[:clicks]end bounced = client.broadcasts.list_recipients(broadcast[:id], filter: "bounced")bounced.items.each { |row| puts "#{row[:emailId]} #{row[:email]}" } copy = client.broadcasts.get_recipient(broadcast[:id], "msg_01dad25067bc4dac966d515d")puts copy[:subject], copy[:bouncedAt] stats = client.broadcasts.stats(broadcast[:id], grain: "day")puts stats.dig(:totals, :opened), stats.dig(:totals, :clicked), stats.dig(:totals, :unsubscribed) lately = client.broadcasts.stats(broadcast[:id], days: 1)puts lately.dig(:window, :opened) later = client.broadcasts.send(draft, scheduledAt: "P1D")client.broadcasts.cancel(later[:id]) history = client.broadcasts.list(audience_id: draft[:audienceIds].first)puts latest[:status], latest.dig(:counts, :sent), history.items.size month = client.broadcasts.analytics(days: 30)month[:broadcasts].each do |row| puts row[:subject], row[:sent], row[:opened]endارسال گروهی یک پیام را برای همهٔ افراد یک یا چند گروه مخاطب میفرستد، به شکل نسخهای جدا برای هر نفر. هر نسخه دقیقاً یک گیرنده دارد و cc یا bcc ندارد، پس هیچکس نمیبیند برای چه کس دیگری رفته، و هر نسخه ایمیلی معمولی است با شناسهٔ 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: یا کلیدی که gem میسازد، پس تلاش دوباره پس از شکست شبکه بهجای دو بار فرستادن، با ارسال گروهیای که تلاش نخست ساخته پاسخ میدهد، با replayed برابر true. preview، get، cancel و همهٔ خواندنها را میتوان بیخطر تکرار کرد و دوباره تلاش میشوند.
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: Time.now + 3600, idempotency_key: "doors-open-2026-10") puts broadcast[:id], broadcast[:status], broadcast[:replayed]فیلدهای یک ارسال گروهی آرگومانهای کلیدواژهای یا یک Hash هستند و نامهای camelCase در API را نگه میدارند (audienceIds:، scheduledAt:). idempotency_key: و api_key: گزینههای فراخوانیاند و هرگز بهصورت فیلد فرستاده نمیشوند. کلیدواژههایی که کنار یک Hash داده شوند در آن ادغام میشوند، پس send(draft, scheduledAt: "P1D") همان پیشنویس را یک روز بعد میفرستد. scheduledAt: یک Time، یک DateTime، یک String با قالب ISO 8601 یا مدتی مانند PT2H میگیرد، و Time بهصورت یک لحظهٔ UTC فرستاده میشود. preview از آنچه به آن میدهید فقط audienceIds را میفرستد، پس همان Hash ارسال send را میپذیرد. پاسخ یک Hash با کلیدهای Symbol است، پس broadcast[:status] وضعیت را میخواند.
فیلدهای ادغام
subject، html و text برای هر نفر از روی مخاطبش پر میشوند. {{firstName}} نخستین واژهٔ نام مخاطب است، {{lastName}} بقیهٔ آن، {{name}} نام کامل، {{email}} نشانیای که نسخه به آن میرود و {{unsubscribeUrl}} پیوندی که اشتراکش را لغو میکند.
هر فیلد پس از یک خط یک مقدار جایگزین میپذیرد که وقتی مخاطب مقداری برای آن ندارد به کار میرود، پس {{firstName|there}} برای مخاطبی که بینام ذخیره شده "there" میشود. مقدارها در html گریزانده میشوند و هر {{…}} دیگری دقیقاً همانطور که نوشته شده میماند.
برای فرستادن یک قالب ذخیرهشده، template: را بهجای html: و text: بدهید، بهصورت یک Hash با id و بهطور اختیاری version، props و slots. همان پنج مقدار به شکل prop به آن میرسند، ولی فقط propهایی که قالب اعلام میکند، پس قالبی که firstName را اعلام کند آن را میگیرد و قالبی که اعلام نکند هرگز به خاطرش رد نمیشود. هر چه در props آن باشد برای همهٔ نسخهها یکسان میرود.
لغو اشتراک
هر نسخه سرآیندهای لغو اشتراک با یک کلیک را دارد که به برنامهٔ ایمیل اجازه میدهند دکمهٔ لغو اشتراکِ خودش را نشان دهد، چیزی که ارائهدهندگان بزرگ صندوق ایمیل از ایمیل انبوه میخواهند. متن html یا text که خودش {{unsubscribeUrl}} را نگذارد یک پانویس یکخطی با پیوند میگیرد. قالب دقیقاً همانطور که هست فرستاده میشود، پس {{unsubscribeUrl}} را در قالب بگذارید.
لغو اشتراک، فرد را در همهٔ گروههایی که آن ارسال گروهی برایشان رفته لغواشتراککرده علامت میزند، و audiences.list_contacts آن را در unsubscribedAt ردیف او نشان میدهد، همانطور که صفحهٔ «گروههای مخاطب» توضیح میدهد. او در گروه و در دفترچهٔ نشانیها میماند، گروههای دیگرش دست نمیخورند، و ایمیلی که تکتک برایش فرستاده میشود همچنان میرود. بیرون آوردن او از گروه و افزودن دوبارهاش او را از نو مشترک میکند.
چه کسانی رد میشوند
ارسال گروهی به هر مخاطبی میرسد که دستکم در یکی از audienceIds باشد، یک بار هر چند تا که او را داشته باشند. از مخاطبی که از همهٔ آن گروههایی که در آنهاست لغو اشتراک کرده، و از نشانیای که پس از برگشت یا شکایت، یا چون کسی آن را افزوده، در فهرست توقیف است رد میشود. مخاطبی که پس از send ولی پیش از رسیدن ارسال به او به یکی از گروهها افزوده شود، دریافت میکند.
preview همان عددها را بدون ارسال برمیگرداند: recipients، unsubscribed و suppressed. sendی که به هیچکس نرسد 422 no_recipients را بهصورت OpenEmail::ValidationError raise میکند.
کل ارسال پیش از نوشتن هر چیزی با سهمیهٔ ماهانهٔ ارسال در طرح سنجیده میشود، پس ارسال گروهیای که سهمیه پوشش ندهد 429 send_quota_exceeded را بهصورت OpenEmail::RateLimitError raise میکند و چیزی از خود به جا نمیگذارد. هر نسخه یک ارسال حساب میشود.
وضعیت و پیشرفت
get مقدار counts را زنده از نسخهها میخواند، پس در طول ارسال آن را پیاپی بخوانید، با sleep میان فراخوانیها همانطور که نمونهٔ بالا انجام میدهد. status از scheduled یا queued به sending میرود و وقتی هر نسخهٔ سپردهشده رفته یا ناموفق شده روی sent میایستد. تا وقتی نسخهها هنوز منتظرند sending میماند، حتی پس از آنکه completedAt بگوید به آخرین نفر رسیده. failed یعنی کل ارسال گروهی متوقف شده و lastError دلیلش را میگوید: دیگر نمیشود از نشانی from فرستاد، قالب دیگر بارگذاری نمیشود، طرح در میانهٔ راه تمام شد، خودِ ارسال پیاپی ناموفق ماند، یا حتی یک نسخه هم نوشته نشد.
cancel ارسال گروهیای را که scheduled، queued یا sending است متوقف میکند. کسی دیگر افزوده نمیشود و هر نسخهای که هنوز منتظر است لغو میشود، در حالی که نسخههای رفته برگرداندنی نیستند. وقتی همهٔ نسخهها رفته باشند، cancel خطای 409 broadcast_not_cancellable را بهصورت OpenEmail::ConflictError raise میکند، و لغو یک ارسال گروهیِ لغوشده آن را با همان حالتی که هست برمیگرداند.
به چه کسانی رسید
list_recipients یک OpenEmail::Page از کسانی که ارسال گروهی برایشان رفت برمیگرداند، یک ردیف برای هر نسخه، مرتبشده بر اساس نشانی، با items، has_more? و next_cursor. list_all_recipients همهٔ صفحهها را در یک Array میپیماید، و iterate_recipients هر بار یک نسخه را به یک بلاک yield میکند و صفحهٔ بعد را فقط وقتی حلقه بخواهد میگیرد. بدون بلاک یک Enumerator برمیگرداند. limit: از 1 تا 200 است با پیشفرض 50، و cursor: با همان filter: و q: پس داده میشود.
| `filter:` | نگه میدارد |
|---|---|
| pending | نسخههایی که هنوز در صف، زمانبندیشده یا در حال ارسالاند. |
| sent | نسخههایی که فرستاده شدند. |
| delivered | نسخههایی که سرور گیرنده پذیرفت. |
| opened | نسخههایی که دستکم یک بار باز شدند. |
| not_opened | نسخههایی که فرستاده شدند و هرگز باز نشدند. |
| clicked | نسخههایی با دستکم یک کلیک ردیابیشده. |
| bounced | نسخههایی که برگشت خوردند. |
| complained | نسخههایی که آن شخص به عنوان هرزنامه گزارش کرد. |
| failed | نسخههایی که ناموفق بودند یا لغو شدند. |
| unsubscribed | افرادی که پس از ارسال گروهی لغو اشتراک کردند. |
OpenEmail::BROADCAST_RECIPIENT_FILTERS هر فیلتر را نام میبرد، و q: نشانی و نام را بدون توجه به بزرگی و کوچکی حروف جستوجو میکند. باز کردنها و کلیکها پراکسیهای تصویر و اسکنرهای پیوند را کنار میگذارند، و وقتی ارسال گروهی با ردیابی خاموش رفته باشد 0 میمانند.
get_recipient(id, email_id) یک نسخه را برمیگرداند: همان ردیف، بهعلاوهٔ subject، html و text دقیقاً همانطور که آن شخص دریافت کرد، با فیلدهای ادغامِ پرشده و پیوند لغو اشتراک مخصوص خودش. emailId یک ردیف را بهعنوان email_id بدهید. HTML مربوط به پیش از افزودن ردیابی باز کردن و کلیک است. email_idی که نسخهای از این ارسال گروهی نیست 404 recipient_not_found را raise میکند، و ارسال گروهی ناشناخته 404 broadcast_not_found را، هر دو بهصورت OpenEmail::NotFoundError.
stats مجموعها و یک سری را برمیگرداند. totals نسخههای sent، delivered، bounced، complained و failed را میشمارد، با pending برای آنهایی که هنوز در انتظارند، و افرادی را که opened، clicked و unsubscribed شدند، با opens و clicks بهعنوان شمار رویدادها. series پراکنده است و قدیمیترین اول، یک بازه برای هر grain: (minute، hour یا day، با پیشفرض hour) که در آن چیزی رخ داده، بریدهشده در منطقهٔ زمانیای که offset_minutes: دقیقه در شرق UTC است. برای منطقهٔ زمانی محلی Time.now.utc_offset / 60 را بدهید. هر کس را یک بار میشمارد، در نخستین باری که برایش رخ داد، پس جمعش با مجموعها برابر میشود.
برای اینکه آنچه اخیراً رخ داده را هم بخوانید، days: یا minutes: را به stats بدهید. آنگاه window آنچه را درون آن تحویل شده، برگشت خورده، هرزنامه گزارش شده، باز شده، کلیک شده و لغو اشتراک شده میشمارد، و series فقط بازههای همان پنجره را نگه میدارد، در حالی که totals همچنان کل ارسال گروهی را در بر میگیرد. بدون هیچکدام، window برابر nil است.
کلیدی که به نشانیها یا دامنههای خاصی محدود است فقط به ارسالهای گروهیای دسترسی دارد که از نشانی یا دامنهای که دارد فرستاده شدهاند. list، list_all و iterate بقیه را کنار میگذارند، و get، متدهای گیرندگان، stats و cancel برای آنها 404 broadcast_not_found را raise میکنند.
پاسخ: یک ارسال گروهی
send، get و cancel هرکدام یکی از اینها را برمیگردانند، یک Hash با کلیدهای Symbol، و send مقدار replayed را هم میافزاید. list یک OpenEmail::Page از آنها برمیگرداند، تازهترین اول، و list_all و iterate همهٔ صفحهها را میپیمایند. preview یک Hash با audienceIds، recipients، unsubscribed و suppressed برمیگرداند. list_recipients یک OpenEmail::Page از ردیفهای گیرنده برمیگرداند، get_recipient یک ردیف را همراه محتوایش برمیگرداند، و stats یک Hash با broadcastId، grain، totals، window و series برمیگرداند. analytics یک Hash با totals، series و یک ردیف برای هر ارسال گروهی در broadcasts برمیگرداند. زمانها Stringهایی با قالب ISO 8601 هستند که Time.iso8601 آنها را تجزیه میکند.
idString- شناسهٔ ماندگار، `brd_` و پس از آن ۲۴ نویسهٔ هگزادسیمال.
statusString- `scheduled`، `queued`، `sending`، `sent`، `cancelled` یا `failed`. `OpenEmail::BROADCAST_STATUSES` هرکدام را نام میبرد.
modeString- `live` یا `test`، بسته به کلیدی که آن را ساخته. نسخههای ارسال گروهیِ آزمایشی ارسالشده علامت میخورند و به هیچکس تحویل داده نمیشوند.
sourceString- از کجا شروع شده: `api` برای کلید، `oauth` برای برنامهٔ متصل، `composer` برای خود برنامه، `mcp` برای دستیار.
audienceIdsArray<String>- گروههایی که برایشان فرستاده شده، هر کدام یک بار.
fromString- نشانیای که هر نسخه از آن فرستاده میشود.
subjectString- موضوع همانطور که نوشته شده، با فیلدهای ادغام. خالی وقتی قالب موضوع را میدهد.
countsHash- `recipients` تخمینی است که هنگام `send` گرفته شده. `created` نسخههای نوشتهشده را میشمارد، `skipped` کسانی را که چون نشانیشان تا آن موقع توقیف بود کنار گذاشته شدند، و `failedToQueue` کسانی را که نسخهشان نوشته نشد. `queued`، `sending`، `sent`، `failed` و `cancelled` نسخهها را بر اساس وضعیتی که هر کدام الان دارد میشمارند.
lastErrorString or nil- اینکه ارسال گروهی چرا ناموفق شد، یا تازهترین نسخهای که نوشته نشد و چرا. تا وقتی مشکلی پیش نیامده nil است.
scheduledAtString or nil- ISO-8601 به وقت UTC، زمانی که ارسال باید شروع شود. برای ارسال گروهیای که بیدرنگ فرستاده شده nil است.
startedAtString or nil- ISO-8601 UTC، زمانی که ارسال به نخستین افراد رسید.
completedAtString or nil- ISO-8601 UTC، زمانی که به آخرین نفر رسید. پس از آن هنوز ممکن است نسخههایی منتظر رفتن باشند.
cancelledAtString or nil- ISO-8601 UTC، زمانی که `cancel` آن را متوقف کرد.
createdAtString- ISO-8601 UTC، زمانی که `send` فراخوانده شد. ترتیب فهرست را تعیین میکند.
updatedAtString- ISO-8601 UTC، با پیشرفت ارسال بهروز میشود.
پاسخ: یک ردیف گیرنده
هر ردیف list_recipients، list_all_recipients و iterate_recipients، بهصورت یک Hash با کلیدهای Symbol. Hashی که get_recipient برمیگرداند subject، html و text را هم میافزاید.
emailIdString- شناسهٔ `msg_` نسخهٔ این شخص. `get_recipient` آن را همراه محتوایش میخواند، و `emails.get` آن را بهعنوان یک ایمیل ارسالشده میخواند، همانطور که صفحهٔ «فهرست و دریافت» توضیح میدهد.
contactIdString or nil- مخاطبی که نسخه برایش رفت، یا nil وقتی مخاطب از آن پس حذف شده باشد.
emailString- نشانیای که نسخه به آن رفت.
nameString or nil- نام روی مخاطب.
statusString- وضعیت نسخه: `queued`، `scheduled`، `sending`، `sent`، `failed` یا `cancelled`.
sentAtString or nil- ISO-8601 UTC، زمانی که نسخه فرستاده شد.
deliveredAtString or nil- ISO-8601 UTC، زمانی که سرور گیرنده آن را پذیرفت، نخستین `email.delivered`.
bouncedAtString or nil- ISO-8601 UTC، زمانی که برگشت خورد، نخستین `email.bounced`.
complainedAtString or nil- ISO-8601 UTC، زمانی که آن شخص آن را به عنوان هرزنامه گزارش کرد، نخستین `email.complained`.
failureString or nil- دلیل ناموفق بودن نسخه، اگر ناموفق بود.
opensInteger- باز کردنهای ثبتشده، بدون آنهایی که پراکسیهای تصویر و اسکنرها ایجاد میکنند. وقتی ردیابی خاموش بود 0 است.
firstOpenAtString or nil- ISO-8601 UTC، نخستین باز کردن.
clicksInteger- کلیکهای ثبتشده روی لینکهای ردیابیشده، بدون اسکنرها.
firstClickAtString or nil- ISO-8601 UTC، نخستین کلیک.
unsubscribedAtString or nil- ISO-8601 به وقت UTC، زمانی که این شخص پس از ارسال، از راه پیوند آن یا به هر راه دیگری، از یکی از گروههای مخاطب ارسال گروهی لغو اشتراک کرد.