Aller à la documentation
PHP

Planifier et annuler

`scheduledAt`, `emails->reschedule`, `emails->update` et `emails->cancel`.

Envoyer plus tard

schedule.php
$message = [    'from' => '[email protected]',    'to' => '[email protected]',    'subject' => 'Your September invoice',    'text' => 'Invoice attached.',]; $client->emails->send([...$message, 'scheduledAt' => 'PT1H']);$client->emails->send([...$message, 'scheduledAt' => new \DateTimeImmutable('2027-01-01 09:00', new \DateTimeZone('UTC'))]);$client->emails->send([...$message, 'scheduledAt' => '2027-01-01T09:00:00.000Z']);

Un DateTimeInterface, un instant ISO 8601 sous forme de chaîne, ou une durée comme PT1H ou P2D. Jusqu'à un an à l'avance, jamais dans le passé. Décompresser un message construit plus tôt dans un nouveau tableau, avec scheduledAt à côté, ajoute le champ et laisse l'original intact.

Un DateTimeInterface est envoyé comme un instant en UTC quel que soit le fuseau dans lequel il a été créé : 09:00 à Europe/London part donc comme l'instant qu'il désigne. Une chaîne de date sans heure, comme 2027-01-01, est lue comme minuit UTC ce jour-là : passez donc un instant quand l'heure compte.

Déplacer et arrêter

reschedule.php
$message = [    'from' => '[email protected]',    'to' => '[email protected]',    'subject' => 'Your September invoice',    'text' => 'Invoice attached.',]; $queued = $client->emails->send([...$message, 'scheduledAt' => 'PT1H']); $client->emails->reschedule($queued['id'], new \DateTimeImmutable('+1 day'));$client->emails->cancel($queued['id']);

Seuls les messages queued et scheduled peuvent être arrêtés. Tout ce qui est plus avancé lève une ConflictException, 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.

Pour trouver ce qui attend de partir dans une fenêtre de temps, listez avec status: ['scheduled', 'queued'] ainsi que scheduledFrom: et scheduledTo:, comme le fait le calendrier de l'application.

Le modifier avant son départ

emails->update modifie un message qui n'est pas encore parti : quand il part, avec scheduledAt, ce qu'il dit, avec subject, html et text, l'adresse depuis laquelle il part, avec from, et à qui il est envoyé, avec to, cc et bcc. Envoyez-en autant que vous voulez ensemble, et un champ omis garde sa valeur. Une liste de destinataires remplace entièrement celle qui est stockée. C'est ce que fait la modification d'un message planifié dans le calendrier de l'application.

update.php
$updated = $client->emails->update('msg_3f9a1c07d2b84e6a9c5b1f20', [    'subject' => 'Your September invoice, corrected',    'to' => ['[email protected]', '[email protected]'],    'scheduledAt' => new \DateTimeImmutable('2026-10-05 08:00', new \DateTimeZone('UTC')),]); echo $updated['status'], ' ', $updated['subject'], ' ', $updated['scheduledAt'], PHP_EOL;

from est vérifié comme lors d'un envoi : ce doit donc être une adresse depuis laquelle la clé peut envoyer. Un message traduit au moment de son acceptation garde sa formulation approuvée : un nouveau subject, html ou text sur lui donne donc un 409 translation_locked, et un message chiffré avant d'être planifié garde sa formulation et ses destinataires. Annulez-les et envoyez à nouveau à la place.

Une fenêtre d'annulation à la place

undo_window.php
$message = [    'from' => '[email protected]',    'to' => '[email protected]',    'subject' => 'Your September invoice',    'text' => 'Invoice attached.',]; $held = $client->emails->send([...$message, 'cancellableForSeconds' => 30]); echo $held['status'], ' ', $held['cancellableUntil'], PHP_EOL;

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

scheduledAtDateTimeInterface or string
Quand envoyer, sur `emails->send` : un `DateTimeInterface`, un instant ISO 8601 sous forme de chaîne, ou une durée comme `PT1H` ou `P2D`. Un `DateTimeInterface` est envoyé comme un instant UTC et une chaîne telle quelle, et une chaîne de date sans heure signifie minuit UTC. Au moins une seconde dans le futur et au plus 365 jours à l'avance, chacune des deux bornes donnant une `validation_error` sur `scheduledAt`, et le langage naturel n'est pas accepté, car interpréter « mardi prochain » de travers envoie un message à une heure sur laquelle on ne peut pas revenir.
cancellableForSecondsint
Une fenêtre d'annulation sur un envoi IMMÉDIAT : un int 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`, d'`emails->reschedule` et d'`emails->update`. Ils exigent `emails:send` plutôt qu'une portée qui leur serait propre, et cherchent l'id à l'intérieur de l'espace de travail de la clé : un id appartenant à un autre espace de travail donne donc une `not_found_error`, exactement comme un id qui n'a jamais existé.
$scheduledAtDateTimeInterface or stringobligatoire
La nouvelle heure, en deuxième argument d'`emails->reschedule`, lue selon les mêmes règles et dans la même fenêtre d'un an. C'est la seule chose que `reschedule` modifie, et le client n'envoie rien d'autre. 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.
apiKeystring
Un argument nommé sur chacun des trois appels. Agit avec cette clé au lieu de celle du client.

Réponse

cancel, reschedule et update renvoient chacun le message entier sous forme de tableau dont les clés sont les noms camelCase de l'API.

objectstring
Toujours `email`. Ces 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.
statusstring
`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é lève une `ConflictException` dont l'`errorCode` vaut `email_not_cancellable`, car une partie est déjà dans la boîte de quelqu'un.
scheduledAtstring or null
L'instant ISO 8601 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 or 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 or null
Quand le message est réellement parti. null tant qu'il attend, et null pour toujours sur un message annulé.
messageIdstring or null
Le Message-ID RFC 5322, null tant que le MIME n'existe pas, donc toujours null sur un message sur lequel ces 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 or 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.
transportstring or 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 un transport que ce package ne nomme pas encore peut apparaître : traitez donc une valeur inconnue comme une information plutôt que comme une erreur.
attemptsint
Combien de fois l'expédition a réclamé cette ligne. Le compteur augmente à chaque réclamation et non à chaque envoi réussi, et vaut 0 pour tout ce qui attend encore.
lastErrorstring or 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 : le `from` envoyé, stocké nu et en minuscules. Tout nom d'affichage est abandonné ici, car le filtre `from:` d'`emails->list` compare sur l'égalité.