E-mail küldése
`emails.send`: egy üzenet, most vagy később.
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 },})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.
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.
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') // trueA 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_erroratranslate.tomezőn, még mielőtt bármi elmenne. translation_too_long30 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
templatemező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-faceszabá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
translatemezővel együtt), így ha ugyanazzal azIdempotency-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.rescheduletová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.
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.