Ugrás a dokumentációra
SDK

E-mail küldése

`emails.send`: egy üzenet, most vagy később.

emails.send

send-email.ts
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 },})

A to, a cc és a bcc egy vagy több címzettet fogad, és az egyedülállót helyetted tömbbe csomagoljuk. Mindegyik lehet csupasz cím, Name <addr@host> vagy { email, name }.

Paraméterek

fromRecipientInputkötelező
A feladó. Csupasz cím, `Name <addr@host>` vagy objektum. Olyannak kell lennie, amellyel ez a kulcs küldhet. Nincs tartalék feladó, mert a tartalék a munkaterület alapértelmezett címe volna, amely változik, ahogy a címek jönnek-mennek.
toRecipientInput | RecipientInput[]kötelező
Egy vagy több címzett; az egyedülállót helyetted tömbbe csomagoljuk. A to, a cc és a bcc együtt legfeljebb 50 cím.
ccRecipientInput | RecipientInput[]
Beleszámít az 50 címzettes korlátba.
bccRecipientInput | RecipientInput[]
Soha nem nevezzük meg azokban a bájtokban, amelyeket bárki más megkap, mert címzettenként külön borítékot továbbítunk.
replyToRecipientInput
Egyetlen cím, amelyet Reply-To fejlécként küldünk.
subjectstring
Legfeljebb 998 karakter, az RFC 5322 sorhossz-korlátja. Alapértelmezés szerint üres.
htmlstring
A html, a text, a draftId vagy a template közül egy kötelező. Ha a html és a text is meg van adva, a címzettek a HTML-t látják.
textstring
Az egyszerű szöveges rész.
template{ id, version?, props?, slots? }
Tárolt sablon kiszolgálóoldali renderelése. A `version` rögzíti a revíziót; ha kihagyod, azt használjuk, ami a kérés elfogadásakor publikálva van. Az ismeretlen vagy hiányzó prop 422, nem pedig üres hely az üzenetben.
draftIdstring
Mentett piszkozat küldése ezzel a borítékkal.
headersRecord<string, string>
`X-*`, `List-*`, Reply-To, Precedence, Auto-Submitted, Importance, Priority és Feedback-Id. Bármit, amit a szállítás maga állít be, elutasítunk, nem pedig csendben eldobunk.
attachmentsAttachmentInput[]
`{ filename, content, contentType? }`, vagy `{ fileId }`, amely a munkaterületen már meglévő fájlt nevez meg. Add át a tartalmat bájtokként, és helyetted base64-re kódoljuk. 20 fájl, a beágyazottak dekódolva összesen legfeljebb 5 MB. A tárolt fájl lehet nagyobb, és letöltési linkként utazik.
attachmentDeliveryAttachmentDeliveryMode
`mime`, `link` vagy `auto`. Az `auto` letöltési linkként viszi a fájlokat, amint azok 2 MB fölé nőnek olyan domainen, amelynek aktív fájldomainje van, egyébként az üzenetben. Ha kihagyod, a postafiók beállítása érvényesül, amelynek alapértelmezése az `auto`.
threadIdstring
Válasz egy meglévő beszélgetésbe. A szállítás írja az In-Reply-To és a References fejlécet.
scheduledAtDate | string
Egy Date, egy ISO-8601 időpont, vagy egy időtartam, például `PT1H`. Legfeljebb egy évre előre, a múltba soha. Nem kombinálható a cancellableForSeconds értékkel.
cancellableForSecondsnumber
0 és 900 között. Visszavonási ablak azonnali küldésen: a szerkesztő visszavonási mechanizmusa, beégetés helyett közzétéve.
tagsRecord<string, string>
Legfeljebb 10 címke, visszatükrözve és szűrhetően. Soha nem értelmezzük.
signatureboolean
Hordozza-e ez az üzenet annak a címnek az aláírását, amelyről megy – vagyis az adott cím saját aláírását, vagy ennek híján az Összes címre beállítottat. Alapértelmezése true, mert az aláírás a címhez tartozik, nem ahhoz a klienshez, amely az üzenetet küldte. Állítsd `false` értékre annál a levélnél, amelyet program küld valaki nevében, például nyugtánál, jelszó-visszaállításnál vagy összefoglalónál – ezek egyike alá sem kívánkozik emberi kézjegy.
tracking{ opens?, clicks? }
Tegyünk-e megnyitási pixelt és írjuk-e át a linkeket ebben az üzenetben. Bekapcsolva, hacsak a munkaterület tulajdonosa ki nem kapcsolta a követést annál a címnél, amelyről az üzenet megy, vagy az Összes címnél; az itt megadott bármelyik mező erre az egy üzenetre eldönti a kérdést, függetlenül attól, hogyan áll a cím.
translate{ to, from?, subject?, includeOriginal? }
Küldd a címzett nyelvén. A `to` kódot, angol nevet vagy a nyelv saját nevét fogadja; a `subject` és az `includeOriginal` alapértelmezése egyaránt true. A kérés elfogadásakor oldódik fel, így az ütemezett üzenet a jóváhagyott szavakat hordozza. A `draftId` mellett elutasítjuk.

Válasz

idstring
A küldés azonosítója, `msg_…`. Ezt használd a `get`, a `cancel`, a `reschedule` és a `getTracking` hívásnál.
statusEmailStatus
queued, scheduled, sending, sent, partial, cancelled vagy failed. Ezt olvasd, ne azt, hogy a promise teljesült. A `partial` önálló állapot: egyes címzetteknél már ott van, és nem lehet visszaszívni, így az újraküldés hibás, a hiba jelentése pedig hazugság.
mode'live' | 'test'
Milyen típusú kulcs küldte. A tesztküldést rögzítjük, és soha nem továbbítjuk.
fromstring
A ténylegesen engedélyezett és a hálózatra tett cím, amely nem mindig az, amelyet kértek.
subjectstring | null
Ahogy elküldtük.
messageIdstring | null
Az RFC 5322 Message-ID. Null, amíg a MIME nem létezik. A küldő szolgáltatás kimenet közben átírja a fejlécet, így egyetlen visszapattanás vagy kézbesítési jelentés sem hordozza ezt az értéket. Az eseményeken az `id` jön vissza.
threadIdstring | null
A beszélgetés, amelybe bekerült.
transportstring | null
Hogyan ment ki az üzenet. A kiküldésig null.
attemptsnumber
Hányszor próbálkoztunk a kiküldéssel.
lastErrorstring | null
Miért bukott el az utolsó kísérlet, szó szerint.
scheduledAtstring | null
Az ISO-időpont, amikor indulnia kell.
cancellableUntilstring | null
Amíg a mostani idő ez előtt van, a visszavonás még működik.
sentAtstring | null
Az ISO-időpont, amikor elment.
tagsRecord<string, string>
Amit küldtél, visszatükrözve.
sourceEmailSource
composer, api, mcp, ai vagy queue: melyik felület kérte. Az `api` ez a kliens.
createdAtstring
Az ISO-időpont, amikor a rekord íródott.
replayedboolean
Igaz, ha egy Idempotency-Key egy már létező küldéssel egyezett. Semmi új nem ment el, és ez az eredeti üzenet.
translationEmailTranslationResource | undefined
Csak lefordított üzeneten van jelen, és csak ott, ahol a teljes tárolt kérést hordozzuk: ezen a válaszon és a `get` hívásnál. `{ language, languageName, detectedSourceLanguage, subject, includeOriginal }`, mindegyik kód, nem nyelvsor. A listasorokon soha nincs ott, így az ottani hiánya semmit nem mond egyik irányba sem.

A címzett nyelvén

A translate még kimenet előtt átírja az üzenetet valaki más nyelvére. A törzset – és a tárgyat is, hacsak azt ki nem kapcsolod – akkor fordítjuk le, amikor az API elfogadja a kérést, és ami kijött, az megy ki: ha a fordítást nem sikerült előállítani, elutasítjuk a küldést, nem pedig azon a nyelven adjuk fel, amelyen írtad.

translate.ts
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 }

Azt senki nem olvasta el, mielőtt elment. Az emails.translate ugyanaz a körfordulat, egy lépéssel korábban megállítva. Mutasd meg egy embernek, engedd, hogy módosítson rajta, majd küldd el, amit jóváhagyott – translate nélkül a híváson. Ha újra megadnád, másodszor is lefordítaná, és eldobná a szerkesztéseit.

preview-translation.ts
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,})
render-picker.ts
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') // true

A táblázat a csomag része, választósorrendben, így egy választó már az első kérés előtt feltölthető. A languages.list() ugyanezekkel a sorokkal tér vissza a hálózatról, sima tömbként, annak, aki inkább az aktuálisakat szeretné, mint azokat, amelyekkel ez a verzió megjelent. A resolveLanguage kódot, angol nevet, endonimát vagy aliast fogad (a zh-TW egy már nem listázott kód aliasa), a languageByCode kis- és nagybetűtől függetlenül pontos kódra illeszt, és a sorok közül tizenhat jobbról balra író. A native, a label és a code mezőben együtt keress, a native értéket mutasd elöl, és a kódot tárold.

Az emails.translate hívást nem próbáljuk újra automatikusan. Modellhívásokat fogyaszt, és semmit nem ír, így nincs mit idempotenssé tenni, és egy megválaszolatlan kérés utáni újrapróbálkozás csak kétszer venné meg ugyanazt a választ.

  • Az a nyelv, amely semmire nem oldódik fel, validation_error a translate.to mezőn, még mielőtt bármi elmenne.
  • translation_too_long 30 000 karakter felett, translation_not_configured, ha a telepítésen nincs AI beállítva, translation_failed, ha a szolgáltató nem válaszolt. Egyik sem küldi el tartalékként az üzenetet lefordítatlanul.
  • Működik a template mezővel: a RENDERELT kimenetet fordítjuk le, így egy tárolt törzs minden nyelvet kiszolgál, amelyen az ügyfeleid olvasnak. A teljes dokumentumot rendelő sablon megtartja a doctype-ját, a <style> blokkjait és az @font-face szabályait: csak a törzs megy a modellhez, a többit köré tesszük vissza. A <title> elemet érintetlenül hagyjuk, amit amúgy sem jelenít meg semmi.
  • Az újrapróbálkozás nem kerül semmi többe. A fordítás nem része az idempotencia-ujjlenyomatnak (a kérés igen, a translate mezővel együtt), így ha ugyanazzal az Idempotency-Key értékkel próbálsz újra egy megválaszolatlan küldést, a már létező üzenetet játsszuk vissza, nem pedig másodszor is fordítunk és küldünk.
  • A lefordított, sorban álló vagy ütemezett üzenet szövege be van fagyasztva. Az emails.reschedule továbbra is mozgatja; ha azon akarsz változtatni, amit mond, vond vissza, és küldd el újra.

Mellékletek

A content a hálózaton base64. Add át a bájtokat, és helyetted kódoljuk.

attachment.ts
attachments: [  { filename: 'invoice.pdf', content: pdfBytes, contentType: 'application/pdf' },]

A toBase64 exportálva van, ha máshol is szükséged van rá. Darabokban dolgozik, amit a btoa(String.fromCharCode(...bytes)) nem. Az körülbelül 100 kB fölött elszáll, méghozzá a valódi fájlon, nem azon, amellyel teszteltél.