API выгрузки практики «Дзыня»

Обновлено 15 сентября 2026

Этот API позволяет трекеру сообщества (дальше — трекеру) читать журнал практики участника «Дзыня» напрямую. Журнал отдаётся как CSV, совместимый с форматом Insight Timer: три HTTP-запроса и только те люди, кто включил выгрузку.

Как получить ключ

Напишите на support.ding@gmail.com: ID Discord-сервера и кто ведёт трекер. Ключ выдаётся под этот сервер. Трекер передаёт его заголовком Bearer, никогда в адресе запроса — мы его не логируем.

Три запроса

Базовый адрес https://syntony.is/ding. {guild_id} — Discord-сервер трекера, {user_id} — Discord ID участника. У всех трёх — Authorization: Bearer КЛЮЧ.

POST   /exports/{guild_id}/{user_id}            → 204   человек включил выгрузку у трекера
GET    /exports/{guild_id}/{user_id}/practice   → 200   сам CSV
DELETE /exports/{guild_id}/{user_id}            → 204   человек выключил

Ключ в $KEY:

# 1. ВКЛЮЧИТЬ (Enable) — человек включил выгрузку у вас.
#    До этого запроса всё, что ниже, отвечает 404, и телефон ничего не заливает.
#    -> 204, тело пустое. Повторять безопасно: включить дважды не ошибка.
curl -i -X POST -H "Authorization: Bearer $KEY" \
  https://syntony.is/ding/exports/{guild_id}/{user_id}

# 2a. ЗАБРАТЬ (Sync now и дальше по своему расписанию) — всю историю целиком, каждый раз.
#     -> 200: CSV в DingLogs.csv, заголовки вместе с ETag — в headers.txt.
#     -> 404, пока телефон ещё не залил: после шага 1 это нормально минуты и дни.
curl -sD headers.txt -o DingLogs.csv -H "Authorization: Bearer $KEY" \
  https://syntony.is/ding/exports/{guild_id}/{user_id}/practice

# 2b. ЗАБРАТЬ, КОГДА УЖЕ ЗАБИРАЛ — тот же запрос плюс один заголовок. Необязательно и
#     дёшево: файл меняется только после сидки, большинству опросов отдавать нечего.
#     -> 304 с пустым телом, если ничего не менялось; 200 со всем файлом, если менялось.
ETAG=$(awk 'tolower($1)=="etag:"{print $2}' headers.txt | tr -d '\r')
curl -i -H "Authorization: Bearer $KEY" -H "If-None-Match: $ETAG" \
  https://syntony.is/ding/exports/{guild_id}/{user_id}/practice

# 3. ВЫКЛЮЧИТЬ (Disable) — человек выключил выгрузку у вас.
#    -> 204. Если других трекеров у него не включено, мы заодно стираем файл:
#    держать практику, которую больше некому забрать, незачем.
curl -i -X DELETE -H "Authorization: Bearer $KEY" \
  https://syntony.is/ding/exports/{guild_id}/{user_id}

POST отвечает 404 так же охотно, как GET, и на первом подключении это самый вероятный ответ: человеку нужно ещё отметить ваш круг в «Дзыне», на экране «Вместе». Согласие спрашивается в двух местах намеренно — у трекера и в приложении, — и этот 404 единственное, что стоит передать человеку обратно: открыть «Дзынь» → «Вместе» → отметить круг.

Сервер видит не всю практику: полный журнал есть только на телефоне участника. Поэтому файл приходит с телефона — он уходит наверх, когда «Дзынь» в следующий раз открыт и в сети, и первый может прийти и через минуты, и через дни после POST.

POST и DELETE идемпотентны. Пока не вызван POST, GET отвечает 404 даже по человеку, который сидит в «Дзыне» каждый день: нет согласия — нет данных, и телефон тоже ничего не заливает. У GET нет побочных эффектов — его безопасно звать по расписанию и повторно; достаточно вернуть прошлый ETag в If-None-Match, и в ответ придёт 304, когда ничего не изменилось (то есть почти всегда).

Ответы

КодЧто значит
200GET. Журнал. Тело — CSV, сильный ETag, имя вложения DingLogs-YYYY-MM-DD.csv.
204POST, DELETE. Приняты. Тело пустое, повтор отвечает так же: включить дважды не ошибка, и был ли человек уже подписан, мы не говорим.
304GET. Не менялось с присланного трекером ETag.
404Все три. Для этого трекера тут ничего нет — намеренно единый ответ на все причины: человека не знаем, выгрузка не включена, круг снят в приложении, ничего ещё не залито, кривой ID. Мы не рассказываем ключу, кто наши пользователи.
429Все три. Больше 120 запросов в минуту на ключ трекера. Retry-After говорит, когда вернуться.
401Все три. Ключ не распознан.

Файл

Строка заголовка и по строке на сессию, новые сверху.

Started At,Duration,Preset,Activity
06/22/2026 07:13:26,1:0:0,Утро,Meditation
06/21/2026 08:30:00,0:12:5,Вместе,Meditation

Заголовок и четыре колонки заморожены. Всё новое появляется внутри Preset.

Как человек это выключает

Либо выключает выгрузку у трекера, либо снимает галочку этого круга на экране «Вместе» в «Дзыне». Любое из двух останавливает и выдачу, и заливку с телефона. Что мы передаём и как это остановить — простыми словами в нашей политике конфиденциальности.

Вопросы

support.ding@gmail.com. Вопросы и возражения одинаково уместны. API новый, форма ещё открыта: если трекеру удобнее другая — лучше сделаем её.