API выгрузки практики «Дзыня»
Этот 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,
когда ничего не изменилось (то есть почти всегда).
Ответы
| Код | Что значит |
|---|---|
| 200 | GET. Журнал. Тело — CSV, сильный ETag, имя вложения DingLogs-YYYY-MM-DD.csv. |
| 204 | POST, DELETE. Приняты. Тело пустое, повтор отвечает так же: включить дважды не ошибка, и был ли человек уже подписан, мы не говорим. |
| 304 | GET. Не менялось с присланного трекером 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
- Started At — местное время сессии,
MM/DD/YYYY HH:MM:SS, без зоны. Заморожено в той зоне, где сидка и случилась: переезд или ретрит не переписывает молча метки всей истории. - Duration —
H:M:S, без ведущих нулей. - Preset — название практики, которую выбрал человек. Имена тех, с кем он сидел, срезаются до того, как файл уйдёт с нашего сервера: у нас есть согласие этого человека, а не его партнёров.
- Activity — всегда
Meditation.
Заголовок и четыре колонки заморожены. Всё новое появляется внутри Preset.
Как человек это выключает
Либо выключает выгрузку у трекера, либо снимает галочку этого круга на экране «Вместе» в «Дзыне». Любое из двух останавливает и выдачу, и заливку с телефона. Что мы передаём и как это остановить — простыми словами в нашей политике конфиденциальности.
Вопросы
support.ding@gmail.com. Вопросы и возражения одинаково уместны. API новый, форма ещё открыта: если трекеру удобнее другая — лучше сделаем её.