Agendar e cancelar
`scheduledAt`, `emails->reschedule`, `emails->update` e `emails->cancel`.
Enviar mais tarde
$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']);Um DateTimeInterface, um instante ISO 8601 como string, ou uma duração como PT1H ou P2D. Até um ano à frente, nunca no passado. Espalhar uma mensagem que construiu antes num novo array com scheduledAt ao lado acrescenta o campo e deixa o original intacto.
Um DateTimeInterface é enviado como um instante em UTC, seja qual for o fuso em que foi criado, por isso 09:00 em Europe/London sai como o instante que indica. Uma string de data sem hora, como 2027-01-01, é lida como meia-noite UTC desse dia, por isso passe um instante quando a hora importa.
Mover e interromper
$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']);Só as mensagens queued e scheduled podem ser interrompidas. Qualquer uma mais avançada lança um ConflictException, porque parte dela já está na caixa de correio de alguém. Cancelar uma mensagem já cancelada é bem-sucedido e não altera nada.
Para encontrar o que está à espera de sair numa janela de tempo, liste com status: ['scheduled', 'queued'] e scheduledFrom: e scheduledTo:, como faz o calendário da aplicação.
Alterá-la antes de sair
emails->update altera uma mensagem que ainda não saiu: quando sai, com scheduledAt, o que diz, com subject, html e text, o endereço de onde sai, com from, e para quem vai, com to, cc e bcc. Envie os que quiser em conjunto, e um campo omitido mantém o seu valor. Uma lista de destinatários substitui por inteiro a que estava guardada. É o que faz editar uma mensagem agendada no calendário da aplicação.
$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 é verificado como num envio, por isso tem de ser um endereço a partir do qual a chave possa enviar. Uma mensagem traduzida quando foi aceite mantém o texto aprovado, por isso um novo subject, html ou text nela dá um 409 translation_locked, e uma que foi cifrada antes de ser agendada mantém o texto e os destinatários. Nesses casos, cancele e envie de novo.
Em alternativa, uma janela para anular
$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;Uma mensagem agendada já pode ser cancelada até sair, pelo que as duas opções não podem ser combinadas e o servidor recusa-o. Use esta para uma janela de anulação do envio numa mensagem imediata.
Parâmetros: agendamento
scheduledAtDateTimeInterface or string- Quando enviar, em `emails->send`: um `DateTimeInterface`, um instante ISO 8601 como string, ou uma duração como `PT1H` ou `P2D`. Um `DateTimeInterface` é enviado como instante UTC e uma string tal como está, e uma string de data sem hora significa meia-noite UTC. Pelo menos um segundo no futuro e no máximo 365 dias à frente, sendo a violação de qualquer um dos limites um `validation_error` em `scheduledAt`. Não é aceite linguagem natural, porque interpretar mal «próxima terça-feira» envia uma mensagem num momento que não pode ser desfeito.
cancellableForSecondsint- Uma janela de anulação do envio num envio IMEDIATO: um int de 0 a 900, com 0 por predefinição. Qualquer valor acima de 0 é recusado em conjunto com `scheduledAt`, que já pode ser cancelado até sair, e uma mensagem retida desta forma fica em `queued` e não em `scheduled`. É o mesmo mecanismo de diferimento com um atraso curto.
$idstringobrigatório- O id `msg_`, e o primeiro argumento de `emails->cancel`, `emails->reschedule` e `emails->update`. Exigem `emails:send` e não um âmbito próprio, e procuram o id dentro do espaço de trabalho da própria chave, pelo que um id que pertença a outro dá `not_found_error`, exatamente como um id que nunca existiu.
$scheduledAtDateTimeInterface or stringobrigatório- A nova hora, como segundo argumento de `emails->reschedule`, lida pelas mesmas regras e dentro da mesma janela de um ano. É a única coisa que `reschedule` altera, e o cliente não envia mais nada. Uma duração é relativa ao momento em que o SERVIDOR a lê, pelo que um reagendamento repetido fica ligeiramente mais tarde do que o primeiro teria ficado: mais tarde, nunca mais cedo.
apiKeystring- Um argumento nomeado em qualquer uma das três chamadas. Atua com esta chave em vez da do cliente.
Resposta
cancel, reschedule e update devolvem cada um a mensagem completa como um array com as chaves dos nomes em camelCase da API.
objectstring- Sempre `email`. Estas chamadas respondem com a mensagem completa e não com uma confirmação, pelo que não é preciso voltar a obter nada para ver o que mudou. `emails->send` devolve esta mesma forma mais `replayed`.
idstring- O identificador `msg_`. Estável durante toda a vida da mensagem e o id que todas as outras chamadas sobre ela recebem.
statusstring- `cancelled` após um cancelamento e `scheduled` após um reagendamento, incluindo numa mensagem que estava apenas `queued` atrás de uma janela para anular, que um reagendamento transforma num agendamento real. Só as mensagens `queued` e `scheduled` podem ser movidas ou interrompidas. Qualquer uma mais avançada lança um `ConflictException` cujo `errorCode` é `email_not_cancellable`, porque parte dela já está na caixa de correio de alguém.
scheduledAtstring or null- O instante ISO 8601 em que a mensagem deve ser despachada. Definido tanto para uma janela para anular como para um envio com `scheduledAt`, já que os dois são um único mecanismo, e null num envio imediato simples.
cancellableUntilstring or null- Quando o cancelamento deixa de funcionar, que é o mesmo instante que `scheduledAt` em ambos os percursos diferidos. É null num envio imediato, que já saiu quando a chamada retorna.
sentAtstring or null- Quando a mensagem saiu efetivamente. É null enquanto espera, e null para sempre numa mensagem cancelada.
messageIdstring or null- O Message-ID do RFC 5322, null até o MIME existir, pelo que é sempre null numa mensagem sobre a qual estas chamadas podem agir. Não serve para referenciar a mensagem na API, nem é aquilo com que uma devolução posterior regressa: o serviço de envio reescreve o cabeçalho à saída.
threadIdstring or null- A conversa a que esta mensagem pertence, retirada do pedido e reescrita com o que o transporte reportar depois de enviar. É null quando não é uma resposta.
transportstring or null- Como os bytes saíram, e null até ao despacho, por isso null em todas as mensagens que um cancelamento ou um reagendamento podem devolver. Um envio em modo de teste regista `test`, e pode aparecer um transporte que este pacote ainda não nomeia, por isso trate um valor desconhecido como informação e não como um erro.
attemptsint- Quantas vezes o despacho reservou esta linha. Aumenta com cada reserva e não com um envio bem-sucedido, e é 0 para tudo o que ainda está à espera.
lastErrorstring or null- A última falha registada na mensagem, null enquanto nada tiver falhado. Um envio diferido cuja tarefa não pôde ser colocada em fila é registado aqui como `Could not schedule: …` e passa a `failed`, que é a única forma de uma mensagem agendada deixar de poder ser cancelada sem que ninguém o peça.
fromstring- O endereço com que a mensagem foi autorizada a sair: o `from` que foi enviado, guardado simples e em minúsculas. Qualquer nome de apresentação é descartado aqui, porque o filtro `from:` de `emails->list` compara por igualdade.