Listar y obtener
`emails.list`, `emails.list_all`, `emails.iterate`, `emails.get` y `emails.list_events`.
emails.list
filters = {status: ["queued", "scheduled"], from: "[email protected]"} first = client.emails.list(**filters, limit: 50)second = client.emails.list(**filters, limit: 50, cursor: first.next_cursor) if first.next_cursor p first.items.size, second&.items&.sizeUna página es una OpenEmail::Page con items, has_more? y next_cursor. Devuelve next_cursor como cursor:, con los mismos filtros, para obtener la página siguiente.
emails.iterate y emails.list_all
client.emails.iterate(status: "failed") do |email| warn "#{email[:id]} #{email[:lastError]}"end failures = client.emails.list_all(status: "failed", from: "[email protected]")puts failures.sizeAmbos siguen next_cursor por ti. iterate obtiene una página solo cuando el recorrido llega a ella, así que break en el bloque, o first o find sobre el Enumerator que devuelve sin bloque, detienen las solicitudes, mientras que list_all recorre todas las páginas antes de devolver un único Array, así que dale un filtro que termine. En ambos casos es paginación por keyset, de modo que un mensaje que llegue a mitad de la iteración no puede hacer que se salte una fila, como ocurriría con un offset.
emails.get y emails.list_events
email = client.emails.get("msg_3f9a1c07d2b84e6a9c5b1f20")puts email[:status]p email[:recipients] events = client.emails.list_all_events("msg_3f9a1c07d2b84e6a9c5b1f20")events.each { |event| puts "#{event[:type]} #{event[:createdAt]}" }get es la única llamada que devuelve recipients, un Hash por dirección con sus propios status, error y deliveredAt. Una lista de cincuenta mensajes que llevan cada uno sus destinatarios es un informe de una página que nadie pidió.
list_events lee el rastro de eventos de un envío, del más antiguo al más reciente: email.accepted, email.queued, email.sent, email.delivered, email.bounced, email.opened y los demás, cada uno con un Hash data cuya forma depende de su type. list_all_events e iterate_events recorren todo el rastro por ti. Los webhooks entregan un subconjunto de esos mismos eventos a medida que ocurren, así que aquí es donde mirar cuando se perdió un webhook.
Parámetros
statusString or Array<String>- Un estado o varios (`queued`, `scheduled`, `sending`, `sent`, `partial`, `bounced`, `cancelled`, `failed`), que coinciden con cualquiera de los indicados. `bounced` significa que rebotaron todos los destinatarios a los que fue el mensaje, mientras que un mensaje que rebotó para algunos y llegó al resto figura como `partial`. La gema envía un Array como un único valor separado por comas porque el servidor divide por comas, y un valor fuera de ese conjunto es un 422 que nombra el desconocido.
broadcast_idString- Solo las copias de un envío masivo, un id `brd_` de `broadcasts.send`. Cada persona a la que llega un envío masivo recibe un mensaje propio, así que esto lista a quién fue y qué pasó con cada copia. `broadcasts.list_recipients` lista a las mismas personas con sus aperturas, clics y bajas.
fromString- Coincidencia exacta con la dirección de envío tal como se registró, que es el `addr@host` escueto en minúsculas. La fila se escribe con cualquier nombre visible eliminado, así que una dirección con ángulos como `Acme <[email protected]>` no coincide con nada. Tu valor se pasa a minúsculas antes de comparar, y es una igualdad, no una coincidencia por prefijo ni por dominio.
scheduled_fromTime, DateTime or String- Solo los mensajes programados para este instante o después. Con `scheduled_to:` y `status: ["scheduled", "queued"]` lista lo que espera para salir en una ventana de tiempo, como hace el calendario de la app. Un mensaje sin `scheduledAt` queda fuera. Pasa un Time, un DateTime o un instante ISO 8601 con su desfase horario: una Date de Ruby se envía como fecha sin hora, que estos dos filtros rechazan.
scheduled_toTime, DateTime or String- Solo los mensajes programados para este instante o antes. Un `scheduled_from:` posterior a `scheduled_to:` es un 422 `invalid_parameter`.
limitInteger- Filas en esta página, de 1 a 100, con 25 por defecto. Un valor fuera de ese rango se rechaza con un 422 en lugar de recortarse. En `list_all` e `iterate` es el tamaño de cada página que obtienen.
cursorString- Un id de mensaje (`msg_…`) desde el que paginar. Es keyset y no offset: las filas vuelven estrictamente más antiguas que el `createdAt` de ese mensaje, así que los envíos que lleguen a mitad de página no pueden desplazar una fila y hacer que te la saltes. Un id que no nombra ningún mensaje de este espacio de trabajo es un 400 `invalid_cursor`.
api_keyString- Lista con esta clave en lugar de la del cliente.
Una clave restringida a algunas direcciones solo lee los mensajes enviados desde las direcciones que cubre, y la página se corta después de ese filtro, así que todas las páginas salvo la última siguen conteniendo limit filas. Un from: que la clave no cubre devuelve una última página vacía en lugar de un 403.
Respuesta: OpenEmail::Page
itemsArray<Hash>- Una página de mensajes, de más nuevo a más antiguo por `createdAt`, extraída del sobre `data` de la API. Las filas de la lista nunca llevan el desglose `recipients` por dirección. Eso está en `get`.
has_more?Boolean- Si hay más filas que coinciden con el filtro más allá de esta página. Se responde obteniendo una fila más que `limit` en lugar de con una segunda consulta de recuento.
next_cursorString or nil- El id que hay que devolver como `cursor:`, y nil en la última página. `iterate` y `list_all` se detienen cuando esto es nil o `has_more?` es false, ya que una página que afirme que hay más sin nombrar ningún cursor provocaría un bucle infinito.
Cada elemento
objectString- Siempre `email` en una fila de esta lista.
idString- El id propio de esta API, `msg_…`. Es lo que aceptan todas las demás llamadas de emails y lo que nombra un cursor.
statusString- En qué punto de su vida está el mensaje. `partial` es un estado propio y no una variante de failed: algunos destinatarios ya lo tienen y no se les puede quitar el envío, así que reintentar es un error. `bounced` significa que rebotó en todos los destinatarios después de salir, así que nadie lo tiene, y cada destinatario en `get` dice por qué.
modeString- `live` o `test`, tomado de la clave que lo envió. Un envío de prueba se registra aquí y nunca se transmite.
fromString- La dirección bajo la que se autorizó el envío, almacenada escueta y en minúsculas, de modo que un nombre visible indicado en `from` sí sale por la red pero no se guarda aquí. Es una String simple y no un Hash porque esta es la identidad que se autorizó: una dirección fuera del ámbito de envío de una clave, que no esté en un dominio que posee ni declarada en ella, se rechaza con un 403 y nunca se cambia en silencio por una que sí lo esté.
subjectString or nil- El asunto tal como está almacenado. nil en un mensaje registrado sin ninguno.
messageIdString or nil- El Message-ID de RFC 5322, no nuestro id. nil hasta que existe el MIME, y el servicio de envío lo reescribe a la salida, así que un rebote o DSN posterior lleva un id distinto y se correlaciona mediante `id`.
threadIdString or nil- El hilo al que pertenece este mensaje, cuando se indicó o se asignó uno. nil en caso contrario.
transportString or nil- Cómo salieron los bytes. nil hasta el despacho. Los registros almacenados todavía pueden nombrar transportes que ya no se usan, así que trata un valor que no conozcas como información y no como un error.
attemptsInteger- Cuántos intentos de despacho ha tenido el mensaje, 0 antes del primero.
lastErrorString or nil- El error de despacho más reciente, escrito para una persona. nil mientras no haya fallado nada.
scheduledAtString or nil- Cuándo está previsto que salga el mensaje, como instante ISO 8601. Solo es nil en un envío inmediato sin ventana de cancelación: una ventana es un retraso corto y nada más, así que `cancellableForSeconds` también rellena este campo, en una fila cuyo `status` es `queued` y no `scheduled`.
cancellableUntilString or nil- El instante en que está previsto que salga el mensaje, con el mismo valor que `scheduledAt` en cualquier envío que se aplazara y nil en uno que no. Es una marca de tiempo para mostrar, no la comprobación que hace el servidor: `cancel` ramifica según `status` y solo detiene un mensaje mientras siga en `queued` o `scheduled`.
sentAtString or nil- Cuándo salió. nil hasta que el despacho se ha completado, razón por la cual el campo por el que hay que ramificar es `status` y no este.
tagsHash- Las etiquetas indicadas en el envío, devueltas tal cual y nunca interpretadas. Siempre un Hash, vacío si no se pusieron y nunca nil, y solo devueltas: esta lista filtra por `status`, `from`, `broadcast_id` y la ventana de programación, así que una etiqueta es algo que se lee en un mensaje, no una forma de encontrarlo.
broadcastIdString or nil- El envío masivo `brd_` del que este mensaje es una copia, o nil para un mensaje enviado por sí solo.
sourceString- Qué superficie solicitó el envío: `composer`, `api`, `mcp`, `ai` o `queue`. `api` es este cliente.
createdAtString- Cuándo se escribió el registro de envío, que es antes del despacho. Es el campo por el que ordena la lista y el campo con el que compara un cursor.
trackingHash- El resumen de interacción, presente solo en una fila cuyo mensaje tuvo seguimiento y ausente en caso contrario. Su ausencia es la respuesta a «¿se hizo seguimiento de esto?», mientras que un `openCount` de 0 se leería como «nadie lo abrió».
translationHash- Nunca está presente en una fila de lista: el registro de traducción vive en la solicitud almacenada, que una lista deliberadamente no obtiene. Su ausencia aquí no dice nada sobre si el mensaje se tradujo. Pregúntale a `get`.
El seguimiento de un elemento
opensBoolean- Si este mensaje salió con un píxel. Lo que se aplicó a este mensaje, no lo que dice ahora la configuración de la cuenta.
clicksBoolean- Si se reescribieron los enlaces de este mensaje. False cuando el cuerpo no tenía enlaces que reescribir, ya que entonces no se cambió nada.
openedBoolean- Si se registró alguna apertura contabilizada, derivado de que `openCount` sea mayor que 0.
clickedBoolean- Si se registró algún clic contabilizado, derivado de que `clickCount` sea mayor que 0.
openCountInteger- Aperturas que se cree causadas por una persona, sumadas sobre cada copia del mensaje. Los escáneres y los proxies de privacidad se registran pero se excluyen, y las peticiones repetidas en menos de treinta segundos se agrupan en una.
clickCountInteger- Clics contabilizados, sumados sobre las copias. Se deduplican por enlace y no por mensaje, porque seguir dos enlaces con segundos de diferencia son dos actos y no una repetición.
firstOpenAtString or nil- La primera apertura contabilizada entre las copias, y nil mientras no haya ninguna. Las visitas de máquinas nunca la mueven.