AttendBeacon
Abrir a área de trabalho

Conceitos

Paginação e sincronização

As listas respondem uma página de cada vez com um cursor; updatedSince obtém apenas o que mudou desde a última execução.

Páginas e cursores

Todas as listas respondem da mesma forma: os itens, o cursor para a página seguinte e se ela existe.

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

Devolva nextCursor como cursor, com os mesmos filtros, até ser null. limit define o tamanho da página: 100 por predefinição e 500 no máximo. Um cursor é opaco: guarde-o tal como veio e não construa um por sua conta. Um cursor que o servidor não criou é recusado com invalidCursor, em vez de recomeçar silenciosamente.

As listas têm uma ordem fixa, a alteração mais antiga primeiro, com o id a desempatar, por isso uma página nunca salta nem repete um item que não mudou enquanto lê. Um item que muda enquanto pagina passa para o fim e volta a vê-lo, que é o que uma sincronização quer.

As listas de participantes, encomendas e registos de entrada também aceitam os page e pageSize que aceitavam antes de existirem cursores. Continuam a funcionar; prefira o cursor, que nunca conta.

Sincronizar: só o que mudou

As listas de coisas que mudam indicam quando cada item mudou pela última vez, em updatedUtc, e aceitam updatedSince. Uma sincronização guarda o updatedUtc mais recente que viu e pergunta a partir daí da vez seguinte:

  1. Leia todas as páginas com updatedSince definido para o que guardou da última vez (nada na primeira vez).
  2. Guarde ou atualize cada item pelo seu id.
  3. Guarde o updatedUtc mais recente da execução para a próxima vez.

updatedSince é inclusivo: um item alterado no mesmo milissegundo da sua marca volta a aparecer em vez de se perder. Atualizar um item que já tem não faz mal; perder um, sim.

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);

As horas são ISO 8601 em UTC com três casas decimais e um Z, por isso também se comparam corretamente como texto.

O que não tem hora de alteração

Salas, áreas temáticas, oradores, patrocinadores e níveis de patrocínio são listas pequenas sem hora de alteração própria: leia-as por inteiro, com o cursor se quiser. Os seus recursos individuais e o próprio evento respondem com um ETag, por isso perguntar de novo com If-None-Match responde 304 Not Modified, sem corpo, quando nada mudou.

Os registos de entrada nunca mudam depois de feitos: percorra-os por cursor, ou por after, o último checkInId que tem, que só aumenta.

Cancelamentos e eliminação

Um bilhete cancelado continua na lista com "status": "cancelled", para que uma sincronização veja o cancelamento. Quando alguém elimina os seus dados na app do evento, o seu participante mantém-se com "erased": true e sem nada pessoal; o webhook attendee.erased avisa-o de imediato, para que possa eliminar a sua própria cópia. Consulte Privacidade e eliminação.

Webhooks ou consultas periódicas

Consultar com updatedSince a cada poucos minutos é simples e apanha tudo. Os webhooks avisam em segundos. Muitas integrações fazem as duas coisas: webhooks pela rapidez, uma sincronização noturna por segurança.

Os guias e este site estão no seu idioma. As descrições da própria referência da API estão em inglês, tal como a própria API.