Odeslání e-mailu
`emails.send`: jedna zpráva, hned nebo později.
emails.send
const email = await openemail.emails.send({ from: { email: '[email protected]', name: 'Acme Billing' }, to: ['[email protected]', 'Grace <[email protected]>'], cc: '[email protected]', bcc: [{ email: '[email protected]' }], replyTo: '[email protected]', subject: 'Your September invoice', html: '<p>Invoice attached.</p>', text: 'Invoice attached.', headers: { 'X-Campaign': 'invoices' }, attachments: [{ filename: 'invoice.pdf', content: pdfBytes }], threadId: 'thread_…', scheduledAt: 'PT1H', tags: { order: '4021' }, tracking: { opens: true, clicks: true },})to, cc a bcc přijímají jednoho příjemce i více; jediného za vás zabalíme do pole. Každý může být holá adresa, Name <addr@host> nebo { email, name }.
Parametry
fromRecipientInputpovinné- Odesílatel. Holá adresa, `Name <addr@host>` nebo objekt. Musí to být adresa, pod kterou tento klíč smí odesílat. Žádný záložní odesílatel neexistuje, protože záložním by byla výchozí adresa pracovního prostoru, která se mění, jak adresy přibývají a ubývají.
toRecipientInput | RecipientInput[]povinné- Jeden příjemce nebo více; jediného za vás zabalíme do pole. Nejvýše 50 dohromady napříč to, cc a bcc.
ccRecipientInput | RecipientInput[]- Započítává se do limitu 50 příjemců.
bccRecipientInput | RecipientInput[]- V bajtech, které dostane kdokoli jiný, se nikdy neobjeví, protože se pro každého příjemce přenáší samostatná obálka.
replyToRecipientInput- Jediná adresa, odesílaná jako hlavička Reply-To.
subjectstring- Nejvýše 998 znaků, limit řádku podle RFC 5322. Výchozí je prázdný.
htmlstring- Vyžaduje se jedno z html, text, draftId nebo template. Když zadáte html i text, příjemci uvidí HTML.
textstring- Část v prostém textu.
template{ id, version?, props?, slots? }- Vykreslí uloženou šablonu na serveru. `version` připíná konkrétní revizi; vynechejte ji, aby se použilo to, co je publikováno v okamžiku přijetí požadavku. Neznámá nebo chybějící prop je 422, ne prázdné místo ve zprávě.
draftIdstring- Odešle uložený koncept pod touto obálkou.
headersRecord<string, string>- `X-*`, `List-*`, Reply-To, Precedence, Auto-Submitted, Importance, Priority a Feedback-Id. Cokoli, co si nastavuje sám transport, je odmítnuto, ne tiše zahozeno.
attachmentsAttachmentInput[]- `{ filename, content, contentType? }`, nebo `{ fileId }` odkazující na soubor, který už v pracovním prostoru je. Předejte jako obsah bajty a zakódujeme je za vás do base64. 20 souborů, přičemž vložené soubory mají po dekódování dohromady limit 5 MB. Uložený soubor může být větší a putuje jako odkaz ke stažení.
attachmentDeliveryAttachmentDeliveryMode- `mime`, `link` nebo `auto`. `auto` posílá soubory jako odkazy ke stažení, jakmile na doméně s aktivní doménou pro soubory přesáhnou 2 MB, jinak je nese uvnitř zprávy. Když to vynecháte, uplatní se nastavení schránky, jehož výchozí hodnota je `auto`.
threadIdstring- Odpověď do existujícího vlákna. Transport zapíše In-Reply-To a References.
scheduledAtDate | string- Date, okamžik podle ISO-8601 nebo doba trvání jako `PT1H`. Nejvýše rok dopředu, nikdy do minulosti. Nelze kombinovat s cancellableForSeconds.
cancellableForSecondsnumber- 0 až 900. Okno pro vzetí zpět u okamžitého odeslání: mechanismus vzetí zpět známý z editoru zpráv, vystavený ven místo napevno zadrátované hodnoty.
tagsRecord<string, string>- Až 10 štítků, vracejí se zpět a lze podle nich filtrovat. Nikdy se nijak neinterpretují.
signatureboolean- Zda tato zpráva nese podpis adresy, ze které se odesílá, tedy vlastní podpis té adresy, případně podpis nastavený pro Všechny adresy. Výchozí hodnota je true, protože podpis patří adrese, ne tomu klientovi, který zprávu poslal. Nastavte `false` u pošty, kterou odesílá program za někoho jiného – u potvrzení, resetu hesla nebo souhrnu – pod žádnou z nich se lidský podpis nehodí.
tracking{ opens?, clicks? }- Zda k této zprávě přidat pixel pro otevření a přepsat odkazy. Zapnuto, pokud vlastník pracovního prostoru nevypnul sledování pro adresu, ze které se odesílá, nebo pro Všechny adresy; kterékoli z těchto polí uvedené zde rozhodne o té jedné zprávě bez ohledu na to, jak je adresa nastavená.
translate{ to, from?, subject?, includeOriginal? }- Odešle zprávu v jazyce příjemce. `to` přijímá kód, anglický název nebo vlastní název jazyka; `subject` i `includeOriginal` mají výchozí hodnotu true. Vyhodnocuje se při přijetí požadavku, takže naplánovaná zpráva nese slova, která byla schválena. Odmítnuto společně s `draftId`.
Odpověď
idstring- Id odeslání, `msg_…`. Použijte je pro `get`, `cancel`, `reschedule` a `getTracking`.
statusEmailStatus- queued, scheduled, sending, sent, partial, cancelled nebo failed. Řiďte se tímhle, ne tím, že se promise vyřešila. `partial` je samostatný stav: někteří příjemci zprávu mají a odeslání jim nelze vzít zpět, takže opakovat odeslání je chyba a hlásit selhání je lež.
mode'live' | 'test'- Jakým druhem klíče byla zpráva odeslána. Testovací odeslání se zaznamená a nikdy nepřenáší.
fromstring- Adresa, která byla skutečně autorizována a odeslána po drátě; není to vždy ta, o kterou se žádalo.
subjectstring | null- Tak, jak bylo odesláno.
messageIdstring | null- Message-ID podle RFC 5322. Null, dokud MIME neexistuje. Odesílací služba hlavičku cestou ven přepisuje, takže tuhle hodnotu nenese žádný bounce ani hlášení o doručení. Událost se vrací pod `id`.
threadIdstring | null- Vlákno, do kterého zpráva přistála.
transportstring | null- Jak zpráva odešla. Null až do odeslání.
attemptsnumber- Kolikrát bylo odeslání zkoušeno.
lastErrorstring | null- Proč poslední pokus selhal, doslova.
scheduledAtstring | null- Okamžik v ISO, kdy má zpráva odejít.
cancellableUntilstring | null- Dokud je současný okamžik před tímto, zrušení stále funguje.
sentAtstring | null- Okamžik v ISO, kdy zpráva odešla.
tagsRecord<string, string>- To, co jste poslali, vrácené zpět.
sourceEmailSource- composer, api, mcp, ai nebo queue: které rozhraní o odeslání požádalo. `api` je tento klient.
createdAtstring- Okamžik v ISO, kdy byl záznam zapsán.
replayedboolean- True, když Idempotency-Key odpovídal odeslání, které už existovalo. Nic nového se neodeslalo a tohle je původní zpráva.
translationEmailTranslationResource | undefined- Přítomné jen u zprávy, která byla přeložena, a jen tam, kde se nese celý uložený požadavek: v této odpovědi a v `get`. `{ language, languageName, detectedSourceLanguage, subject, includeOriginal }`, vše jako kódy, ne jako celé jazykové záznamy. Řádek seznamu to nikdy nemá, takže tam jeho nepřítomnost neříká nic ani tak, ani tak.
V jazyce příjemce
translate napíše zprávu v jazyce někoho jiného ještě předtím, než odejde. Tělo – a pokud to nevypnete, i předmět – se přeloží ve chvíli, kdy API požadavek přijme, a ven jde přesně to, co z překladu vyšlo: překlad, který se nepodařilo vytvořit, odeslání odmítne, místo aby zprávu poslal v jazyce, ve kterém jste ji napsali.
const email = await openemail.emails.send({ from: '[email protected]', to: '[email protected]', subject: 'Your September invoice', html: '<p>Invoice attached. Payment is due on the 14th.</p>', translate: { to: 'de' },}) console.log(email.translation)// { language: 'de', languageName: 'German', detectedSourceLanguage: 'en', subject: true, includeOriginal: true }Tohle si před odesláním nikdo nepřečetl. emails.translate je tatáž cesta tam a zpět, zastavená o krok dřív. Ukažte překlad člověku, nechte ho jej upravit a pak odešlete to, co schválil, už zcela bez translate ve volání. Kdybyste je předali znovu, přeložilo by se to podruhé a jeho úpravy by se zahodily.
const preview = await openemail.emails.translate({ subject: 'Your September invoice', html: '<p>Invoice attached. Payment is due on the 14th.</p>', to: 'de',}) console.log(preview.language.native, preview.detectedSourceLanguage) const approved = await showToSomebody(preview) await openemail.emails.send({ from: '[email protected]', to: '[email protected]', subject: approved.subject, html: approved.html,})import { LANGUAGES, isRtlLanguage, languageByCode, openemail, resolveLanguage } from '@openemail/sdk' LANGUAGES.length // 200 const current = await openemail.languages.list() resolveLanguage('Deutsch')?.code // 'de'resolveLanguage('zh-TW')?.code // 'zh-Hant'languageByCode('DE')?.native // 'Deutsch'isRtlLanguage('ar') // trueTabulka je přibalená, v pořadí pro výběr, takže výběr lze naplnit ještě před prvním požadavkem. languages.list() se vyhodnotí na tytéž řádky stažené po drátě jako prosté pole – pro volajícího, který chce raději aktuální seznam než ten, se kterým byla dodána tato verze. resolveLanguage přijímá kód, anglický název, endonymum nebo alias (zh-TW je alias kódu, který se už neuvádí), languageByCode hledá přesnou shodu kódu bez ohledu na velikost písmen a šestnáct řádků je psáno zprava doleva. Hledejte v native, label i code najednou, zobrazujte nejprve native a ukládejte kód.
emails.translate se automaticky neopakuje. Spotřebovává volání modelu a nic nezapisuje, takže není co dělat idempotentním a opakování po nezodpovězeném požadavku by vám jen dvakrát koupilo tutéž odpověď.
- Jazyk, který se nevyhodnotí na nic, je
validation_errornatranslate.to, ještě než se cokoli odešle. translation_too_longnad 30 000 znaků,translation_not_configured, když instalace nemá nakonfigurovanou AI,translation_failed, když poskytovatel neodpověděl. Žádná z nich neodešle zprávu nepřeloženou jako náhradní řešení.- Funguje s
template: překládá se VYKRESLENÝ výstup, takže jedno uložené tělo poslouží všem jazykům, ve kterých vaši zákazníci čtou. Šablona, která vykresluje celý dokument, si zachová svůj doctype, bloky<style>i pravidla@font-face: modelu se předá pouze tělo a zbytek se kolem něj zase poskládá. Její<title>zůstane beze změny, stejně jej nic nezobrazuje. - Opakování nic navíc nestojí. Překlad není součástí idempotenčního otisku (požadavek ano, včetně
translate), takže opakování nezodpovězeného odeslání se stejnýmIdempotency-Keypřehraje zprávu, která už existuje, místo aby přeložilo a odeslalo druhou. - Přeložená zpráva ve frontě nebo naplánovaná je proti změnám formulací zmrazená.
emails.reschedules ní pořád pohne; změnit to, co říká, znamená zrušit ji a odeslat znovu.
Přílohy
content jde po drátě jako base64. Předejte bajty a zakódujeme je za vás.
attachments: [ { filename: 'invoice.pdf', content: pdfBytes, contentType: 'application/pdf' },]toBase64 je exportováno, kdybyste je potřebovali i jinde. Zpracovává data po blocích, což btoa(String.fromCharCode(...bytes)) nedělá. To selže na čemkoli nad zhruba 100 kB – a selže na skutečném souboru, ne na tom, se kterým jste to testovali.