Aller à la documentation
SDK

Planifier et annuler

`scheduledAt`, `emails.reschedule` et `emails.cancel`.

Envoyer plus tard

schedule.ts
await openemail.emails.send({ ...message, scheduledAt: 'PT1H' })await openemail.emails.send({ ...message, scheduledAt: new Date('2027-01-01T09:00:00Z') })await openemail.emails.send({ ...message, scheduledAt: '2027-01-01T09:00:00.000Z' })

Un Date, un instant ISO-8601, ou une durée comme PT1H / P2D. Jusqu'à un an à l'avance, jamais dans le passé.

Déplacer et arrêter

reschedule.ts
const queued = await openemail.emails.send({ ...message, scheduledAt: 'PT1H' }) await openemail.emails.reschedule(queued.id, new Date(Date.now() + 86_400_000))await openemail.emails.cancel(queued.id)

Seuls les messages queued et scheduled peuvent être arrêtés ; tout ce qui est plus avancé donne un conflict_error, car une partie est déjà dans la boîte de quelqu'un. Annuler un message déjà annulé réussit et ne change rien.

Une fenêtre d'annulation à la place

undo-window.ts
await openemail.emails.send({ ...message, cancellableForSeconds: 30 })

Un message planifié est déjà annulable jusqu'à son départ : les deux ne peuvent donc pas être combinés, et le serveur le refuse. Utilisez celui-ci pour une fenêtre d'annulation sur un message immédiat.

Paramètres : planification

scheduledAtDate | string
Quand envoyer, sur `emails.send` : un `Date`, un instant ISO-8601, ou une durée comme `PT1H` ou `P2D`, que le client convertit en string pour le réseau. Au moins une seconde dans le futur et au plus 365 jours à l'avance, chacune des deux bornes donnant un `validation_error` sur `scheduledAt` ; le langage naturel n'est pas accepté, car interpréter « mardi prochain » de travers envoie un message à une heure sur laquelle on ne peut plus revenir.
cancellableForSecondsnumber
Une fenêtre d'annulation sur un envoi IMMÉDIAT : un integer de 0 à 900, 0 par défaut. Toute valeur supérieure à 0 est refusée en présence de `scheduledAt`, qui est déjà annulable jusqu'à son départ, et un message retenu ainsi reste à `queued` plutôt qu'à `scheduled`. C'est le même mécanisme de report, avec un court délai.
idstringobligatoire
L'id `msg_…`, et le premier argument d'`emails.cancel` comme d'`emails.reschedule`. Les deux exigent `emails:send` plutôt qu'une portée qui leur serait propre, et les deux résolvent à l'intérieur du workspace de la clé : un id appartenant à un autre workspace donne donc un `not_found_error`, exactement comme un id qui n'a jamais existé.
reschedule.scheduledAtDate | stringobligatoire
La nouvelle heure, en deuxième argument d'`emails.reschedule`, analysée selon les mêmes règles et dans la même fenêtre d'un an, et la seule chose que le `PATCH /emails/{id}` sous-jacent modifiera. Une durée est relative au moment où le SERVEUR la lit : une replanification réessayée tombe donc un peu plus tard que la première ne l'aurait fait — plus tard, jamais plus tôt.

Réponse : EmailResource

object'email'
Toujours `email`. Les deux appels répondent avec le message entier plutôt qu'avec un accusé de réception : rien n'a donc besoin d'être récupéré à nouveau pour voir ce qui a changé ; `emails.send` renvoie cette même forme, plus `replayed`.
idstring
Le handle `msg_…`. Stable pendant toute la vie du message, et c'est l'id que prend tout autre appel le concernant.
statusEmailStatus
`cancelled` après une annulation et `scheduled` après une replanification, y compris pour un message qui n'était que `queued` derrière une fenêtre d'annulation, qu'une replanification transforme en véritable planification. Seuls les messages `queued` et `scheduled` peuvent être déplacés ou arrêtés ; tout ce qui est plus avancé donne un `conflict_error` avec le code `email_not_cancellable`, car une partie est déjà dans la boîte de quelqu'un.
scheduledAtstring | null
L'instant ISO auquel le message doit être expédié. Renseigné aussi bien pour une fenêtre d'annulation que pour un envoi avec `scheduledAt`, puisque les deux ne font qu'un seul mécanisme, et null sur un simple envoi immédiat.
cancellableUntilstring | null
Le moment où l'annulation cesse de fonctionner, soit le même instant que `scheduledAt` sur les deux chemins différés. Null sur un envoi immédiat, déjà parti au moment où l'appel revient.
sentAtstring | null
Quand le message est réellement parti. Null tant qu'il attend, et null pour toujours sur un message annulé.
messageIdstring | null
Le Message-ID RFC 5322, null tant que le MIME n'existe pas, donc toujours null sur un message sur lequel ces deux appels peuvent agir. Ce n'est pas avec lui qu'on s'adresse à l'API, ni sur lui qu'un bounce ultérieur revient : le service d'envoi réécrit l'en-tête au départ.
threadIdstring | null
Le thread auquel ce message appartient, repris de la requête et réécrit avec ce que rapporte le transport une fois l'envoi fait. Null quand ce n'est pas une réponse.
transportEmailTransport | (string & {}) | null
Par où les octets sont partis, et null jusqu'à l'expédition, donc null sur tout message qu'une annulation ou une replanification peut renvoyer. Un envoi en mode test enregistre `test`, et l'union reste ouverte pour qu'un transport que ce SDK ne nomme pas encore ne soit pas un changement cassant.
attemptsnumber
Combien de fois l'expédition a réclamé cette ligne. Incrémenté par la réclamation et non par un envoi réussi, et vaut 0 pour tout ce qui attend encore.
lastErrorstring | null
Le dernier échec enregistré sur le message, null tant que rien n'a échoué. Un envoi différé dont le job n'a pas pu être mis en file est écrit ici sous la forme `Could not schedule: …` et passe à `failed`, seule manière pour un message planifié de cesser d'être annulable sans que personne ne l'ait demandé.
fromstring
L'adresse sous laquelle le message a été autorisé à partir, stockée nue et en minuscules. Pas toujours l'adresse demandée (une clé restreinte qui ne nomme aucun `from` se résout à la première adresse qu'elle peut utiliser), et tout nom d'affichage est abandonné ici, car le filtre `from` d'`emails.list` compare sur l'égalité.