Постраничный вывод
Списки — тикеты, клиенты, статьи, сообщения, доставки — приходят страницами. Следующая страница — по курсору из ответа, а не по номеру.
Страница списка
{
"data": [ { "id": "…", "number": "T-1042" }, { "id": "…", "number": "T-1041" } ],
"next_cursor": "WyIyMDI2LTEwLTIxVDA5OjE1OjA0LjIxODQ1MyswMDowMCIsIjBiOGY2YzFlLTVkMmEtNGM3Yi05YTMxLTZlMmY3ZDRjOWExMCJd"
}Как листать
Первый запрос — без курсора, с нужным
limit: от 1 до 100, по умолчанию 50.Есть
next_cursor— передайте его как есть в параметреcursorследующего запроса, с теми же фильтрами.next_cursor: null— страниц больше нет.
curl "https://app.deskus.ru/api/v1/tickets?status=open&limit=100&cursor=WyIyMDI2LTEw…" \
-H "Authorization: Bearer $DESKUS_KEY"Все тикеты, Node.js 18+
async function* allTickets(query = "") {
let cursor = null;
do {
const url = new URL("https://app.deskus.ru/api/v1/tickets");
url.search = query;
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("cursor", cursor);
const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.DESKUS_KEY}` } });
if (!res.ok) throw new Error((await res.json()).error.message);
const page = await res.json();
yield* page.data;
cursor = page.next_cursor;
} while (cursor);
}Полезно знать
Курсор — непрозрачная строка: не разбирайте и не собирайте её сами, формат может меняться.
Курсор держит место по времени и id последней строки, поэтому новые тикеты во время обхода не сдвигают страницы: строки не теряются и не повторяются.
Порядок: тикеты, клиенты, статьи и доставки — новые сверху; сообщения тикета — по порядку, старые сверху.
Битый курсор —
400 bad_request.limitбольше 100 урезается до 100, ноль и дробь —400.Для синхронизации берите фильтр
updated_sinceу тикетов илиcreated_sinceу клиентов и запоминайте время последнего прохода.
