AttendBeacon
Abrir el espacio de trabajo

Conceptos

Paginación y sincronización

Las listas responden página a página con un cursor; updatedSince obtiene solo lo que ha cambiado desde tu última ejecución.

Páginas y cursores

Todas las listas responden igual: los elementos, el cursor de la página siguiente y si hay una.

JSON
{
  "data": [ { "sessionId": "b3ac0004-0000-4000-8000-000000000000", "title": "Registration and coffee" } ],
  "nextCursor": "YzE6MDYzOTI3NjEwODQ4MjgyMDAwMHxiM2Fj...",
  "hasMore": true
}

Devuelve nextCursor como cursor, con los mismos filtros, hasta que sea null. limit fija el tamaño de página: 100 por defecto y 500 como máximo. Un cursor es opaco: consérvalo tal como llegó y no construyas uno tú. Uno que no haya generado el servidor se rechaza con invalidCursor, en lugar de volver a empezar sin avisar.

Las listas tienen un orden fijo, primero el cambio más antiguo, con el id para desempatar, así que una página nunca se salta ni repite un elemento que no haya cambiado mientras lees. Un elemento que cambia mientras paginas pasa al final y lo vuelves a ver, que es justo lo que quiere una sincronización.

Las listas de asistentes, pedidos y registros de entrada también aceptan page y pageSize, como antes de que existieran los cursores. Siguen funcionando; es mejor usar el cursor, que nunca cuenta.

Sincronizar: solo lo que ha cambiado

Las listas de cosas que cambian indican cuándo cambió cada elemento por última vez, en updatedUtc, y aceptan updatedSince. Una sincronización guarda el updatedUtc más reciente que ha visto y pregunta desde ahí la próxima vez:

  1. Lee todas las páginas con updatedSince igual a lo que guardaste la última vez (nada la primera vez).
  2. Guarda o actualiza cada elemento por su id.
  3. Guarda el updatedUtc más reciente de la ejecución para la próxima vez.

updatedSince es inclusivo: un elemento que cambió en el mismo milisegundo que tu marca vuelve a llegar en lugar de perderse. Actualizar un elemento que ya tienes no hace daño; perder uno, sí.

const base = "https://attendbeacon.com/api/v1/events/b3ac0000-0000-4000-8000-000000000001/attendees";
const headers = { Authorization: `Bearer ${process.env.ATTENDBEACON_KEY}` };

let since = await loadMark();              // null on the first run
let newest = since;
let cursor = null;

do {
  const url = new URL(base);
  url.searchParams.set("limit", "500");
  if (since) url.searchParams.set("updatedSince", since);
  if (cursor) url.searchParams.set("cursor", cursor);

  const page = await fetch(url, { headers }).then((r) => r.json());
  for (const attendee of page.data) {
    await upsert(attendee);                // by attendee.attendeeId
    if (!newest || attendee.updatedUtc > newest) newest = attendee.updatedUtc;
  }
  cursor = page.nextCursor;
} while (cursor);

await saveMark(newest);

Las horas son ISO 8601 en UTC con tres decimales y una Z, así que también se comparan correctamente como texto.

Lo que no tiene hora de cambio

Las salas, los itinerarios, los ponentes, los patrocinadores y los niveles de patrocinio son listas pequeñas sin hora de cambio propia: léelas enteras, con el cursor si quieres. Sus recursos individuales y el propio evento responden con un ETag, así que si vuelves a preguntar con If-None-Match se responde 304 Not Modified, sin cuerpo, cuando nada ha cambiado.

Los registros de entrada nunca cambian una vez hechos: recórrelos por cursor, o por after, el último checkInId que tengas, que solo crece.

Eliminaciones y borrado de datos

Una entrada cancelada sigue en la lista con "status": "cancelled", así que una sincronización ve la cancelación. Cuando alguien elimina sus datos desde la app del evento, su asistente se queda con "erased": true y sin nada personal; el webhook attendee.erased te avisa de inmediato para que puedas eliminar tu propia copia. Consulta Privacidad y borrado de datos.

Webhooks o consultas periódicas

Consultar con updatedSince cada pocos minutos es sencillo y lo capta todo. Los webhooks te avisan en segundos. Muchas integraciones hacen las dos cosas: webhooks para la rapidez y una sincronización nocturna para estar seguros.

Las guías y este sitio están en tu idioma. Las descripciones de la referencia de la API están en inglés, el idioma de la propia API.