API de Action Log: cómo los clientes integran los eventos de perfiles en sus propios sistemas


Alex Phillips
Customer Service Specialist
La interfaz estándar de Octo Browser muestra lo que ocurre con tu perfil en ese momento. Pero cuando un equipo gestiona cientos o miles de perfiles, llega un momento en el que necesitas enviar automáticamente los eventos de los perfiles a un CRM, un sistema de control de acceso o un panel interno.
Para eso sirve Action Log de Octo: un endpoint de WebSocket que transmite eventos en tiempo real. Lo añadimos para equipos que han integrado Octo en su propio CRM, ERP o sistema de gestión. Actualmente, Action Log de Octo admite diez tipos de eventos, desde el inicio y la detención de perfiles hasta su transferencia, eliminación y cambio de proxy, y la lista sigue creciendo a medida que los equipos encuentran nuevos casos de uso.
A continuación, mostramos dos ejemplos de cómo puedes utilizar Action Log en la práctica: control de acceso en tiempo real y gestión de la actividad del equipo a gran escala.
Contenidos
Mantén tu anonimato en línea con Octo Browser. Tu huella digital real no se puede rastrear.
¿Te gustaría probar Octo Browser con descuento?
Usa el código promocional OCTOBLOG para obtener un 30% de descuento en cualquier suscripción. Esta oferta es válida solo para nuevos usuarios.
Control de acceso sin comprobaciones manuales
Uno de nuestros clientes tiene empleados de distintos departamentos trabajando con perfiles de Octo Browser. Cada empleado tiene su propio nivel de acceso mediante una extensión personalizada que utiliza junto con Octo. Antes de conceder los permisos necesarios, el sistema debe saber quién está trabajando en ese momento con un perfil concreto.
Sin Action Log, no era posible saber exactamente quién iniciaba un perfil. El sistema de niveles de acceso tenía que basarse en indicadores indirectos: podía detectar que un perfil estaba en uso, pero no quién lo estaba utilizando.
El proceso cambió cuando añadimos el evento profiles.started: user_email a Action Log; llega en el momento en que se inicia el perfil y los permisos se aplican automáticamente. Esta relación evento → permisos se convirtió en la base de la mayoría de las automatizaciones internas de nuestros clientes.
Es un mecanismo que funciona continuamente y responde en tiempo real a cada inicio de perfil. Los eventos se procesan sobre la marcha y se guardan en la base de datos propia del cliente.
El cliente necesitó un desarrollador y aproximadamente una hora para integrarlo. Action Log se incorporó al sistema de permisos existente como un módulo adicional, sin necesidad de reconstruir el proceso desde cero.
Gestión del equipo en segundos en lugar de horas
Otro cliente prepara un gran volumen de cuentas con un equipo distribuido: muchas personas y muchos perfiles trabajando al mismo tiempo. A esta escala, es fácil perder la visión general: cuántos perfiles gestiona cada persona, cuántos están listos, cuántos se han asignado, cuántos se han eliminado y quién y por qué realizó cada acción.
Antes de pasar a su propio sistema, el equipo llevaba el control en hojas de cálculo. Cualquier consulta sobre el estado del equipo requería revisar manualmente las etiquetas y los registros. Recopilar datos actualizados llevaba desde un par de horas hasta un día entero y, cuando el informe estaba listo, parte de la información ya estaba desactualizada.
Cuando ampliamos las funciones de Action Log, el cliente creó su propio CRM, que recibe los eventos de los perfiles mediante la API y los reúne en una única vista: cuántos perfiles está gestionando cada empleado, cuántos están listos, cuántos se han asignado y cuántos se han eliminado, vinculando cada acción con la persona que la realizó y el momento en que lo hizo.
Todos los datos aparecen en un panel como contadores y estados y se actualizan automáticamente. Un informe que antes tardaba horas en prepararse ahora se genera en 30 segundos: solo hay que abrir la sección correspondiente.
El sistema se desarrolló sin contar con un desarrollador interno, utilizando herramientas de IA para escribir código. Crear una versión funcional del CRM con integración mediante API llevó una semana.
Otras formas de utilizar Action Log
Una misma API permite resolver distintas tareas: control operativo en tiempo real, registro de acciones y automatización de procesos internos. En los dos casos descritos, la integración llevó horas o días, no meses, y no requirió un equipo de desarrollo independiente.
El principio es el mismo en todos los casos: Octo transmite en tiempo real los eventos relacionados con las acciones realizadas con los perfiles, mientras que el sistema del cliente decide cómo procesarlos, almacenarlos y utilizarlos.
Las necesidades reales de los clientes determinan en gran medida la evolución de Action Log. Eventos como profiles.transferred, profiles.deleted y profiles.proxy_changed surgieron a petición de equipos que ya habían creado procesos en torno a la API, pero necesitaban más datos. La lista de eventos seguirá ampliándose en esta misma dirección.
Además de los casos descritos anteriormente, Action Log puede utilizarse para otras tareas:
Facturación y cálculos internos:
run_durationdeprofiles.stoppedproporciona la duración exacta de la sesión, lo que resulta útil si facturas el trabajo de los empleados en función del tiempo real que pasan trabajando con un perfil, sin necesidad de un rastreador de tiempo independiente.Auditoría de eliminaciones:
profiles.deletedyprofiles.trashed, junto conuser_email, permiten saber rápidamente quién eliminó un perfil concreto y cuándo, sin tener que preguntárselo manualmente al equipo.Control de las transferencias de perfiles:
profiles.transferredincluye ambas partes en un mismo registro: el remitente y el destinatario, sin necesidad de cruzar datos de distintas fuentes.Notificaciones sobre pérdida de datos:
profiles.force_stoppedsignifica que un perfil en ejecución pasó al estado inactivo porque no se cerró correctamente. Los resultados del trabajo realizado en el perfil en el momento de la detención forzada no se sincronizan, por lo que conviene avisar a los compañeros que estaban trabajando con él: sus cambios no se guardarán. Más información en la documentación.Control de cambios de proxy: el trío
proxy_assigned/proxy_unassigned/proxy_changedresulta útil cuando los sistemas externos necesitan conocer el proxy actual de un perfil sin tener que consultarlo periódicamente.
Hay una limitación importante: Action Log funciona como un flujo de eventos y solo conserva los datos de las últimas 24 horas. Por eso, si necesitas los eventos para auditorías o análisis a largo plazo, debes guardarlos en tu propio sistema a medida que llegan.
Ahora vamos a ver los eventos disponibles y cómo trabajar con ellos.
Cómo funciona Action Log en Octo Browser
Tipo: WebSocket
URL:
wss://app.octobrowser.net/api/v2/automation/ws/action_logAutorización: token en el encabezado
X-Octo-Api-Token
Después de conectarte, el servidor envía automáticamente los eventos a medida que se producen, sin necesidad de realizar solicitudes repetidas. Cada mensaje es un StreamPage: un conjunto de eventos y un watermark.
{ "items": [ { "uuid": "550e8400-e29b-41d4-a716-446655440000", "action": "profiles.started", "time": 1707053400, "user_email": "user@example.com", "object_type": "profile", "object_id": "a1b2c3d4e5f67890abcdef1234567890", "object_title": "Octo Browser Profile", "data": { "connection_data": { "ip": "203.0.113.42", "countryCode": "FR", "countryName": "France", "subdivisions": ["Île-de-France", "Paris"], "postalCode": "75008", "cityName": "Paris", "timezone": "Europe/Paris", "lat": 48.8566, "lon": 2.3522, "languages": ["fr", "en-US", "en"], "isp": "Example Networks Ltd", "connectionType": "Cable/DSL" } } } ], "watermark": { "uuid": "550e8400-e29b-41d4-a716-446655440000", "time": 1707053400 } }
{ "items": [ { "uuid": "550e8400-e29b-41d4-a716-446655440000", "action": "profiles.started", "time": 1707053400, "user_email": "user@example.com", "object_type": "profile", "object_id": "a1b2c3d4e5f67890abcdef1234567890", "object_title": "Octo Browser Profile", "data": { "connection_data": { "ip": "203.0.113.42", "countryCode": "FR", "countryName": "France", "subdivisions": ["Île-de-France", "Paris"], "postalCode": "75008", "cityName": "Paris", "timezone": "Europe/Paris", "lat": 48.8566, "lon": 2.3522, "languages": ["fr", "en-US", "en"], "isp": "Example Networks Ltd", "connectionType": "Cable/DSL" } } } ], "watermark": { "uuid": "550e8400-e29b-41d4-a716-446655440000", "time": 1707053400 } }
Actualmente, Action Log admite diez tipos de eventos:
profiles.started— el perfil se ha iniciado;profiles.stopped— el perfil se ha detenido;profiles.force_stopped— el perfil se ha detenido de forma forzada;profiles.transferred— el perfil se ha transferido a otro usuario;profiles.trashed— el perfil se ha movido a la papelera;
profiles.deleted — el perfil se ha eliminado;
profiles.updated— el perfil se ha modificado;profiles.proxy_assigned— se ha asignado un proxy al perfil;profiles.proxy_unassigned— se ha quitado el proxy del perfil;profiles.proxy_changed— se ha cambiado el proxy por otro.
Para evitar problemas cuando se interrumpe la conexión, cada mensaje incluye un watermark: el UUID y la hora del último evento. Al volver a conectarte, basta con pasar este UUID en el parámetro after_uuid: el flujo enviará todo lo que haya ocurrido durante la interrupción, sin perder ni duplicar eventos. Otra opción es comenzar desde un momento concreto mediante from_timestamp. La única limitación es que los eventos se conservan durante 24 horas: es un flujo de datos activo, no un archivo histórico.
Esto también funciona con operaciones masivas: si un empleado mueve 100 perfiles a la papelera de una vez, en el flujo aparecerán los 100 eventos, cada uno con su propio object_id; ninguno se perderá ni se duplicará.
Puedes obtener más información sobre el funcionamiento de Action Log en la documentación.
Qué contiene data: desglose por evento
El conjunto de campos dentro de data depende de action. Esto es lo que se recibe para cada uno de los diez tipos:
Evento | Contenido de |
|
|
|
|
|
|
|
|
|
|
|
|
| los mismos campos con los prefijos |
profiles.stopped
La duración de la sesión se recibe en formato ISO 8601, no como un número de segundos:
{ "action": "profiles.stopped", "data": { "run_duration": "PT19.627134S" } }
{ "action": "profiles.stopped", "data": { "run_duration": "PT19.627134S" } }
profiles.updated
Changeset no es una lista fija de campos, sino una diferencia dinámica: contiene únicamente lo que ha cambiado en esa ocasión. Por ejemplo, si se modifican varias opciones del perfil a la vez, se recibe lo siguiente:
{ "action": "profiles.updated", "data": { "changeset": { "description": { "old_value": "", "new_value": "Test action log" }, "start_pages": { "added": ["http://google.com", "http://facebook.com"], "removed": [] }, "storage_options": { "added": ["serviceworkers", "localstorage"], "removed": [] }, "bookmarks": { "added": ["https://ebay.com", "https://amazon.com"], "removed": [] }, "launch_args": { "added": ["--start-maximized"], "removed": [] }, "images_load_limit": { "old_value": null, "new_value": 10240 }, "local_cache": { "old_value": false, "new_value": true }, "fingerprint": {} } } }
{ "action": "profiles.updated", "data": { "changeset": { "description": { "old_value": "", "new_value": "Test action log" }, "start_pages": { "added": ["http://google.com", "http://facebook.com"], "removed": [] }, "storage_options": { "added": ["serviceworkers", "localstorage"], "removed": [] }, "bookmarks": { "added": ["https://ebay.com", "https://amazon.com"], "removed": [] }, "launch_args": { "added": ["--start-maximized"], "removed": [] }, "images_load_limit": { "old_value": null, "new_value": 10240 }, "local_cache": { "old_value": false, "new_value": true }, "fingerprint": {} } } }
Puedes observar dos patrones:
para valores individuales (
description,images_load_limit,local_cache), se incluye un parold_value/new_value;para listas (
start_pages,storage_options,bookmarks,launch_args), se incluyenadded/removed.
fingerprint es una excepción: la clave aparece cuando la huella realmente ha cambiado, pero siempre como un objeto vacío, sin detalles sobre qué ha cambiado en su interior. La regla general es sencilla: si un campo no ha cambiado, su clave no aparecerá en changeset.
profiles.deleted
{ "action": "profiles.deleted", "data": { "manual": true } }
{ "action": "profiles.deleted", "data": { "manual": true } }
profiles.proxy_changed
Compara el proxy antiguo y el nuevo en un único evento:
{ "action": "profiles.proxy_changed", "data": { "old_proxy_uuid": "370b0ce963194f68803a812dd42db4be", "old_proxy_title": "Netlabs GB England", "old_url": "socks5://user:pass@proxy.example.com:1080", "new_proxy_uuid": "9c51385c3e2b417d9b34fc305a49d4f6", "new_proxy_title": "Netlabs GB England Towcester", "new_url": "socks5://user:pass@proxy2.example.com:1080" } }
{ "action": "profiles.proxy_changed", "data": { "old_proxy_uuid": "370b0ce963194f68803a812dd42db4be", "old_proxy_title": "Netlabs GB England", "old_url": "socks5://user:pass@proxy.example.com:1080", "new_proxy_uuid": "9c51385c3e2b417d9b34fc305a49d4f6", "new_proxy_title": "Netlabs GB England Towcester", "new_url": "socks5://user:pass@proxy2.example.com:1080" } }
profiles.proxy_assigned y profiles.proxy_unassigned devuelven los mismos campos, pero sin los prefijos old_ / new_: un único conjunto de campos por evento, en lugar de una comparación.
El campo temporary merece una mención aparte: true significa que el proxy se ha introducido mediante una acción rápida (por ejemplo, pegando una línea), en lugar de asignarlo de la forma habitual desde la configuración del perfil.
profiles.trashed y eliminación automática
profiles.trashed llega con un data vacío, al igual que force_stopped. Si el perfil no se restaura ni se elimina manualmente, se eliminará automáticamente después de 72 horas. Más información en la documentación de la papelera.
profiles.transferred
Un único evento contiene ambas partes:
{ "action": "profiles.transferred", "user_email": "sender@example.com", "data": { "receiver": "receiver@example.com" } }
{ "action": "profiles.transferred", "user_email": "sender@example.com", "data": { "receiver": "receiver@example.com" } }
user_email: como en cualquier otro evento, es el correo del usuario que realizó la acción, es decir, el remitente de la transferencia.
data.receiver: el destinatario.
Conexión y reconexión
Puedes conectarte con cualquier cliente compatible con WebSocket.
En Node.js, sería así:
const WebSocket = require('ws'); const ws = new WebSocket('wss://app.octobrowser.net/api/v2/automation/ws/action_log', { headers: { 'X-Octo-Api-Token': 'Octo API Token' } }); ws.on('open', () => console.log('Connected!')); ws.on('message', (data) => { const parsed = JSON.parse(data.toString()); console.log(JSON.stringify(parsed, null, 2)); console.log(''); }); ws.on('error', (err) => console.log('Error:', err.message)); ws.on('close', () => console.log('Connection closed'));
const WebSocket = require('ws'); const ws = new WebSocket('wss://app.octobrowser.net/api/v2/automation/ws/action_log', { headers: { 'X-Octo-Api-Token': 'Octo API Token' } }); ws.on('open', () => console.log('Connected!')); ws.on('message', (data) => { const parsed = JSON.parse(data.toString()); console.log(JSON.stringify(parsed, null, 2)); console.log(''); }); ws.on('error', (err) => console.log('Error:', err.message)); ws.on('close', () => console.log('Connection closed'));
Esto significa cada campo del evento recibido:
uuid — identificador del propio evento, no del perfil; es único para cada registro, incluso si se producen varios eventos en el mismo segundo;
action — tipo de acción de la lista anterior;
time — hora del evento en formato Unix;
user_email — correo del usuario que realizó la acción;
object_type — tipo de objeto al que corresponde el evento;
object_id — identificador del propio perfil, independiente del UUID del evento;
object_title — nombre del perfil en el momento del evento;
data — detalles que dependen de
action, descritos anteriormente.
Si se detiene un perfil, llegará un segundo evento, profiles.stopped, con un nuevo uuid, pero con el mismo object_id, ya que se trata del mismo perfil. Puedes utilizar object_id para vincular todos los eventos de un perfil en un único historial en tu sistema: object_id no cambia durante toda la vida del perfil, desde que se inicia hasta que se elimina.
Para continuar el flujo después de una interrupción de la conexión, basta con guardar el uuid del último watermark recibido y pasarlo en after_uuid:
const WebSocket = require('ws'); const ws = new WebSocket('wss://app.octobrowser.net/api/v2/automation/ws/action_log?after_uuid=UUID', { headers: { 'X-Octo-Api-Token': 'Octo API Token' } }); ws.on('open', () => console.log('Connected!')); ws.on('message', (data) => { const parsed = JSON.parse(data.toString()); console.log(JSON.stringify(parsed, null, 2)); console.log(''); }); ws.on('error', (err) => console.log('Error:', err.message)); ws.on('close', () => console.log('Connection closed'));
const WebSocket = require('ws'); const ws = new WebSocket('wss://app.octobrowser.net/api/v2/automation/ws/action_log?after_uuid=UUID', { headers: { 'X-Octo-Api-Token': 'Octo API Token' } }); ws.on('open', () => console.log('Connected!')); ws.on('message', (data) => { const parsed = JSON.parse(data.toString()); console.log(JSON.stringify(parsed, null, 2)); console.log(''); }); ws.on('error', (err) => console.log('Error:', err.message)); ws.on('close', () => console.log('Connection closed'));
La conexión enviará inmediatamente los eventos que se hayan producido después de ese UUID y, a continuación, continuará funcionando como un flujo normal. Solo tendrás que volver a indicar after_uuid después de la siguiente interrupción.
Si no tienes un watermark guardado, por ejemplo, después de una interrupción prolongada en la que solo conoces aproximadamente el momento en que se produjo la desconexión, puedes comenzar desde un momento concreto mediante from_timestamp (tiempo Unix en segundos):
const WebSocket = require('ws'); const ws = new WebSocket('wss://app.octobrowser.net/api/v2/automation/ws/action_log?from_timestamp=TIMESTAMP', { headers: { 'X-Octo-Api-Token': 'Octo API Token' } }); ws.on('open', () => console.log('Connected!')); ws.on('message', (data) => { const parsed = JSON.parse(data.toString()); console.log(JSON.stringify(parsed, null, 2)); console.log(''); }); ws.on('error', (err) => console.log('Error:', err.message)); ws.on('close', () => console.log('Connection closed'));
const WebSocket = require('ws'); const ws = new WebSocket('wss://app.octobrowser.net/api/v2/automation/ws/action_log?from_timestamp=TIMESTAMP', { headers: { 'X-Octo-Api-Token': 'Octo API Token' } }); ws.on('open', () => console.log('Connected!')); ws.on('message', (data) => { const parsed = JSON.parse(data.toString()); console.log(JSON.stringify(parsed, null, 2)); console.log(''); }); ws.on('error', (err) => console.log('Error:', err.message)); ws.on('close', () => console.log('Connection closed'));
Si estás empezando a trabajar con automatización, explicamos la API de Octo Browser con más detalle en un artículo aparte.
Conclusión
Action Log permite utilizar los eventos de Octo Browser como parte de tu propia infraestructura: enviarlos a un CRM, un sistema de control de acceso, una plataforma de analítica u otras herramientas internas. Octo informa de lo que ha ocurrido con el perfil y tú decides cómo procesar, guardar y utilizar esos datos.
Si tienes un caso de uso para Action Log, cuéntanoslo. Muchos de los eventos disponibles actualmente surgieron precisamente de las necesidades reales de equipos que trabajan con la API.
Mantén tu anonimato en línea con Octo Browser. Tu huella digital real no se puede rastrear.
¿Te gustaría probar Octo Browser con descuento?
Usa el código promocional OCTOBLOG para obtener un 30% de descuento en cualquier suscripción. Esta oferta es válida solo para nuevos usuarios.
Control de acceso sin comprobaciones manuales
Uno de nuestros clientes tiene empleados de distintos departamentos trabajando con perfiles de Octo Browser. Cada empleado tiene su propio nivel de acceso mediante una extensión personalizada que utiliza junto con Octo. Antes de conceder los permisos necesarios, el sistema debe saber quién está trabajando en ese momento con un perfil concreto.
Sin Action Log, no era posible saber exactamente quién iniciaba un perfil. El sistema de niveles de acceso tenía que basarse en indicadores indirectos: podía detectar que un perfil estaba en uso, pero no quién lo estaba utilizando.
El proceso cambió cuando añadimos el evento profiles.started: user_email a Action Log; llega en el momento en que se inicia el perfil y los permisos se aplican automáticamente. Esta relación evento → permisos se convirtió en la base de la mayoría de las automatizaciones internas de nuestros clientes.
Es un mecanismo que funciona continuamente y responde en tiempo real a cada inicio de perfil. Los eventos se procesan sobre la marcha y se guardan en la base de datos propia del cliente.
El cliente necesitó un desarrollador y aproximadamente una hora para integrarlo. Action Log se incorporó al sistema de permisos existente como un módulo adicional, sin necesidad de reconstruir el proceso desde cero.
Gestión del equipo en segundos en lugar de horas
Otro cliente prepara un gran volumen de cuentas con un equipo distribuido: muchas personas y muchos perfiles trabajando al mismo tiempo. A esta escala, es fácil perder la visión general: cuántos perfiles gestiona cada persona, cuántos están listos, cuántos se han asignado, cuántos se han eliminado y quién y por qué realizó cada acción.
Antes de pasar a su propio sistema, el equipo llevaba el control en hojas de cálculo. Cualquier consulta sobre el estado del equipo requería revisar manualmente las etiquetas y los registros. Recopilar datos actualizados llevaba desde un par de horas hasta un día entero y, cuando el informe estaba listo, parte de la información ya estaba desactualizada.
Cuando ampliamos las funciones de Action Log, el cliente creó su propio CRM, que recibe los eventos de los perfiles mediante la API y los reúne en una única vista: cuántos perfiles está gestionando cada empleado, cuántos están listos, cuántos se han asignado y cuántos se han eliminado, vinculando cada acción con la persona que la realizó y el momento en que lo hizo.
Todos los datos aparecen en un panel como contadores y estados y se actualizan automáticamente. Un informe que antes tardaba horas en prepararse ahora se genera en 30 segundos: solo hay que abrir la sección correspondiente.
El sistema se desarrolló sin contar con un desarrollador interno, utilizando herramientas de IA para escribir código. Crear una versión funcional del CRM con integración mediante API llevó una semana.
Otras formas de utilizar Action Log
Una misma API permite resolver distintas tareas: control operativo en tiempo real, registro de acciones y automatización de procesos internos. En los dos casos descritos, la integración llevó horas o días, no meses, y no requirió un equipo de desarrollo independiente.
El principio es el mismo en todos los casos: Octo transmite en tiempo real los eventos relacionados con las acciones realizadas con los perfiles, mientras que el sistema del cliente decide cómo procesarlos, almacenarlos y utilizarlos.
Las necesidades reales de los clientes determinan en gran medida la evolución de Action Log. Eventos como profiles.transferred, profiles.deleted y profiles.proxy_changed surgieron a petición de equipos que ya habían creado procesos en torno a la API, pero necesitaban más datos. La lista de eventos seguirá ampliándose en esta misma dirección.
Además de los casos descritos anteriormente, Action Log puede utilizarse para otras tareas:
Facturación y cálculos internos:
run_durationdeprofiles.stoppedproporciona la duración exacta de la sesión, lo que resulta útil si facturas el trabajo de los empleados en función del tiempo real que pasan trabajando con un perfil, sin necesidad de un rastreador de tiempo independiente.Auditoría de eliminaciones:
profiles.deletedyprofiles.trashed, junto conuser_email, permiten saber rápidamente quién eliminó un perfil concreto y cuándo, sin tener que preguntárselo manualmente al equipo.Control de las transferencias de perfiles:
profiles.transferredincluye ambas partes en un mismo registro: el remitente y el destinatario, sin necesidad de cruzar datos de distintas fuentes.Notificaciones sobre pérdida de datos:
profiles.force_stoppedsignifica que un perfil en ejecución pasó al estado inactivo porque no se cerró correctamente. Los resultados del trabajo realizado en el perfil en el momento de la detención forzada no se sincronizan, por lo que conviene avisar a los compañeros que estaban trabajando con él: sus cambios no se guardarán. Más información en la documentación.Control de cambios de proxy: el trío
proxy_assigned/proxy_unassigned/proxy_changedresulta útil cuando los sistemas externos necesitan conocer el proxy actual de un perfil sin tener que consultarlo periódicamente.
Hay una limitación importante: Action Log funciona como un flujo de eventos y solo conserva los datos de las últimas 24 horas. Por eso, si necesitas los eventos para auditorías o análisis a largo plazo, debes guardarlos en tu propio sistema a medida que llegan.
Ahora vamos a ver los eventos disponibles y cómo trabajar con ellos.
Cómo funciona Action Log en Octo Browser
Tipo: WebSocket
URL:
wss://app.octobrowser.net/api/v2/automation/ws/action_logAutorización: token en el encabezado
X-Octo-Api-Token
Después de conectarte, el servidor envía automáticamente los eventos a medida que se producen, sin necesidad de realizar solicitudes repetidas. Cada mensaje es un StreamPage: un conjunto de eventos y un watermark.
{ "items": [ { "uuid": "550e8400-e29b-41d4-a716-446655440000", "action": "profiles.started", "time": 1707053400, "user_email": "user@example.com", "object_type": "profile", "object_id": "a1b2c3d4e5f67890abcdef1234567890", "object_title": "Octo Browser Profile", "data": { "connection_data": { "ip": "203.0.113.42", "countryCode": "FR", "countryName": "France", "subdivisions": ["Île-de-France", "Paris"], "postalCode": "75008", "cityName": "Paris", "timezone": "Europe/Paris", "lat": 48.8566, "lon": 2.3522, "languages": ["fr", "en-US", "en"], "isp": "Example Networks Ltd", "connectionType": "Cable/DSL" } } } ], "watermark": { "uuid": "550e8400-e29b-41d4-a716-446655440000", "time": 1707053400 } }
Actualmente, Action Log admite diez tipos de eventos:
profiles.started— el perfil se ha iniciado;profiles.stopped— el perfil se ha detenido;profiles.force_stopped— el perfil se ha detenido de forma forzada;profiles.transferred— el perfil se ha transferido a otro usuario;profiles.trashed— el perfil se ha movido a la papelera;
profiles.deleted — el perfil se ha eliminado;
profiles.updated— el perfil se ha modificado;profiles.proxy_assigned— se ha asignado un proxy al perfil;profiles.proxy_unassigned— se ha quitado el proxy del perfil;profiles.proxy_changed— se ha cambiado el proxy por otro.
Para evitar problemas cuando se interrumpe la conexión, cada mensaje incluye un watermark: el UUID y la hora del último evento. Al volver a conectarte, basta con pasar este UUID en el parámetro after_uuid: el flujo enviará todo lo que haya ocurrido durante la interrupción, sin perder ni duplicar eventos. Otra opción es comenzar desde un momento concreto mediante from_timestamp. La única limitación es que los eventos se conservan durante 24 horas: es un flujo de datos activo, no un archivo histórico.
Esto también funciona con operaciones masivas: si un empleado mueve 100 perfiles a la papelera de una vez, en el flujo aparecerán los 100 eventos, cada uno con su propio object_id; ninguno se perderá ni se duplicará.
Puedes obtener más información sobre el funcionamiento de Action Log en la documentación.
Qué contiene data: desglose por evento
El conjunto de campos dentro de data depende de action. Esto es lo que se recibe para cada uno de los diez tipos:
Evento | Contenido de |
|
|
|
|
|
|
|
|
|
|
|
|
| los mismos campos con los prefijos |
profiles.stopped
La duración de la sesión se recibe en formato ISO 8601, no como un número de segundos:
{ "action": "profiles.stopped", "data": { "run_duration": "PT19.627134S" } }
profiles.updated
Changeset no es una lista fija de campos, sino una diferencia dinámica: contiene únicamente lo que ha cambiado en esa ocasión. Por ejemplo, si se modifican varias opciones del perfil a la vez, se recibe lo siguiente:
{ "action": "profiles.updated", "data": { "changeset": { "description": { "old_value": "", "new_value": "Test action log" }, "start_pages": { "added": ["http://google.com", "http://facebook.com"], "removed": [] }, "storage_options": { "added": ["serviceworkers", "localstorage"], "removed": [] }, "bookmarks": { "added": ["https://ebay.com", "https://amazon.com"], "removed": [] }, "launch_args": { "added": ["--start-maximized"], "removed": [] }, "images_load_limit": { "old_value": null, "new_value": 10240 }, "local_cache": { "old_value": false, "new_value": true }, "fingerprint": {} } } }
Puedes observar dos patrones:
para valores individuales (
description,images_load_limit,local_cache), se incluye un parold_value/new_value;para listas (
start_pages,storage_options,bookmarks,launch_args), se incluyenadded/removed.
fingerprint es una excepción: la clave aparece cuando la huella realmente ha cambiado, pero siempre como un objeto vacío, sin detalles sobre qué ha cambiado en su interior. La regla general es sencilla: si un campo no ha cambiado, su clave no aparecerá en changeset.
profiles.deleted
{ "action": "profiles.deleted", "data": { "manual": true } }
profiles.proxy_changed
Compara el proxy antiguo y el nuevo en un único evento:
{ "action": "profiles.proxy_changed", "data": { "old_proxy_uuid": "370b0ce963194f68803a812dd42db4be", "old_proxy_title": "Netlabs GB England", "old_url": "socks5://user:pass@proxy.example.com:1080", "new_proxy_uuid": "9c51385c3e2b417d9b34fc305a49d4f6", "new_proxy_title": "Netlabs GB England Towcester", "new_url": "socks5://user:pass@proxy2.example.com:1080" } }
profiles.proxy_assigned y profiles.proxy_unassigned devuelven los mismos campos, pero sin los prefijos old_ / new_: un único conjunto de campos por evento, en lugar de una comparación.
El campo temporary merece una mención aparte: true significa que el proxy se ha introducido mediante una acción rápida (por ejemplo, pegando una línea), en lugar de asignarlo de la forma habitual desde la configuración del perfil.
profiles.trashed y eliminación automática
profiles.trashed llega con un data vacío, al igual que force_stopped. Si el perfil no se restaura ni se elimina manualmente, se eliminará automáticamente después de 72 horas. Más información en la documentación de la papelera.
profiles.transferred
Un único evento contiene ambas partes:
{ "action": "profiles.transferred", "user_email": "sender@example.com", "data": { "receiver": "receiver@example.com" } }
user_email: como en cualquier otro evento, es el correo del usuario que realizó la acción, es decir, el remitente de la transferencia.
data.receiver: el destinatario.
Conexión y reconexión
Puedes conectarte con cualquier cliente compatible con WebSocket.
En Node.js, sería así:
const WebSocket = require('ws'); const ws = new WebSocket('wss://app.octobrowser.net/api/v2/automation/ws/action_log', { headers: { 'X-Octo-Api-Token': 'Octo API Token' } }); ws.on('open', () => console.log('Connected!')); ws.on('message', (data) => { const parsed = JSON.parse(data.toString()); console.log(JSON.stringify(parsed, null, 2)); console.log(''); }); ws.on('error', (err) => console.log('Error:', err.message)); ws.on('close', () => console.log('Connection closed'));
Esto significa cada campo del evento recibido:
uuid — identificador del propio evento, no del perfil; es único para cada registro, incluso si se producen varios eventos en el mismo segundo;
action — tipo de acción de la lista anterior;
time — hora del evento en formato Unix;
user_email — correo del usuario que realizó la acción;
object_type — tipo de objeto al que corresponde el evento;
object_id — identificador del propio perfil, independiente del UUID del evento;
object_title — nombre del perfil en el momento del evento;
data — detalles que dependen de
action, descritos anteriormente.
Si se detiene un perfil, llegará un segundo evento, profiles.stopped, con un nuevo uuid, pero con el mismo object_id, ya que se trata del mismo perfil. Puedes utilizar object_id para vincular todos los eventos de un perfil en un único historial en tu sistema: object_id no cambia durante toda la vida del perfil, desde que se inicia hasta que se elimina.
Para continuar el flujo después de una interrupción de la conexión, basta con guardar el uuid del último watermark recibido y pasarlo en after_uuid:
const WebSocket = require('ws'); const ws = new WebSocket('wss://app.octobrowser.net/api/v2/automation/ws/action_log?after_uuid=UUID', { headers: { 'X-Octo-Api-Token': 'Octo API Token' } }); ws.on('open', () => console.log('Connected!')); ws.on('message', (data) => { const parsed = JSON.parse(data.toString()); console.log(JSON.stringify(parsed, null, 2)); console.log(''); }); ws.on('error', (err) => console.log('Error:', err.message)); ws.on('close', () => console.log('Connection closed'));
La conexión enviará inmediatamente los eventos que se hayan producido después de ese UUID y, a continuación, continuará funcionando como un flujo normal. Solo tendrás que volver a indicar after_uuid después de la siguiente interrupción.
Si no tienes un watermark guardado, por ejemplo, después de una interrupción prolongada en la que solo conoces aproximadamente el momento en que se produjo la desconexión, puedes comenzar desde un momento concreto mediante from_timestamp (tiempo Unix en segundos):
const WebSocket = require('ws'); const ws = new WebSocket('wss://app.octobrowser.net/api/v2/automation/ws/action_log?from_timestamp=TIMESTAMP', { headers: { 'X-Octo-Api-Token': 'Octo API Token' } }); ws.on('open', () => console.log('Connected!')); ws.on('message', (data) => { const parsed = JSON.parse(data.toString()); console.log(JSON.stringify(parsed, null, 2)); console.log(''); }); ws.on('error', (err) => console.log('Error:', err.message)); ws.on('close', () => console.log('Connection closed'));
Si estás empezando a trabajar con automatización, explicamos la API de Octo Browser con más detalle en un artículo aparte.
Conclusión
Action Log permite utilizar los eventos de Octo Browser como parte de tu propia infraestructura: enviarlos a un CRM, un sistema de control de acceso, una plataforma de analítica u otras herramientas internas. Octo informa de lo que ha ocurrido con el perfil y tú decides cómo procesar, guardar y utilizar esos datos.
Si tienes un caso de uso para Action Log, cuéntanoslo. Muchos de los eventos disponibles actualmente surgieron precisamente de las necesidades reales de equipos que trabajan con la API.
Mantente al día de las últimas noticias sobre Octo Browser
Al hacer clic en el botón, aceptas nuestra Política de privacidad.
Mantente al día de las últimas noticias sobre Octo Browser
Al hacer clic en el botón, aceptas nuestra Política de privacidad.
Mantente al día de las últimas noticias sobre Octo Browser
Al hacer clic en el botón, aceptas nuestra Política de privacidad.

Únete a Octo Browser ahora
O contacta al servicio al cliente en cualquier momento si tienes alguna pregunta.

Únete a Octo Browser ahora
O contacta al servicio al cliente en cualquier momento si tienes alguna pregunta.
Únete a Octo Browser ahora
O contacta al servicio al cliente en cualquier momento si tienes alguna pregunta.
