AttendBeacon
Öppna arbetsytan

Begrepp

Sidindelning och synkronisering

Listor svarar en sida i taget med en markör; updatedSince hämtar bara det som har ändrats sedan din senaste körning.

Sidor och markörer

Varje lista svarar på samma sätt: posterna, markören för nästa sida och om det finns en.

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

Skicka tillbaka nextCursor som cursor, med samma filter, tills den är null. limit anger sidstorleken, 100 som standard och högst 500. En markör är ogenomskinlig: behåll den som den kom och bygg aldrig en själv. En markör som servern inte har skapat avvisas med invalidCursor i stället för att i tysthet börja om.

Listorna har en fast ordning, den äldsta ändringen först, med id:t som avgör vid lika, så en sida hoppar aldrig över eller upprepar en post som inte ändrades medan du läste. En post som ändras medan du bläddrar flyttas till slutet och du ser den igen, vilket är precis vad en synkronisering vill.

Listorna över deltagare, beställningar och incheckningar tar också page och pageSize, som de tog innan markörerna fanns. De fungerar fortfarande; använd hellre markören, som aldrig räknar.

Synkronisera: bara det som har ändrats

Listor med saker som ändras anger när varje post senast ändrades, i updatedUtc, och tar updatedSince. En synkronisering sparar det senaste updatedUtc den såg och frågar därifrån nästa gång:

  1. Läs varje sida med updatedSince satt till det du sparade förra gången (inget första gången).
  2. Spara eller uppdatera varje post utifrån dess id.
  3. Spara körningens senaste updatedUtc till nästa gång.

updatedSince är inkluderande: en post som ändrades under samma millisekund som ditt märke kommer igen i stället för att missas. Att uppdatera en post du redan har är ofarligt; att missa en är det inte.

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

Tider anges i ISO 8601 i UTC med tre decimaler och ett Z, så de jämförs också korrekt som text.

Det som saknar ändringstid

Rum, spår, talare, sponsorer och sponsornivåer är små listor utan egen ändringstid: läs dem i sin helhet, gärna med markören. Deras enskilda resurser och själva evenemanget svarar med en ETag, så om du frågar igen med If-None-Match blir svaret 304 Not Modified, utan brödtext, när inget har ändrats.

Incheckningar ändras aldrig när de väl har gjorts: bläddra igenom dem med cursor, eller med after, det senaste checkInId du har, som bara växer.

Borttagningar och radering

En avbokad biljett ligger kvar i listan med "status": "cancelled", så att en synkronisering ser avbokningen. När någon raderar sina uppgifter i evenemangsappen ligger deltagaren kvar med "erased": true och inget personligt; webhooken attendee.erased meddelar dig direkt, så att du kan radera din egen kopia. Se Integritet och radering.

Webhooks eller att fråga

Att fråga med updatedSince med några minuters mellanrum är enkelt och fångar allt. Webhooks meddelar dig inom några sekunder. Många integrationer gör båda: webhooks för snabbheten, en nattlig synkronisering för säkerhets skull.

Guiderna och den här webbplatsen finns på ditt språk. API-referensens egna beskrivningar är på engelska, precis som API:t självt.