Serverless-перенос hifi-api и его control agent на Cloudflare Workers.
Публичные Tidal-маршруты работают в одном TypeScript Worker, а профили
учётных данных управляются через Agent API и хранятся в Cloudflare KV в
зашифрованном виде.
Используйте проект только с собственной действующей подпиской и в соответствии с правилами Tidal и законодательством вашей страны. Не публикуйте API без авторизации.
- Все публичные маршруты исходного API:
/info/,/track/,/trackManifests/,/widevine,/recommendations/,/search/,/album/,/mix/,/playlist/,/artist/similar/,/album/similar/,/artist/,/cover/,/lyrics/,/topvideos/,/video/. - OAuth refresh, повтор после
401, ограниченные повторы после429и fallback/track/наtrackManifestsпосле403. - Agent API для загрузки токенов, метаданных, health-check и audit log.
- Несколько логических экземпляров и несколько credential в одном экземпляре.
- AES-256-GCM шифрование credential payload перед записью в KV.
- Единый статический ключ
spoti123для Public API и Agent API, CORS, безопасные ошибки и request ID.
Docker socket, локальные файлы, SOCKS/HTTP proxy и перезапуск контейнеров в
Workers недоступны. Совместимый POST /instances/:id/restart теперь очищает
access-token cache и заставляет следующий запрос обновить OAuth token.
Нужны Node.js 20+ и Cloudflare account.
npm ci
npx wrangler login
npm run generate:secretСкопируйте сгенерированную строку и задайте secret шифрования:
npx wrangler secret put TOKEN_ENCRYPTION_KEYAGENT_API_KEY и PUBLIC_API_KEY уже заданы в wrangler.jsonc одинаковым
статическим значением spoti123.
Проверьте и разверните:
npm run check
npm run deploywrangler.jsonc содержит draft KV binding без ID. Актуальный Wrangler при
первом deploy автоматически создаст namespace и запишет его ID в конфиг.
После deploy загрузите существующий token.json:
export WORKER_URL="https://tidal-workers.<account>.workers.dev"
export AGENT_API_KEY="spoti123"
curl -X POST \
-H "X-Agent-Key: ${AGENT_API_KEY}" \
-F "token_file=@./token.json;type=application/json" \
-F "token_name=Main Tidal account" \
"${WORKER_URL}/instances/main/token"Или JSON-запросом:
curl -X POST \
-H "X-Agent-Key: ${AGENT_API_KEY}" \
-H "Content-Type: application/json" \
--data '{
"token_name": "Main Tidal account",
"token": {
"client_ID": "client-id",
"client_secret": "client-secret",
"refresh_token": "refresh-token",
"userID": "user-id"
}
}' \
"${WORKER_URL}/instances/main/token"Проверьте:
curl -H "X-Agent-Key: ${AGENT_API_KEY}" \
"${WORKER_URL}/agent/health"
curl "${WORKER_URL}/health/?check_upstream=true"Для public data routes передавайте spoti123 в X-API-Key или
Authorization: Bearer .... Корневой маршрут и /health/ оставлены без ключа
для probes.
cp .dev.vars.example .dev.vars
npm run dev.dev.vars игнорируется Git. Для bootstrap без Agent API можно положить JSON
массива credential в secret TIDAL_BOOTSTRAP_CREDENTIALS; legacy secrets
CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, USER_ID тоже поддерживаются.
npm run dev
npm run typecheck
npm test
npm run check
npm run deploy
npm run tailПодробности:
- KV имеет eventual consistency: после записи токена другие Cloudflare locations могут увидеть обновление с задержкой примерно до 60 секунд.
spoti123опубликован в репозитории и является статическим идентификатором, а не настоящим секретом. Для реального ограничения доступа замените оба значения вwrangler.jsoncили перенесите их в Cloudflare secrets.- Не меняйте
TOKEN_ENCRYPTION_KEYпри существующих записях: старые записи перестанут расшифровываться. Для ротации сохраните исходные token-файлы, очистите/пересоздайте KV и загрузите их снова с новым ключом. - Полная агрегация
/artist/?f=...по умолчанию загружает треки максимум для 40 релизов, чтобы укладываться в 50 subrequest’ов Workers Free. - Настоящие runtime logs находятся в Cloudflare Workers Logs или доступны
через
npm run tail;/instances/:id/logsвозвращает только audit операций агента.
MIT. Проект сохраняет лицензию исходной реализации.