Ir a la documentación
Python

Seguimiento de aperturas y clics

`emails.get_tracking` y todo el recurso `tracking`.

Un mensaje

tracking.py
from openemail import openemail report = openemail.emails.get_tracking('msg_…') print(report['openCount'], 'opens from', len(report['recipients']), 'recipients')for link in report['links']:    print(link['url'], link['clickCount'])

Un mensaje del que nunca se hizo seguimiento lanza un OpenEmailApiError cuyo is_not_found es verdadero, no un informe vacío. «No registramos nada» y «nadie lo abrió» son respuestas distintas y no deben compartir una misma respuesta.

En todo el buzón

tracking_report.py
import time from openemail import openemail openemail.tracking.list(opened=False, days=7, limit=100)openemail.tracking.get_stats(days=30, offset_minutes=time.localtime().tm_gmtoff // 60)openemail.tracking.get('msg_…')openemail.tracking.list_opens('msg_…', include_machine=True)openemail.tracking.list_clicks('msg_…')

list, list_opens y list_clicks devuelven una página, {'items': [...], 'hasMore': ..., 'nextCursor': ...}, y list_all, iterate, list_all_opens, iterate_opens, list_all_clicks e iterate_clicks recorren todas las páginas por ti. get, list_opens y list_clicks aceptan tanto el id de envío msg_… como el tmsg_… propio del registro de seguimiento.

Es un recurso propio en lugar de campos en emails, y el motivo es la cobertura: emails lista registros de envío, que solo existen para el correo que gestionó esta API. El redactor, las herramientas MCP y el asistente envían sin uno, así que un informe construido sobre emails sería un informe sobre tu tráfico de API y no sobre el buzón.

Leer las cifras con honestidad

ParQué significa
opens / clicksLo que se APLICÓ: si el mensaje salió con un píxel o con enlaces reescritos.
opened / clickedLo que ocurrió.
openCountVisitas contabilizadas. Se excluyen los escáneres y los proxies de privacidad.
openCountRawTodas las visitas. Citar esto como interacción es la forma de que una tasa de apertura supere el 100 %.
attributableSi una lectura puede atribuirse siquiera a un destinatario concreto.

Las tasas de tracking.get_stats se calculan sobre los mensajes CON SEGUIMIENTO, nunca sobre todo lo enviado. De lo contrario, un buzón que hace seguimiento de uno de cada diez mensajes parecería haberse hundido.

Parámetros: tracking.list

openedbool
`True` selecciona los mensajes con al menos una apertura contabilizada; `False` selecciona los mensajes con seguimiento que no tienen ninguna. Ninguno es el valor por defecto, y `False` nunca significa correo sin seguimiento, que no aparece en esta lista en absoluto.
clickedbool
El mismo filtro para los clics contabilizados, aplicado con independencia de `opened`. Se pueden indicar ambos, y los mensajes deben cumplir los dos.
daysint
Cuántos días hacia atrás desde ahora hay que mirar, de 1 a 365 y con 30 por defecto; fuera de ese rango es un 422. La ventana se mide sobre la fecha de creación del registro de seguimiento, y solo se listan los registros cuyo envío salió realmente.
limitint
Informes por página, de 1 a 200 y con 50 por defecto, de más nuevo a más antiguo. Devuelve el `nextCursor` de la página como `cursor`, con los mismos filtros, para la siguiente, o deja que `list_all` e `iterate` recorran toda la ventana.

Respuesta: TrackingResource

objectLiteral['tracking']
Siempre `'tracking'` en un informe obtenido por sí mismo, mediante `tracking.get`, `tracking.list` o `emails.get_tracking`. El mismo informe anidado como `email['tracking']` en un mensaje recuperado llega sin esta clave, porque allí forma parte de ese objeto en lugar de ser algo que se obtuvo.
idstr
El id propio del registro de seguimiento, `tmsg_…`. Es la clave sobre la que operan las llamadas por visita `list_opens` y `list_clicks`; un `msg_…` que se les entregue se resuelve antes a este.
sendIdstr | None
El envío `msg_…` con el que se correlaciona, y null cuando no se escribió ningún registro de envío. El redactor, el `sendEmail` de MCP y el asistente envían todos sin uno. El seguimiento cubre el buzón, no solo el tráfico de la API.
threadIdstr | None
Se rellena tras la transmisión para que una interfaz de lectura pueda volver a encontrar el mensaje, y es null cuando el driver no informó de ninguno. No es imprescindible: un registro con este campo en null sigue contando.
messageIdstr | None
El Message-ID de RFC 5322, no nuestro id. También se rellena tras la transmisión, y es null cuando el transporte no devolvió nada con lo que rellenarlo.
subjectstr | None
El asunto tal como estaba en el momento del envío. Null en un mensaje registrado sin ninguno.
fromstr
La dirección de envío, copiada en el registro en lugar de unida desde el envío. Los informes se leen mucho después, y una dirección corregida o eliminada desde entonces reescribiría la historia.
sourceEmailSource | str
Qué superficie lo envió: `composer`, `api`, `mcp`, `ai`, `oauth` o `form`. Con tipo abierto para que una superficie que este SDK aún no nombra no sea un cambio incompatible.
sentAtstr | None
Cuándo salió el mensaje, como instante ISO-8601. Null en un registro cuyo envío nunca se completó. `tracking.list` los excluye; `get` no.
opensbool
Si se APLICÓ un píxel a este mensaje. Esto es lo que se hizo, no lo que dice ahora la configuración de la cuenta.
clicksbool
Si se reescribieron los enlaces de este mensaje. False cuando el cuerpo no llevaba enlaces, porque entonces no se cambió nada y un registro que afirmara lo contrario no se podría conciliar con los bytes.
openedbool
Si se registró alguna apertura contabilizada entre las copias. Léelo junto con `opens`: que no haya datos porque no se recogió ninguno es un hecho distinto de que nadie haya leído el mensaje.
clickedbool
Si se registró algún clic contabilizado. Es una prueba más sólida que una apertura, ya que las imágenes se bloquean mucho más a menudo de lo que los enlaces se quedan sin seguir.
attributablebool
Si toda lectura recogida aquí puede atribuirse a un destinatario concreto. Es False en cuanto una copia sin atribuir muestra actividad contabilizada, que es el caso de varios destinatarios en el que un mismo cuerpo va a toda la lista bajo un único token, así que compruébalo antes de escribir «Bob no ha abierto esto».
openCountint
Aperturas que se cree causadas por una persona, sumadas sobre las copias. Se excluyen las visitas de máquinas y las repeticiones en menos de treinta segundos se agrupan en una, así que esta es la cifra que hay que poner delante de un lector.
clickCountint
Clics contabilizados, sumados sobre las copias. Se deduplican por enlace y no por mensaje, así que dos enlaces distintos seguidos con segundos de diferencia son dos clics.
openCountRawint
Todas las peticiones del píxel, incluidos los escáneres y los proxies de privacidad. `openCountRaw - openCount` es cuántas apartó el clasificador, y la única prueba disponible de que el filtrado llegó a ocurrir.
clickCountRawint
Todas las visitas a un enlace reescrito, incluidas las de máquinas y las repeticiones.
firstOpenAtstr | None
La primera apertura contabilizada entre las copias, y null mientras no haya ninguna. Las visitas de máquinas nunca la mueven.
lastOpenAtstr | None
La apertura contabilizada más reciente entre las copias, null mientras no haya ninguna.
firstClickAtstr | None
El primer clic contabilizado entre las copias, null mientras no haya ninguno.
lastClickAtstr | None
El clic contabilizado más reciente entre las copias, null mientras no haya ninguno.
recipientslist[TrackingRecipientResource]
Una entrada por copia con seguimiento: una por destinatario cuando el transporte permite que los bytes difieran por persona, y una única entrada compartida cuando no. La entrada compartida se descarta salvo que realmente haya llegado algo a ella, así que una fila «alguien» sin tocar nunca aparece junto a nombres reales.
recipients[].emailstr | None
A quién fue esta copia, en minúsculas y tal como estaba en el momento del envío. Es null exactamente cuando `attributed` es false.
recipients[].kindRecipientKind | None
En qué cabecera apareció la dirección, para que un informe se lea igual que se leyó el mensaje. Null en la copia compartida, que no pertenece a ninguna dirección.
recipients[].attributedbool
Si esta fila nombra a una persona. Léelo antes que `email`: false es la copia compartida, que se lista en cuanto le llega cualquier visita, y ponerle un nombre a esa visita, incluso en un mensaje con un solo destinatario, inventaría el único dato que el mecanismo no puede aportar.
recipients[].openCountint
Aperturas contabilizadas solo en esta copia, con las mismas exclusiones que el total del mensaje: se descartan las visitas de máquinas y las repeticiones en menos de treinta segundos se agrupan en una.
recipients[].clickCountint
Clics contabilizados solo en esta copia, deduplicados por enlace y no por copia.
recipients[].firstOpenAtstr | None
La primera apertura contabilizada en esta copia, null mientras no haya ninguna.
recipients[].lastOpenAtstr | None
La apertura contabilizada más reciente en esta copia, null mientras no haya ninguna.
recipients[].firstClickAtstr | None
El primer clic contabilizado en esta copia, null mientras no haya ninguno.
recipients[].lastClickAtstr | None
El clic contabilizado más reciente en esta copia, null mientras no haya ninguno.
linkslist[TrackingLinkResource]
Todos los enlaces que se reescribieron en este mensaje, ordenados por su posición en el cuerpo. Vacío cuando no hubo ninguno: un mensaje enviado con `clicks` desactivado, o uno cuyo cuerpo no llevaba ningún enlace.
links[].idstr
El id propio del enlace, `lnk_…`. Es el valor que nombra el `linkId` de una fila de clic, de modo que una visita de `list_clicks` puede emparejarse con la entrada de aquí.
links[].urlstr
Adónde va realmente el enlace, tal como estaba en el mensaje antes de la reescritura. El redirector resuelve un id de vuelta a esto y envía al visitante a su destino.
links[].labelstr | None
El texto del enlace tal como apareció en el mensaje, o null cuando el enlace no tenía ninguno, como una imagen o una URL escueta. Está ahí para que un informe pueda decir «el enlace de precios» en lugar de citar una URL con tres parámetros de seguimiento, y nunca sustituye a `url`.
links[].clickCountint
Visitas contabilizadas a este enlace, sumadas sobre las copias. La misma ventana de treinta segundos por enlace que `clickCount` en el mensaje.
links[].clickCountRawint
Todas las visitas a este enlace, incluidas las de máquinas y las repeticiones.

Referencia