Programar y cancelar
`scheduledAt`, `emails.reschedule`, `emails.update` y `emails.cancel`.
Enviar más 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: Time.utc(2027, 1, 1, 9))client.emails.send(message, scheduledAt: "2027-01-01T09:00:00.000Z")Un Time o un DateTime, un instante ISO 8601 como String, o una duración como PT1H o P2D. Hasta un año en el futuro, nunca en el pasado. Un argumento nombrado junto al Hash añade el campo a un mensaje que construiste antes.
Una Date de Ruby se envía como una fecha sin hora, como 2027-01-01, que la API lee como medianoche UTC de ese día. Pasa un Time, como Time.utc(2027, 1, 1, 9), cuando la hora importe.
Mover y detener
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], Time.now + 86_400)client.emails.cancel(queued[:id])Solo se pueden detener los mensajes en queued y scheduled. Cualquier cosa más avanzada lanza un OpenEmail::ConflictError, porque parte del mensaje ya está en el buzón de alguien. Cancelar un mensaje ya cancelado tiene éxito y no cambia nada.
Para encontrar lo que espera para salir en una ventana de tiempo, lista con status: ["scheduled", "queued"] y scheduled_from: y scheduled_to:, como hace el calendario de la app.
Cambiarlo antes de que salga
emails.update cambia un mensaje que aún no ha salido: cuándo sale con scheduledAt, qué dice con subject, html y text, la dirección desde la que sale con from, y a quién va con to, cc y bcc. Envía los que quieras a la vez, y un campo que omitas conserva su valor. Una lista de destinatarios sustituye entera a la almacenada. Es lo que hace editar un mensaje programado en el calendario de la app.
updated = client.emails.update( "msg_3f9a1c07d2b84e6a9c5b1f20", subject: "Your September invoice, corrected", to: ["[email protected]", "[email protected]"], scheduledAt: Time.utc(2026, 10, 5, 8)) puts updated[:status], updated[:subject], updated[:scheduledAt]from se comprueba igual que en un envío, así que tiene que ser una dirección con la que la clave pueda enviar. Un mensaje que se tradujo al aceptarse conserva su redacción aprobada, así que un subject, html o text nuevo en él es un 409 translation_locked, y uno que se cifró antes de programarse conserva su redacción y sus destinatarios. En esos casos, cancela y vuelve a enviar.
Una ventana de deshacer en su lugar
message = {from: "[email protected]", to: "[email protected]", subject: "Your September invoice", text: "Invoice attached."} held = client.emails.send(message, cancellableForSeconds: 30) puts held[:status], held[:cancellableUntil]Un mensaje programado ya se puede cancelar hasta que sale, así que no se pueden combinar ambos y el servidor lo rechaza. Usa este para una ventana de deshacer el envío en un mensaje inmediato.
Parámetros: programación
scheduledAtTime, DateTime or String- Cuándo enviar, en `emails.send`: un Time o un DateTime, un instante ISO 8601 como String, o una duración como `PT1H` o `P2D`. Un Time o un DateTime se envía como instante UTC, una String tal cual, y una Date de Ruby como fecha sin hora que significa medianoche UTC. Al menos un segundo en el futuro y como máximo 365 días por delante, y superar cualquiera de los dos límites es un `validation_error` en `scheduledAt`. No se acepta lenguaje natural, porque interpretar mal «el próximo martes» envía un mensaje a una hora que ya no se puede deshacer.
cancellableForSecondsInteger- Una ventana de deshacer el envío en un envío INMEDIATO: un Integer de 0 a 900, con 0 por defecto. Cualquier valor superior a 0 se rechaza junto con `scheduledAt`, que ya se puede cancelar hasta que sale, y un mensaje retenido de este modo queda en `queued` y no en `scheduled`. Es el mismo mecanismo de aplazamiento con un retraso corto.
idStringobligatorio- El id `msg_`, y el primer argumento de `emails.cancel`, `emails.reschedule` y `emails.update`. Necesitan `emails:send` en lugar de un ámbito propio, y buscan el id dentro del espacio de trabajo de la propia clave, así que un id que pertenece a otro es un `not_found_error` exactamente igual que un id que nunca existió.
scheduled_atTime, DateTime or Stringobligatorio- La nueva hora, como segundo argumento de `emails.reschedule`, leída con las mismas reglas y contra la misma ventana de un año. Es lo único que cambia `reschedule`, y el cliente no envía nada más. Una duración es relativa al momento en que la lee el SERVIDOR, así que una reprogramación reintentada cae algo más tarde de lo que habría caído la primera: más tarde, nunca antes.
api_keyString- Actúa con esta clave en lugar de la del cliente, en cualquiera de las tres llamadas.
Respuesta
cancel, reschedule y update devuelven cada uno el mensaje completo como un Hash con claves Symbol.
objectString- Siempre `email`. Estas llamadas responden con el mensaje completo en lugar de con un acuse de recibo, así que no hay que volver a pedir nada para ver qué cambió. `emails.send` devuelve esta misma forma más `replayed`.
idString- El identificador `msg_`. Estable durante toda la vida del mensaje y el id que aceptan todas las demás llamadas sobre él.
statusString- `cancelled` tras una cancelación y `scheduled` tras una reprogramación, incluso para un mensaje que solo estaba en `queued` detrás de una ventana de deshacer, que una reprogramación convierte en una programación real. Solo se pueden mover o detener los mensajes en `queued` y `scheduled`. Cualquier cosa más avanzada es un `conflict_error` con el código `email_not_cancellable`, porque parte del mensaje ya está en el buzón de alguien.
scheduledAtString or nil- El instante ISO 8601 en que está previsto despachar el mensaje. Se establece tanto para una ventana de deshacer como para un envío con `scheduledAt`, ya que ambos son un mismo mecanismo, y es nil en un envío inmediato normal.
cancellableUntilString or nil- Cuándo deja de funcionar la cancelación, que es el mismo instante que `scheduledAt` en ambas rutas aplazadas. nil en un envío inmediato, que ya ha salido cuando la llamada retorna.
sentAtString or nil- Cuándo salió realmente el mensaje. nil mientras espera, y nil para siempre en uno cancelado.
messageIdString or nil- El Message-ID de RFC 5322, nil hasta que existe el MIME, así que siempre nil en un mensaje sobre el que pueden actuar estas llamadas. No es algo con lo que dirigirse a la API, ni tampoco aquello con lo que vuelve un rebote posterior: el servicio de envío reescribe la cabecera a la salida.
threadIdString or nil- El hilo al que pertenece este mensaje, tomado de la solicitud y reescrito con lo que informe el transporte una vez enviado. nil cuando no es una respuesta.
transportString or nil- Cómo salieron los bytes, y nil hasta el despacho, así que nil en todos los mensajes que pueden devolver una cancelación o una reprogramación. Un envío en modo de prueba registra `test`, y puede aparecer un transporte que esta gema aún no nombra, así que trata un valor desconocido como información y no como un error.
attemptsInteger- Cuántas veces el despacho ha reclamado esta fila. Aumenta con cada reclamación y no con un envío correcto, y es 0 para todo lo que sigue esperando.
lastErrorString or nil- El último fallo registrado contra el mensaje, nil mientras no haya fallado nada. Un envío aplazado cuyo trabajo no se pudo encolar se escribe aquí como `Could not schedule: …` y pasa a `failed`, que es la única forma en que un mensaje programado deja de poder cancelarse sin que nadie lo pida.
fromString- La dirección con la que se autorizó que saliera el mensaje: el `from` que se envió, almacenado escueto y en minúsculas. Aquí se descarta cualquier nombre visible, porque el filtro `from:` de `emails.list` compara por igualdad.