문서로 건너뛰기
PHP

예약과 취소

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

나중에 보내기

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']);

DateTimeInterface, 문자열로 된 ISO 8601 시각, 또는 PT1H나 P2D 같은 기간입니다. 최대 1년 뒤까지이며 과거는 안 됩니다. 앞서 만든 메시지를 scheduledAt과 함께 새 배열에 펼쳐 넣으면 필드가 추가되고 원본은 그대로 남습니다.

DateTimeInterface는 어느 시간대에서 만들었든 UTC 시각으로 전송되므로, Europe/London의 09:00은 그것이 가리키는 시각 그대로 나갑니다. 2027-01-01처럼 시각이 없는 날짜 문자열은 그날의 UTC 자정으로 읽히므로, 시각이 중요할 때는 시각까지 있는 값을 전달하세요.

옮기기와 중단하기

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']);

중단할 수 있는 것은 queued와 scheduled 메시지뿐이며, 그 이후 단계는 ConflictException을 던집니다. 일부가 이미 누군가의 메일함에 들어가 있기 때문입니다. 이미 취소된 메시지를 취소하면 성공하고 아무것도 바뀌지 않습니다.

어떤 기간에 발송을 기다리는 것을 찾으려면, 앱의 캘린더처럼 status: ['scheduled', 'queued']와 scheduledFrom:, scheduledTo:를 지정해 목록을 가져오세요.

나가기 전에 변경하기

emails->update는 아직 나가지 않은 메시지를 변경합니다: 언제 나갈지는 scheduledAt으로, 무슨 내용인지는 subject, html, text로, 어떤 주소로 나갈지는 from으로, 누구에게 갈지는 to, cc, bcc로 지정합니다. 어느 것이든 함께 보낼 수 있으며, 생략한 필드는 값을 유지합니다. 수신자 목록은 저장된 목록을 통째로 대체합니다. 앱의 캘린더에서 예약된 메시지를 편집할 때 일어나는 일이 바로 이것입니다.

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은 발송할 때와 같이 검사되므로, 키가 발신자로 쓸 수 있는 주소여야 합니다. 수락될 때 번역된 메시지는 승인된 문구를 유지하므로, 여기에 새 subject, html, text를 주면 409 translation_locked입니다. 예약 전에 암호화된 메시지는 문구와 수신자를 유지합니다. 이런 메시지는 대신 취소하고 다시 보내세요.

대신 실행 취소 시간 두기

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;

예약된 메시지는 나가기 전까지 이미 취소할 수 있으므로 둘을 함께 쓸 수 없고, 서버가 이를 거부합니다. 즉시 발송에 실행 취소 시간을 두려면 이쪽을 쓰세요.

매개변수: 예약

scheduledAtDateTimeInterface or string
`emails->send`에서의 발송 시각입니다: `DateTimeInterface`, 문자열로 된 ISO 8601 시각, 또는 `PT1H`나 `P2D` 같은 기간입니다. `DateTimeInterface`는 UTC 시각으로, 문자열은 그대로 전송되며, 시각이 없는 날짜 문자열은 UTC 자정을 뜻합니다. 최소 1초 뒤, 최대 365일 뒤까지 가능하고 어느 경계를 넘든 `scheduledAt`에 대한 `validation_error`입니다. 자연어는 받지 않는데, “다음 화요일”을 잘못 해석하면 되돌릴 수 없는 시각에 메시지가 나가기 때문입니다.
cancellableForSecondsint
즉시 발송에 대한 실행 취소 시간입니다: 0에서 900까지의 int이며 기본값은 0입니다. 0보다 큰 값은 `scheduledAt`과 함께 쓰면 거부되는데, 그쪽은 나가기 전까지 이미 취소할 수 있기 때문입니다. 이렇게 붙잡힌 메시지는 `scheduled`가 아니라 `queued`에 머뭅니다. 짧은 지연이 붙은 같은 연기 메커니즘입니다.
$idstring필수
`msg_` id이며, `emails->cancel`, `emails->reschedule`, `emails->update`의 첫 번째 인자입니다. 모두 별도의 스코프가 아니라 `emails:send`를 필요로 하고, 키 자신의 워크스페이스 안에서 id를 찾으므로, 다른 워크스페이스에 속한 id는 존재한 적 없는 id와 똑같이 `not_found_error`입니다.
$scheduledAtDateTimeInterface or string필수
`emails->reschedule`의 두 번째 인자인 새 시각입니다. 같은 규칙과 같은 1년 범위로 해석됩니다. `reschedule`이 바꾸는 유일한 값이며, 클라이언트는 그 밖에 아무것도 보내지 않습니다. 기간은 서버가 읽는 시점을 기준으로 하므로, 재시도된 일정 변경은 처음보다 조금 뒤에 놓입니다: 더 뒤일 뿐 결코 더 앞은 아닙니다.
apiKeystring
세 호출 중 어느 것에서든 쓰는 명명된 인자입니다. 클라이언트의 키 대신 이 키로 실행합니다.

응답

cancel, reschedule, update는 각각 메시지 전체를 API의 camelCase 이름을 키로 하는 배열로 반환합니다.

objectstring
항상 `email`입니다. 이 호출들은 확인 응답이 아니라 메시지 전체로 답하므로, 무엇이 바뀌었는지 보려고 다시 가져올 필요가 없습니다. `emails->send`는 여기에 `replayed`를 더한 같은 형태를 반환합니다.
idstring
`msg_` 핸들입니다. 메시지가 존재하는 동안 변하지 않으며, 그 메시지에 대한 다른 모든 호출이 받는 id입니다.
statusstring
취소 후에는 `cancelled`, 일정 변경 후에는 `scheduled`이며, 실행 취소 시간 때문에 `queued`에 머물러 있던 메시지도 일정 변경을 거치면 진짜 예약으로 바뀝니다. 옮기거나 중단할 수 있는 것은 `queued`와 `scheduled` 메시지뿐이고, 그 이후 단계는 `errorCode`가 `email_not_cancellable`인 `ConflictException`을 던집니다. 일부가 이미 누군가의 메일함에 들어가 있기 때문입니다.
scheduledAtstring or null
메시지가 발송될 예정인 ISO 8601 시각입니다. 둘이 하나의 메커니즘이므로 `scheduledAt` 발송뿐 아니라 실행 취소 시간에도 설정되며, 평범한 즉시 발송에서는 null입니다.
cancellableUntilstring or null
취소가 더 이상 동작하지 않게 되는 시각이며, 두 지연 경로 모두에서 `scheduledAt`과 같은 시각입니다. 호출이 반환될 때쯤이면 이미 나가 있는 즉시 발송에서는 null입니다.
sentAtstring or null
메시지가 실제로 나간 시각입니다. 대기 중에는 null이고, 취소된 메시지에서는 영원히 null입니다.
messageIdstring or null
RFC 5322의 Message-ID이며 MIME이 만들어지기 전까지는 null이므로, 이 호출들이 다룰 수 있는 메시지에서는 항상 null입니다. API를 호출할 때 쓰는 값도 아니고, 이후 반송이 담고 오는 값도 아닙니다: 발송 서비스가 나가는 길에 헤더를 다시 씁니다.
threadIdstring or null
이 메시지가 속한 스레드로, 요청에서 가져온 뒤 발송이 끝나면 전송 계층이 보고한 값으로 다시 쓰입니다. 답장이 아니면 null입니다.
transportstring or null
바이트가 어떤 경로로 나갔는지이며, 발송 전에는 null이므로 취소나 일정 변경이 반환할 수 있는 모든 메시지에서 null입니다. 테스트 모드의 발송은 `test`를 기록하며, 이 패키지가 아직 이름을 모르는 전송 경로가 나타날 수도 있으므로, 알 수 없는 값은 오류가 아니라 정보로 취급하세요.
attemptsint
발송 과정이 이 행을 몇 번 선점했는지입니다. 성공한 발송이 아니라 선점할 때마다 값이 올라가며, 아직 대기 중인 것은 0입니다.
lastErrorstring or null
메시지에 기록된 마지막 실패이며, 실패한 것이 없으면 null입니다. 작업을 큐에 넣지 못한 지연 발송은 여기에 `Could not schedule: …`로 기록되고 `failed`로 옮겨지는데, 이것이 예약된 메시지가 아무도 요청하지 않았는데 취소 가능 상태에서 벗어나는 유일한 경로입니다.
fromstring
메시지가 나가도록 인가된 주소로, 보낸 `from`을 소문자로 주소만 저장한 값입니다. 표시 이름은 여기서 버려지는데, `emails->list`의 `from:` 필터가 동등 비교를 하기 때문입니다.