Zur Dokumentation springen
Ruby

Eine E-Mail senden

`emails.send`: eine Nachricht, jetzt oder später.

emails.send

send_email.rb
email = client.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: Pathname("invoice.pdf")}],  threadId: "CAHk7pQ2x9LmZ4-mail.example.com",  scheduledAt: "PT1H",  tags: {order: "4021"},  tracking: {opens: true, clicks: true}) puts email[:id], email[:status]

to, cc und bcc nehmen einen Empfänger oder ein Array von Empfängern entgegen, und ein einzelner wird für Sie verpackt. Jeder darf eine bloße Adresse, Name <addr@host> oder ein Hash mit email und name sein.

Die Nachricht wird als Keyword-Argumente oder als einzelner Hash übergeben. Keyword-Argumente neben einem Hash werden in ihn eingemischt und haben Vorrang, wo beide ein Feld nennen. client.emails.send(message, subject: "Re: your invoice") ändert also ein Feld einer Nachricht, die Sie zuvor gebaut haben. Die Schlüssel behalten die Namen der API, deshalb bleiben replyTo und scheduledAt in camelCase, während idempotency_key: und api_key: Optionen des Aufrufs und nie Teil der Nachricht sind.

Parameter

fromString or Hasherforderlich
Der Absender. Eine bloße Adresse, `Name <addr@host>` oder ein Hash mit `email` und `name`. Muss eine Adresse sein, als die dieser Schlüssel senden darf, sonst löst der Aufruf einen 403 `from_address_forbidden` aus. Es gibt keinen Ersatzabsender, ein Versand nennt also immer die Adresse, von der er ausgeht.
toString, Hash or Arrayerforderlich
Ein Empfänger oder ein Array von Empfängern, und ein einzelner wird für Sie verpackt. Höchstens 50 über `to`, `cc` und `bcc` zusammen, mehr ergibt einen 422 `too_many_recipients`.
ccString, Hash or Array
Zählt gegen das Limit von 50 Empfängern.
bccString, Hash or Array
Wird in den Bytes, die andere erhalten, nie genannt, denn pro Empfänger wird ein eigener Umschlag übertragen. Zählt ebenfalls zu den 50.
replyToString or Hash
Eine einzelne Adresse, wird als Reply-To-Header gesendet.
subjectString
Höchstens 998 Zeichen, das Zeilenlimit von RFC 5322. Standardmäßig leer, und ein leerer Betreff fällt auf den des Templates oder des Entwurfs zurück.
htmlString
Eines von `html`, `text`, `draftId` oder `template` ist erforderlich. HTML ist das, was Empfänger sehen, wenn sowohl `html` als auch `text` angegeben sind. Höchstens 1.000.000 Zeichen.
textString
Der Nur-Text-Teil, höchstens 1.000.000 Zeichen.
templateHash
Rendert ein gespeichertes Template serverseitig: ein Hash mit `id`, das eine id oder einen Slug nimmt, und optional `version` (ein Integer), `props` und `slots`. `version` schreibt eine Revision fest. Lassen Sie es weg, um das zu verwenden, was bei Annahme der Anfrage veröffentlicht ist. Ein unbekanntes oder fehlendes Prop ergibt einen 422 und keine Lücke in der Nachricht.
draftIdString
Sendet einen gespeicherten Entwurf unter diesem Umschlag, so wie er geschrieben wurde. Kann nicht mit `template` oder `translate` kombiniert werden.
headersHash
Header-Name auf String-Wert, beschränkt auf `X-*`, `List-*`, Reply-To, Precedence, Auto-Submitted, Importance, Priority und Feedback-ID. Alles, was der Transport selbst setzt, wird mit einem 422 `reserved_header` abgelehnt statt stillschweigend verworfen.
attachmentsArray<Hash>
Jeweils ein Hash mit `filename`, `content` und optional `contentType` oder ein Hash nur mit `fileId`, das eine bereits im Workspace liegende Datei benennt, etwa eine aus `files.upload`. Übergeben Sie Bytes als `content`, dann werden sie für Sie base64-kodiert. 20 Dateien, wobei eingebettete Dateien nach dem Dekodieren zusammen auf 5 MB begrenzt sind. Eine gespeicherte Datei darf größer sein und reist als Download-Link.
attachmentDeliveryString
`mime`, `link` oder `auto`. `auto` überträgt Dateien als Download-Links, sobald sie 2 MB überschreiten und die Domain eine aktive Dateien-Domain hat, und andernfalls innerhalb der Nachricht. Weggelassen gilt die Postfacheinstellung, die standardmäßig `auto` ist.
threadIdString
Antwort in einen bestehenden Thread. Der Transport schreibt In-Reply-To und References.
scheduledAtTime, DateTime or String
Ein Time oder DateTime, gesendet als UTC-Zeitpunkt nach ISO 8601, ein Zeitpunkt nach ISO 8601 als String oder eine Dauer wie `PT1H`. Bis zu einem Jahr im Voraus, nie in der Vergangenheit. Kann nicht mit `cancellableForSeconds` kombiniert werden. Ein Ruby-Date wird als bloßes Datum gesendet, das die API als Mitternacht UTC an diesem Tag liest. Übergeben Sie also ein Time, wenn die Uhrzeit wichtig ist.
cancellableForSecondsInteger
0 bis 900. Ein Rückgängig-Fenster bei einem sofortigen Versand: der Rückgängig-Mechanismus des Composers, offengelegt statt fest verdrahtet.
tagsHash
Bis zu 10 Labels, mit Schlüsseln aus 1 bis 64 Buchstaben, Ziffern, `_` oder `-` und String-Werten bis 256 Zeichen. Werden bei jedem Lesen zurückgegeben und nie interpretiert.
signatureBoolean
Ob diese Nachricht die Signatur der Absenderadresse trägt: die eigene dieser Adresse, sonst bei einer von einem Catch-all aufgefangenen Adresse die des Catch-all, sonst die OpenEmail-Fußzeile, sofern diese Adresse sie nicht ausgeschaltet hat. Ohne Angabe geht ein `html`-Text genau so hinaus, wie er geschrieben ist, ohne Signatur, und ein reiner `text`-Text trägt sie. Setzen Sie `false` für Mail, die ein Programm im Namen einer Person sendet, etwa eine Quittung, ein Passwort-Reset oder eine Zusammenfassung, unter denen niemand die Unterschrift einer Person erwartet. Template-Versände und verschlüsselte Versände tragen nie eine.
trackingHash
Ein Hash mit den optionalen Booleans `opens` und `clicks`: ob für diese Nachricht ein Öffnungs-Pixel hinzugefügt und Links umgeschrieben werden. Inaktiv, sofern das Tracking nicht für die Absenderadresse (oder den Catch-all, der sie aufgefangen hat) eingeschaltet wurde, und jeder hier angegebene Schlüssel entscheidet diese eine Nachricht, unabhängig davon, wie die Adresse eingestellt ist.
translateHash
Sendet sie in der Sprache des Empfängers: ein Hash mit `to` und optional `from`, `subject` und `includeOriginal`. `to` nimmt einen Code, einen englischen Namen oder den Eigennamen der Sprache entgegen, und `subject` und `includeOriginal` sind beide standardmäßig true. Wird bei Annahme der Anfrage festgelegt, eine geplante Nachricht trägt daher genau die freigegebenen Worte. Wird zusammen mit `draftId` abgelehnt.
idempotency_keyString
Ihr eigener Key für diesen Versand, 1 bis 255 Zeichen aus Buchstaben, Ziffern, `_`, `.`, `:` oder `-`. Ohne ihn erzeugt der Client für jeden Aufruf einen Key, sodass seine eigenen Wiederholungen nie zweimal senden, und mit ihm wird ein Versand, der in einem anderen Prozess erneut läuft, erneut abgespielt statt wiederholt.
api_keyString
Sendet mit diesem Schlüssel statt mit dem des Clients, für einen Prozess, der im Namen mehrerer Workspaces sendet.

Antwort

Ein Hash mit Symbol-Schlüsseln, email[:status] liest also den Status.

idString
Die Versand-id, `msg_` gefolgt von 24 Hex-Zeichen. Verwenden Sie sie für `get`, `cancel`, `reschedule` und `get_tracking`.
statusString
queued, scheduled, sending, sent, partial, bounced, cancelled oder failed. Lesen Sie dies und nicht die Tatsache, dass der Aufruf zurückgekehrt ist: Ein sofortiger Versand wird innerhalb der Anfrage ausgeliefert und kommt meist als `sent`, `partial` oder `failed` zurück, ein zurückgehaltener als `queued` oder `scheduled`. `partial` ist ein eigener Zustand: Einige Empfänger haben die Nachricht, und das lässt sich nicht rückgängig machen. Ein erneuter Versuch ist daher falsch, und einen Fehlschlag zu melden ist eine Lüge.
modeString
`live` oder `test`: welche Art von Schlüssel sie gesendet hat. Ein Testversand wird aufgezeichnet und nie übertragen. Er zeigt `sent`, mit `transport` gleich `test`. Prüfen Sie also die Antwort und nicht einen Posteingang.
fromString
Die tatsächlich autorisierte und auf die Leitung gegebene Adresse, die nicht immer die angeforderte ist.
subjectString or nil
Wie gesendet.
messageIdString or nil
Die Message-ID nach RFC 5322. nil, bis das MIME existiert. Der Versanddienst schreibt den Header auf dem Weg hinaus um, kein Bounce und kein Zustellbericht trägt daher diesen Wert. `id` ist das, worüber ein Ereignis zurückkommt.
threadIdString or nil
Der Thread, in dem sie gelandet ist.
transportString or nil
Wie die Nachricht hinausging. nil bis zum Versand.
attemptsInteger
Wie oft der Versand versucht wurde.
lastErrorString or nil
Warum der letzte Versuch fehlschlug, wörtlich.
scheduledAtString or nil
Der Zeitpunkt nach ISO 8601, zu dem sie hinausgehen soll.
cancellableUntilString or nil
Solange die aktuelle Zeit davor liegt, funktioniert `cancel` noch.
sentAtString or nil
Der Zeitpunkt nach ISO 8601, zu dem sie hinausging.
tagsHash
Was Sie gesendet haben, zurückgegeben.
sourceString
composer, api, mcp, ai oder queue: welche Oberfläche angefragt hat. `api` ist dieser Client.
createdAtString
Der Zeitpunkt nach ISO 8601, zu dem der Datensatz geschrieben wurde.
replayedBoolean
True, wenn ein Idempotency-Key auf einen bereits existierenden Versand passte. Es wurde nichts Neues gesendet, und dies ist die ursprüngliche Nachricht in ihrem aktuellen Zustand.
translationHash
Nur bei einer übersetzten Nachricht vorhanden, und nur dort, wo die gesamte gespeicherte Anfrage mitgeführt wird: in dieser Antwort und bei `get`. Es enthält `language`, `languageName`, `detectedSourceLanguage`, `subject` und `includeOriginal`, mit Codes statt ganzer Sprachzeilen. Eine Listenzeile hat es nie, sein Fehlen dort sagt daher in keine Richtung etwas aus.

In der Sprache des Empfängers

translate verfasst die Nachricht vor dem Versand in der Sprache eines anderen. Der Body und, sofern Sie das nicht abschalten, der Betreff werden übersetzt, sobald die API die Anfrage annimmt, und was dabei herauskam, geht hinaus: Eine Übersetzung, die nicht erzeugt werden konnte, lässt den Versand scheitern, statt die Nachricht in der Sprache zu verschicken, in der Sie sie geschrieben haben.

translate.rb
email = client.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"}) p email[:translation]

email[:translation] lautet dann {language: "de", languageName: "German", detectedSourceLanguage: "en", subject: true, includeOriginal: true}.

Niemand hat das gelesen, bevor es hinausging. emails.translate ist derselbe Weg, einen Schritt früher angehalten. Zeigen Sie das Ergebnis einer Person, lassen Sie sie es ändern und senden Sie dann das Freigegebene ganz ohne translate am Aufruf. Es erneut zu übergeben würde ein zweites Mal übersetzen und ihre Änderungen verwerfen.

preview_translation.rb
preview = client.emails.translate(  subject: "Your September invoice",  html: "<p>Invoice attached. Payment is due on the 14th.</p>",  to: "de") puts preview.dig(:language, :native), preview[:subject], preview[:html]print "Send it as it is? [y/N] " if $stdin.gets.to_s.strip.casecmp?("y")  client.emails.send(    from: "[email protected]",    to: "[email protected]",    subject: preview[:subject],    html: preview[:html]  )end
languages.rb
p OpenEmail::LANGUAGES.size current = client.languages.listp current.size p OpenEmail.resolve_language("Deutsch")&.fetch(:code)p OpenEmail.resolve_language("zh-TW")&.fetch(:code)p OpenEmail.language_by_code("DE")&.fetch(:native)p OpenEmail.rtl_language?("ar")

Diese Zeilen geben 200 aus, die Zeilen, mit denen diese Version ausgeliefert wird, dann die Anzahl, die die API jetzt hält, dann "de", "zh-Hant", "Deutsch" und true. Die Tabelle ist in der Reihenfolge des Auswahlfelds als OpenEmail::LANGUAGES mitgeliefert, ein eingefrorenes Array von Hashes mit code, label, native, flag und rtl, ein Auswahlfeld lässt sich daher schon vor der ersten Anfrage füllen. languages.list gibt dieselben Zeilen von der Leitung als einfaches Array zurück, für Aufrufer, denen die aktuellen lieber sind als die, mit denen diese Version ausgeliefert wurde. OpenEmail.resolve_language nimmt einen Code, einen englischen Namen, ein Endonym oder einen Alias entgegen (zh-TW ist ein Alias eines nicht mehr gelisteten Codes) und gibt nil zurück, wenn nichts passt, OpenEmail.language_by_code trifft einen exakten Code ohne Beachtung der Groß- und Kleinschreibung, und sechzehn der Zeilen laufen von rechts nach links. Durchsuchen Sie native, label und code gemeinsam, zeigen Sie native zuerst und speichern Sie den Code.

emails.translate wird nicht automatisch wiederholt. Es verbraucht Modellaufrufe und schreibt nichts, es gibt also nichts idempotent zu machen, und eine Wiederholung nach einer unbeantworteten Anfrage würde dieselbe Antwort nur zweimal bezahlen.

  • Eine Sprache, die die API nicht zuordnen kann, ergibt einen validation_error auf translate.to, bevor irgendetwas gesendet wird.
  • translation_too_long bei über 30.000 Zeichen, translation_not_configured, wenn für die Installation keine KI konfiguriert ist, ein 429 ai_quota_exceeded, wenn der Workspace die KI-Aktionen für heute verbraucht hat (es wird um Mitternacht UTC zurückgesetzt und nicht erneut versucht), translation_failed, wenn der Anbieter nicht geantwortet hat. Keiner dieser Fälle sendet die Nachricht ersatzweise unübersetzt.
  • Funktioniert mit template: Übersetzt wird die GERENDERTE Ausgabe, ein gespeicherter Body bedient daher jede Sprache, in der Ihre Kunden lesen. Ein Template, das ein ganzes Dokument rendert, behält seinen doctype, seine <style>-Blöcke und seine @font-face-Regeln: Nur der Body geht an das Modell, der Rest wird wieder darum gelegt. Sein <title> bleibt unangetastet, was ohnehin nirgends angezeigt wird.
  • Eine Wiederholung kostet nichts zusätzlich. Die Übersetzung ist nicht Teil des Idempotenz-Fingerabdrucks (die Anfrage schon, translate eingeschlossen), eine Wiederholung eines unbeantworteten Versands mit demselben Idempotency-Key spielt daher die bereits existierende Nachricht erneut ab, statt ein zweites Mal zu übersetzen und zu senden.
  • Eine übersetzte Nachricht, die queued oder scheduled ist, behält ihren freigegebenen Wortlaut. emails.reschedule verschiebt sie weiterhin, während emails.update einen neuen Wortlaut mit einem 409 translation_locked ablehnt. Ihren Inhalt zu ändern bedeutet also, abzubrechen und erneut zu senden.

Anhänge

content ist auf der Leitung base64. Übergeben Sie die Bytes, dann werden sie für Sie kodiert: einen binären String, wie ihn File.binread zurückgibt, ein IO wie eine geöffnete File oder einen Pathname, der für Sie gelesen wird.

attachments.rb
attachments = [  {filename: "invoice.pdf", content: File.binread("invoice.pdf"), contentType: "application/pdf"},  {filename: "report.pdf", content: Pathname("report.pdf")},  {fileId: "file_6bb640f5b99e47deb758f1f5"}] client.emails.send(  from: "[email protected]",  to: "[email protected]",  subject: "Your documents",  text: "Both are attached.",  attachments:)

Ein als Text markierter String, wie ihn File.read zurückgibt, gilt als bereits base64-kodiert, und einer, der kein base64 ist, löst einen ArgumentError aus, bevor etwas gesendet wird. Lesen Sie Dateien mit File.binread oder rufen Sie .b auf Bytes auf, die als Text markiert ankamen.

OpenEmail.to_base64 steht bereit, wenn Sie dieselbe Kodierung anderswo brauchen. Es nimmt einen binären String, ein IO oder einen Pathname und gibt striktes base64 ohne Zeilenumbrüche zurück.