Compare commits

..
361 Commits
Author SHA1 Message Date
MoeFurina 4a91f77e62 ci: fix pnpm has no pnpm-workspace.yaml 2026-08-18 20:18:41 +08:00
MoeFurina a7437f7ca4 feat: 更新歌曲相关接口 2026-08-18 20:11:30 +08:00
Takanashi Hoshino 498945c401 Merge pull request #241 from 1254qwer/fix/song-url-v1
fix: 支持获取臻音全景声
2026-08-18 19:30:02 +08:00
MoeFurina 7b17a08628 docs: 补全私人漫游模式文档内容 2026-08-18 19:23:30 +08:00
1254qwer 0b5c3927c9 fix: /song/url/v1/302 & /song/download/url/v1 支持臻音全景声 2026-08-17 09:15:51 +08:00
1254qwer 881267c56d fix: /song/url/v1 支持臻音全景声 2026-08-16 19:08:38 +08:00
MoeFurina d7c0db9455 fix: 错误的docker配置 2026-08-09 11:36:53 +08:00
Takanashi Hoshino c1d14a86d9 Merge pull request #237 from NeteaseCloudMusicApiEnhanced/fix/yidun
refactor: 重写checkToken V2模块
2026-08-09 11:21:39 +08:00
MoeFurina a2a2a40d71 fixes 2026-08-07 13:45:01 +08:00
MoeFurina 543660fcdf fix: pkg打包node18兼容 2026-08-07 12:13:43 +08:00
MoeFurina 98a95002b2 fix: node18兼容 2026-08-07 12:01:11 +08:00
MoeFurina c4a3d83abe refactor: 重写checkToken V2模块 2026-08-07 11:52:54 +08:00
Takanashi Hoshino 7753b5de41 Merge pull request #235 from NeteaseCloudMusicApiEnhanced/feat/yunbei_task
feat: 新增云贝任务相关接口
2026-08-06 16:58:07 +08:00
MoeFurina c1fe1eb925 Merge branch 'pr/235' 2026-08-06 16:55:27 +08:00
MoeFurina 3357317a1d upd 2026-08-06 16:51:51 +08:00
MoeFurina a08f425ae7 Merge branch 'main' into feat/yunbei_task 2026-08-06 16:45:11 +08:00
MoeFurina 5b780addba ci: test ci with the workflow file 2026-08-05 20:44:21 +08:00
MoeFurina fc9f41839c ci: test ci with workflow file 2026-08-05 19:44:08 +08:00
MoeFurina 5859944563 format docs 2026-08-05 18:31:49 +08:00
MoeFurina aaa6459e55 remove disclaimer 2026-08-05 18:13:14 +08:00
MoeFurina a898e1d86c feat: 新增云贝任务相关接口 2026-08-05 18:11:31 +08:00
MoeFurina 4045f1ad3f Merge branch 'pr/227' 2026-08-02 16:40:25 +08:00
MoeFurina e6214a3f73 Merge branch 'pr/229' 2026-08-02 16:39:14 +08:00
MoeFurina 686e8bf969 revert: revert some changes 2026-08-02 16:37:46 +08:00
anupamme 9214cb945f fix: V-001 security vulnerability
Automated security fix generated by OrbisAI Security
2026-08-02 08:35:02 +00:00
MoeFurina a79a2d9ef6 fix: 修正workflow文件 2026-08-02 16:19:40 +08:00
7788dev 9608da9b96 fix(voice): load created podcasts in upload example 2026-08-02 12:52:25 +08:00
7788dev 93b3e624d8 feat(voice): support cover image uploads 2026-08-02 11:53:51 +08:00
MoeFurina 15f515c1ba ci(test): test ci with the workflow file 2026-08-02 11:27:45 +08:00
anupamme e255e8f334 fix: V-001 security vulnerability
Automated security fix generated by OrbisAI Security
2026-08-02 03:16:22 +00:00
MoeFurina 16aa61f98e ci(test): test ci workflow file 2026-08-02 11:00:13 +08:00
MoeFurina a939003b92 ci(test): test ci workflow file 2026-08-02 10:46:19 +08:00
MoeFurina 8f4873f2e2 perf: 更新接口定义 2026-08-01 19:11:37 +08:00
MoeFurina a8b45a8b8b Merge branch 'pr/225' 2026-08-01 17:34:54 +08:00
MoeFurina 1a70281c76 ci: 更新问题管理工作流 2026-08-01 17:20:19 +08:00
tanjuntao f5f4ff6eda feat: add complete current-user event listing 2026-08-01 10:25:00 +08:00
tanjuntao eb1b5ba0ea feat: add event privacy endpoint 2026-08-01 10:25:00 +08:00
MoeFurina 6732fc7c32 ci(test): test ci workflow file 2026-07-31 22:21:34 +08:00
MoeFurina 6ce6b84015 fix: 修复分享笔记接口 2026-07-26 22:39:58 +08:00
MoeFurina 63d89aa906 bump 4.39.0 2026-07-24 17:20:38 +08:00
MoeFurina 8c212be86b docs: 删减合并冲突出现的问题 2026-07-24 17:17:23 +08:00
MoeFurina 89de56d2a2 Merge pull request #215 from ZxwyWebSite/feat-lottery 2026-07-24 17:13:54 +08:00
MoeFurina d298025d7c Merge branch 'pr/215' 2026-07-24 17:12:50 +08:00
MoeFurina a3287a0180 Merge branch 'feat-lottery' of https://github.com/ZxwyWebSite/api-enhanced into pr/215 2026-07-24 17:11:34 +08:00
MoeFurina 9adfd50c58 Merge pull request #215 from ZxwyWebSite/feat-lottery 2026-07-24 17:08:42 +08:00
MoeFurina fda7c9e5b3 Merge branch 'pr/215' 2026-07-24 16:55:29 +08:00
MoeFurina a8266c6d7b feat: 显示器显示剩余时长 2026-07-24 16:48:53 +08:00
Zxwy 64a6b9677a feat: 新增云小编抽奖接口 2026-07-23 11:14:35 +08:00
MoeFurina 20d3a1a7a5 feat: 新增获取免费听市场状态 2026-07-22 20:07:08 +08:00
MoeFurina 4826c65042 feat: weapi支持checkToken 2026-07-22 19:40:12 +08:00
MoeFurina 7822ab08d3 feat: 新增评论相关接口 2026-07-22 19:18:18 +08:00
Takanashi Hoshino 41bd6d82ce Merge pull request #216 from Suxiaoqinx/main
feat(song/url-v1): 新增immerseType参数支持并更新文档
2026-07-19 21:20:40 +08:00
苏晓晴 6f8dd1d971 删除 package-lock.json 2026-07-19 17:45:39 +08:00
Suxiaoqinx ddd0af5474 修复(song_url_v1): 删除非sky等级的immerseType处理逻辑
移除原代码中非sky等级下处理query.immerseType的代码分支,仅在level为sky时设置immerseType参数
2026-07-19 10:04:08 +08:00
Suxiaoqinx fbd2e06419 feat(song/url-v1): 新增immerseType参数支持并更新文档
补充sky音质下immerseType参数的处理逻辑,更新文档说明与调用示例,注明参数仅在level为sky时生效
2026-07-19 09:54:55 +08:00
Zxwy 4442fb4341 feat: 新增云小编抽奖接口 2026-07-18 15:25:15 +08:00
MoeFurina 35d1c61cb4 revert: some changes 2026-07-17 20:41:49 +08:00
MoeFurina a183e153ef Merge branch 'pr/214' 2026-07-17 20:11:37 +08:00
MoeFurina 2fa78c3826 fix: 修复评论接口 2026-07-17 20:11:20 +08:00
Zxwy 5ae1eab14c feat: 新增云小编接口 2026-07-17 19:02:16 +08:00
MoeFurina 321c25bd7d style: 简化createOption 2026-07-15 21:06:50 +08:00
MoeFurina f527c1ef73 docs: 新增免费听接口文档 2026-07-15 16:23:25 +08:00
MoeFurina 0a5a1242f2 feat: 新增免费听接口 2026-07-15 16:14:19 +08:00
MoeFurina 6946dc8e14 docs: 修改运行要求 2026-07-12 10:42:50 +08:00
MoeFurina 22b78779ca Merge branch 'main' of https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced 2026-07-11 17:20:25 +08:00
MoeFurina 35607f5050 perf: 改进api调试页面 2026-07-11 17:20:14 +08:00
Takanashi Hoshino 60af95ac06 Merge pull request #210 from laoshuikaixue/feature/artist-new-song-playall
feat(artist): 添加关注歌手新歌播放全部&新作品接口
2026-07-11 17:04:55 +08:00
LaoShui 46073e5f50 docs(docs): 更新 sourceType 参数说明
- 明确 `1` 表示新歌,其他取值待确认
- 添加默认值 `1` 的标注
2026-07-10 23:07:31 +08:00
LaoShui bf12abe2f1 feat(artist): 添加关注歌手新作品(歌曲/MV)接口
- 新增 module/artist_new_song_mv_list_v2.js 模块实现接口逻辑
- 在文档中添加接口说明、参数详情和调用示例
- 在 TypeScript 定义文件中添加对应的接口类型声明
- 支持分页获取关注歌手的新歌曲和 MV 列表
- 实现时间游标和翻页功能支持
- 提供多种可选参数配置选项
2026-07-10 19:20:54 +08:00
LaoShui 1491b91829 feat(artist): 添加关注歌手新歌播放全部功能
- 新增 module/artist_new_song_playall.js 文件实现获取所有关注歌手最近50首新歌的功能
- 在文档中添加关注歌手最近新歌播放全部接口说明和调用示例
- 在类型定义文件中添加 artist_new_song_playall 函数声明
2026-07-10 18:56:50 +08:00
MoeFurina 63f669d7f8 fix: 黑胶乐签签到失败 (#197) 2026-06-30 14:34:58 +08:00
Furina's Little Ocean Act Theater d525204dda Merge pull request #199 from zhuixingzhe-baisheng/add-vip-growthpoint-getall
feat: add vip_growthpoint_getall - one-click claim all VIP growth rew…
2026-06-29 16:14:42 +08:00
Furina's Little Ocean Act Theater 6eb31984fd Merge pull request #200 from floatwoozy/feat/listen-data-song-play-rank
feat: 新增 listen_data_song_play_rank 歌曲播放排行接口
2026-06-29 16:14:11 +08:00
MoeFurina 9faeb0aa25 docs: 删减文档内容 2026-06-29 15:53:01 +08:00
floatwoozy f6db3e76e9 feat: 新增 listen_data_song_play_rank 歌曲播放排行接口
新增 /api/content/activity/listen/data/song/play/rank,返回某周/月
听歌排行(每首带 playCount),默认 Top20、不足则返回全部。与已有的
listen_data_today_song(今日)同族,补全「带次数的历史周/月榜」。

- module/listen_data_song_play_rank.js:type(week|month) + endTime 参数
- interface.d.ts:补类型声明
- public/docs/home.md:补接口文档
2026-06-25 03:25:20 +08:00
MonkeyCode Agent 9163d48f0a feat: add vip_growthpoint_getall - one-click claim all VIP growth rewards (xeapi)
- New module: module/vip_growthpoint_getall.js
- Uses xeapi encryption for direct  endpoint
- No parameters required, claims all completed task rewards at once
- Added TypeScript type declaration in interface.d.ts
- Added API documentation in public/docs/home.md
2026-06-21 05:24:35 +00:00
MoeFurina 1454ee216c fix: 请求异常 (83ee2cda34) 2026-06-20 23:28:08 +08:00
MoeFurina 83ee2cda34 feat: add NCBL encrypted scrobble interface and update related documentation
- Implemented new scrobble endpoint for NCBL encrypted logs in `scrobble_v1.js`.
- Updated `scrobble.js` to use domain from config.
- Enhanced `scrobble.html` with tabbed interface for original and NCBL versions, including new input fields.
- Added cookie handling and quick fill functionality for both versions.
- Updated `config.json` to include new domain configurations.
- Introduced `ncbl.js` for NCBL encryption utilities.
- Improved documentation in `home.md` to reflect changes in API usage.
2026-06-20 22:51:51 +08:00
MoeFurina 3c352b5752 feat: 新增听歌打卡示例页面 2026-06-20 21:16:14 +08:00
MoeFurina 60ee927e32 fix: 修复听歌打卡接口 (#167) 2026-06-19 15:11:31 +08:00
MoeFurina eb07a525eb feat: 支持显示加密方式 2026-06-18 23:46:11 +08:00
MoeFurina 6fc4231142 feat(docs-format): 增加文档格式化工具 2026-06-18 23:05:44 +08:00
MoeFurina fa69736300 revert: some changes
This reverts commit c959866436.
2026-06-18 22:52:35 +08:00
MoeFurina 73a5e9d788 Revert "feat: 增加文档格式化工具"
This reverts commit 6550c7c827.
2026-06-18 22:51:34 +08:00
MoeFurina dc6f56e8a8 Revert "fix(deploy): 修复部分启动失败 (#196)"
This reverts commit 395a80e74b.
2026-06-18 22:50:53 +08:00
MoeFurina 2c9da8507d Revert "refactor: 优化serverless入口文件"
This reverts commit 1db354464f.
2026-06-18 22:50:51 +08:00
MoeFurina 1db354464f refactor: 优化serverless入口文件 2026-06-18 22:29:24 +08:00
MoeFurina 395a80e74b fix(deploy): 修复部分启动失败 (#196) 2026-06-18 21:00:06 +08:00
MoeFurina 6550c7c827 feat: 增加文档格式化工具 2026-06-13 23:49:30 +08:00
MoeFurina c959866436 feat: 增强配置生成逻辑,添加重试机制和日志记录 2026-06-13 21:21:33 +08:00
MoeFurina e3a1c041b6 fix: 修复游客登陆接口 2026-06-09 00:09:48 +08:00
MoeFurina e2324e26da Merge remote-tracking branch 'origin/dependabot/github_actions/docker/login-action-4' 2026-06-09 00:09:09 +08:00
MoeFurina f01e770c35 Merge remote-tracking branch 'origin/dependabot/npm_and_yarn/types/node-25.9.1' 2026-06-09 00:08:41 +08:00
MoeFurina abb56ec014 Merge remote-tracking branch 'origin/dependabot/github_actions/aormsby/Fork-Sync-With-Upstream-action-3.4.3' 2026-06-09 00:08:23 +08:00
dependabot[bot] 0300c1b51e build(packages): bump @types/node from 25.5.0 to 25.9.2
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.5.0 to 25.9.2.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 25.9.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-06 07:42:44 +00:00
MoeFurina 9896242333 bump 4.35.0 2026-06-06 15:40:08 +08:00
MoEFusion e3812be97b Merge pull request #182 from zhuixingzhe-baisheng/feat/add-relay-play-state-submit
feat: add relay_play_state_submit API for song play state tracking
2026-06-06 15:36:27 +08:00
MoeFurina e7ff0da4ba refactor: 自动生成sessionID 2026-06-06 15:33:15 +08:00
MoeFurina 65261fa658 Merge branch 'main' into pr/182 2026-06-06 15:23:37 +08:00
MoEFusionandgemini-code-assist[bot] cb5b2e7d0f Apply suggestions from code review
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-06-06 15:22:25 +08:00
MoeFurina f58fd4b50d feat: 新增云盘歌曲下载链接接口 (1a5f91a192) 2026-06-06 15:20:06 +08:00
MoeFurina 1a5f91a192 feat: 新增从云盘获取歌曲下载链接接口 2026-06-06 15:17:28 +08:00
MoeFurina 50cc26f297 feat: 为xeapi重构相关接口以优化密钥获取流程 2026-06-06 14:52:33 +08:00
MoeFurina c92613b19e fix: 更新GitHub Actions和Dockerfile中的依赖版本 2026-05-30 20:58:03 +08:00
MoeFurina 7aacc8990b feat: 新增和改进黑胶乐签相关接口 2026-05-30 20:45:24 +08:00
MoeFurina 8e934789a1 ci: 修复Dockerfile的错误配置 2026-05-30 20:17:22 +08:00
MoeFurina d26e6b0615 feat: 新增新版会员任务接口 (#173) 2026-05-30 20:02:00 +08:00
dependabot[bot] a9c33de182 chore(deps): bump docker/login-action from 3 to 4
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-30 10:24:02 +00:00
MoeFurina d0935f6e42 feat: add xeapi support and refactor eapi_decrypt to api_decrypt
- Added xeapi option to the API selection dropdown in api.html.
- Removed eapi_decrypt.html and created a new api_decrypt.html for unified API decryption.
- Implemented multi-crypto support in api_decrypt.html with corresponding UI changes.
- Created decrypt.js module to handle decryption logic for different crypto types including xeapi.
- Updated request.js to remove unnecessary debug logs and improve code clarity.
- Updated index.html to link to the new api_decrypt.html instead of the removed eapi_decrypt.html.
2026-05-30 00:17:24 +08:00
MoeFurina 3e0337ab94 Merge branch 'pr/186' 2026-05-30 00:14:39 +08:00
LuoRain 5cf43c48ef fix: wrong unit for yrc 2026-05-30 00:03:27 +08:00
MoeFurina 68567f4a14 perf: 更新Bug报告模板和配置 2026-05-29 23:24:24 +08:00
MoEFusion d0d71bb4f9 Merge pull request #183 from 1254qwer/feat/xeapi-crypto
feat: 新增 xeapi 算法支持
2026-05-29 22:49:37 +08:00
MoeFurina ec7eff1697 Merge branch 'pr/183' 2026-05-29 22:46:26 +08:00
MoeFurina 1882c3c31e fix workflows 2026-05-29 22:17:16 +08:00
1254qwer f21f5677e8 feat: Add xeapi crypto support 2026-05-29 21:56:27 +08:00
MoeFurina fc5a76d5e2 Merge branch 'main' into main 2026-05-29 21:54:27 +08:00
MoeFurina fbc34a1846 Merge branch 'pr/178' 2026-05-29 21:53:29 +08:00
MoeFurina 3ef5ea341b Merge branch 'pr/179' 2026-05-29 21:53:11 +08:00
MoeFurina 4195c41171 bump 4.33.1 2026-05-29 21:49:21 +08:00
MoeFurina 232cc3d916 Squashed commit of the following:
commit 01d391ac91
Author: Sunset Mikoto <26019675+SunsetMkt@users.noreply.github.com>
Date:   Mon May 25 13:05:14 2026 +0800

    Update util/option.js

    Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

commit 85d70ba9dd
Author: Sunset Mikoto <26019675+SunsetMkt@users.noreply.github.com>
Date:   Mon May 25 12:56:34 2026 +0800

    Update util/option.js

    Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

commit 3cfecbcc1f
Author: Sunset Mikoto <26019675+SunsetMkt@users.noreply.github.com>
Date:   Mon May 25 12:51:29 2026 +0800

    Update util/option.js

    Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

commit c6e9746ed6
Author: Sunset Mikoto <26019675+SunsetMkt@users.noreply.github.com>
Date:   Mon May 25 01:47:53 2026 +0000

    fix: 修正为原始逻辑,简化代码

commit d6961ecb4d
Author: Sunset Mikoto <26019675+SunsetMkt@users.noreply.github.com>
Date:   Sun May 24 18:11:35 2026 +0000

    feat: 当ENABLE_RANDOM_CN_IP为true时,除非请求参数randomCNIP显式为false,默认开启randomCNIP
2026-05-29 17:20:07 +08:00
MoeFurina 1b4af30a49 Squashed commit of the following:
commit 02242eecf6
Author: Sunset Mikoto <26019675+SunsetMkt@users.noreply.github.com>
Date:   Sun May 24 18:00:36 2026 +0000

    fix: randomCNIP 不工作
2026-05-29 17:19:41 +08:00
Developer 39e0e0718d feat: add relay_play_state_submit API for song play state tracking
- Add new interface /api/relay/play/state/submit
- Support sessionId tracking for play sessions
- Support playMode parameter (list_loop, single_loop, random, single)
- Add parameter validation
- Include integration documentation
2026-05-28 13:00:21 +00:00
Sunset Mikotoandgemini-code-assist[bot] 01d391ac91 Update util/option.js
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-05-25 13:05:14 +08:00
Sunset Mikotoandgemini-code-assist[bot] 85d70ba9dd Update util/option.js
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-05-25 12:56:34 +08:00
Sunset Mikotoandgemini-code-assist[bot] 3cfecbcc1f Update util/option.js
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-05-25 12:51:29 +08:00
Sunset Mikoto c6e9746ed6 fix: 修正为原始逻辑,简化代码 2026-05-25 01:47:53 +00:00
Sunset Mikoto d6961ecb4d feat: 当ENABLE_RANDOM_CN_IP为true时,除非请求参数randomCNIP显式为false,默认开启randomCNIP 2026-05-24 18:11:35 +00:00
Sunset Mikoto 02242eecf6 fix: randomCNIP 不工作 2026-05-24 18:00:36 +00:00
MoeFurina 269456def3 fix: 去除对github registry 的支持 2026-05-22 20:45:00 +08:00
MoeFurina 086e379f2c fix(workflow): 移动 pnpm 设置步骤以避免重复 2026-05-22 20:27:20 +08:00
MoeFurina 38803a18ae feat(workflow): 新增版本变更时创建发布的工作流 2026-05-22 20:19:59 +08:00
MoeFurina 3980d09bcd feat(上游): 新增多级行政区划和指定维度音乐排行榜接口 2026-05-22 19:59:42 +08:00
MoeFurina 64d4847350 fix(workflow): 移除发布条件检查以简化工作流 2026-05-16 10:43:28 +08:00
MoeFurina cf74e90c1d fix(workflow): fix cant publish packages 2026-05-16 10:40:21 +08:00
MoeFurina a366983e99 feat: 新增评论举报接口 && bump 4.32.1 2026-05-16 10:21:46 +08:00
dependabot[bot] 6175d55f89 chore(deps): bump aormsby/Fork-Sync-With-Upstream-action
Bumps [aormsby/Fork-Sync-With-Upstream-action](https://github.com/aormsby/fork-sync-with-upstream-action) from 3.4.2 to 3.4.3.
- [Release notes](https://github.com/aormsby/fork-sync-with-upstream-action/releases)
- [Commits](https://github.com/aormsby/fork-sync-with-upstream-action/compare/v3.4.2...v3.4.3)

---
updated-dependencies:
- dependency-name: aormsby/Fork-Sync-With-Upstream-action
  dependency-version: 3.4.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-01 14:54:43 +00:00
MoEFusion 15fa49a2e8 Merge pull request #164 from irtrdr/main 2026-05-01 14:00:51 +08:00
irtrdr f5fe69c863 feat: 更新song_copyright_rcmd接口参数为可选 2026-04-29 04:09:54 +08:00
irtrdr b6be789ccd feat: 新增灰色歌曲其他版本推荐接口 2026-04-29 03:55:21 +08:00
MoeFurina 0395d087d9 Merge branch 'main' into main 2026-04-19 10:19:41 +08:00
wlm3201 3f679c0d87 日推接口增加刷新参数 2026-04-18 11:40:13 +08:00
MoeFurina ba9c6deaee feat: 新增助眠解压相关模块 && bump 4.32.0 2026-04-17 20:41:31 +08:00
MoeFurina 2c36daf07a bump 4.31.0 2026-03-28 00:09:46 +08:00
ElyPrism 5b5f380cd5 Merge pull request #136 from laoshuikaixue/feature/cors-multi-domain 2026-03-20 23:39:06 +08:00
ElyPrism ff7c5518d1 Merge pull request #138 from NeteaseCloudMusicApiEnhanced/up-4.31.0 2026-03-20 20:14:14 +08:00
MoeFurina bbb2b9d4a0 docs: 更新文档 2026-03-20 20:08:47 +08:00
MoeFurina 3188238678 feat: 添加DIFM相关接口 2026-03-20 20:05:40 +08:00
MoeFurina 8e60324452 chore: update deps 2026-03-20 20:02:04 +08:00
MoeFurina c9909cddd3 Merge remote-tracking branch 'origin/dependabot/github_actions/actions/upload-artifact-7' into up-4.31.0 2026-03-20 19:58:27 +08:00
MoeFurina dbdbba3f98 Squashed commit of the following:
commit ed0208eb89
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Sun Mar 1 12:48:11 2026 +0000

    chore(deps): bump actions/download-artifact from 7 to 8

    Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7 to 8.
    - [Release notes](https://github.com/actions/download-artifact/releases)
    - [Commits](https://github.com/actions/download-artifact/compare/v7...v8)

    ---
    updated-dependencies:
    - dependency-name: actions/download-artifact
      dependency-version: '8'
      dependency-type: direct:production
      update-type: version-update:semver-major
    ...

    Signed-off-by: dependabot[bot] <support@github.com>
2026-03-20 19:58:19 +08:00
LaoShui 27aa9a01cb fix(cors): 修复CORS源验证逻辑
- 移除无效的请求源回退逻辑
- 简化Vary头设置条件判断
- 优化CORS允许源验证流程
2026-03-14 21:14:18 +08:00
LaoShui 30e522018f feat(server): 支持多域名CORS配置
- 实现了逗号分隔的多域名CORS配置解析功能
- 新增parseCorsAllowOrigins函数处理域名列表解析
- 新增getCorsAllowOrigin函数实现动态域名匹配逻辑
- 更新CORS响应头设置逻辑支持多域名验证
- 添加Vary: Origin响应头优化缓存策略
- 修改README文档说明多域名配置方式
2026-03-14 21:03:58 +08:00
LaoShui 7b2507e43d refactor(server): 修复函数名拼写错误
- 将 consturctServer 函数名更正为 constructServer
- 更新调用处的函数名称以保持一致性
2026-03-14 19:24:52 +08:00
ElyPrism 3647fc5fa0 Merge branch 'add-new-modules' to main 2026-03-14 00:28:04 +08:00
MoeFurina 8521c198d3 docs: 更新readme 2026-03-14 00:25:43 +08:00
MoeFurina 4d8c4daa14 docs: 更新文档 2026-03-13 23:35:03 +08:00
ElyPrismandgemini-code-assist[bot] 2e3cf4d451 Apply suggestion from @gemini-code-assist[bot]
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-03-08 12:00:17 +08:00
ElyPrismandgemini-code-assist[bot] 288459cddb fix: 修复部分拼写错误
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-03-08 11:59:15 +08:00
ElyPrismandgemini-code-assist[bot] c1b8a381f3 fix: module/voicelist_search.js 拼写错误
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-03-08 11:53:03 +08:00
MoeFurina 2dd12b88ae feat: 新增评论相关接口并更新部分接口 2026-03-08 11:42:32 +08:00
ElyPrism b6a1f9ce0a Merge branch 'main' into main 2026-03-08 09:24:54 +08:00
RedSTAR.Cheng 5991e41c5d Merge branch 'NeteaseCloudMusicApiEnhanced:main' into main 2026-03-04 10:21:38 +08:00
dependabot[bot] f61554714c chore(deps): bump actions/upload-artifact from 6 to 7
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-01 12:48:05 +00:00
RedSTARO 266cd8d059 chore: doc update for 302 endpoint 2026-03-01 14:03:54 +08:00
RedSTARO 89a70b14d4 refactor: simplify /song/url/v1/302 call chain 2026-03-01 13:48:28 +08:00
ElyPrism a9332af453 Merge branch 'main' into main
build(version): bump to 4.30.2
2026-02-28 15:52:06 +08:00
MoeFurina cffe68d9ff upd changelog 2026-02-28 15:51:47 +08:00
MoeFurina 75ec2de66f feat: update doc icon 2026-02-28 15:37:02 +08:00
MoeFurina 0bd023c188 Merge branch 'main' into chore/bump-4.30.2 2026-02-28 15:33:16 +08:00
ElyPrism 2c82c9b7be Merge branch 'add-comment-info' into 'main' 2026-02-28 15:29:10 +08:00
imsyy 1320e5780b feat: 更新文档 2026-02-28 14:52:13 +08:00
imsyy bde1f0864b feat: 更新文档 2026-02-28 14:50:04 +08:00
imsyy e891287f1a feat: 添加评论统计数据 2026-02-28 14:42:25 +08:00
RedSTARO 59241631db feat: add song download url api end point for 302
* This will redirect access from http://localhost:3000/song/url/v1?id=2756058128&level=exhigh to actual resource url
2026-02-26 20:12:43 +08:00
MoeFurina 29ef4f68c2 docs: update readme 2026-02-26 18:43:17 +08:00
MoeFurina ee25eb17a6 docs: update readme 2026-02-23 23:30:55 +08:00
MoeFurina 31d2ec9225 chore: clean up empty code change sections in the changes log 2026-02-23 23:12:01 +08:00
ElyPrismandgemini-code-assist[bot] b45bdd411f Update README.MD
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-02-22 22:20:15 +08:00
MoeFurina c14b06f6c3 build: update deps 2026-02-22 22:16:39 +08:00
ElyPrism b027aca40a Merge branch 'feat/cloud-upload-modes' into 'main'
feat(cloud): 添加云盘上传模式选择功能并优化上传配置
2026-02-19 12:04:19 +08:00
LaoShui b1729f19aa style(code): 格式化代码
- 将长参数列表拆分为多行以提高可读性
- 标准化函数调用中的逗号使用
- 统一对象和数组的换行格式
- 更新 ESLint 配置中的 ECMA 版本至 2020,以支持 ES2020 语法(包括 Optional Chaining)
- 优化代码缩进和对齐方式
- 确保所有文件中的代码风格一致性
2026-02-19 11:52:19 +08:00
LaoShui 755489546b refactor(util): 简化文件帮助工具函数
- 移除未使用的 path 模块引入
- 将 getFileExtension 函数从异步改为同步
- 优化 sanitizeFilename 函数逻辑,移除冗余扩展名处理
2026-02-18 20:24:43 +08:00
LaoShui 92df6e13a0 refactor(cloud): 重构文件处理逻辑并提取辅助函数
- 将文件大小、MD5计算等逻辑提取到 fileHelper 工具模块
- 使用统一的文件扩展名和文件名处理函数
- 简化临时文件处理和清理逻辑
- 统一文件上传数据获取方式
- 移除重复的文件操作代码并提高可维护性
2026-02-18 20:19:46 +08:00
LaoShui 1ad8ab088f fix(cloud): 修改上传接口Cookie参数传递方式
- 将Cookie参数从URL查询字符串改为请求体传递
- 更新token接口调用以将cookie作为data参数发送
- 更新complete接口调用以将cookie作为data参数发送
- 修改API文档说明Cookie参数传递方式变更
- 确保Cookie值通过POST请求体安全传输
2026-02-18 19:37:32 +08:00
LaoShui a09f126ab2 fix(upload): 修复文件上传功能中的路径替换和临时文件支持
- 将单个斜杠替换改为全局正则替换以正确处理所有路径分隔符
- 移除未使用的 crypto 模块引入
- 添加对临时文件上传的支持,使用 fs 模块读取临时文件
- 动态设置 Content-Type 头部,优先使用文件的 mimetype 属性
- 重构多处文件上传逻辑以支持流式读取大文件
- 优化分片上传时的文件大小获取方式
2026-02-18 19:09:15 +08:00
LaoShui 872bae1b43 feat(cloud): 添加音频元数据解析功能
- 集成 jsmediatags 库用于解析音频文件的 ID3 标签
- 实现 parseMediaTags 函数提取歌曲标题、艺术家和专辑信息
- 在上传前添加音频元数据解析步骤
- 将解析的元数据传递给 completeUpload 函数
- 使用元数据中的标题作为歌曲名称,提高准确性
- 添加默认值处理以防止解析失败
- 更新 completeUpload 函数接收文件对象和媒体标签参数
- 移除模块中不再使用的文件扩展名提取逻辑
2026-02-18 18:49:05 +08:00
LaoShui 83c527af01 feat(cloud): 添加云盘上传模式选择和进度显示功能
- 添加客户端直传和后端代理两种上传模式选项
- 实现上传进度条和状态显示界面
- 添加文件MD5计算和上传凭证获取功能
- 支持大文件上传和断点续传机制
- 新增cloud/upload/token和cloud/upload/complete接口
- 更新文档说明上传模式和接口使用方法
- 优化上传按钮禁用状态和提示信息显示
2026-02-18 18:42:28 +08:00
LaoShui 84efe5d758 chore(deps): 更新依赖包版本并移除冗余依赖
- 移除了 express-fileupload 中的 md5 依赖
- 将多个开发依赖包从固定版本改为范围版本(^)
- 更新了 typescript、eslint 等核心依赖的版本声明
- 移除了 charenc、crypt、is-buffer 等冗余依赖包
- 更新了 @typescript-eslint 相关包的版本引用
- 清理了依赖树中的重复和无用条目
2026-02-18 17:24:45 +08:00
LaoShui cfa475bf94 chore(deps): 更新依赖包版本并移除不需要的依赖
- 移除了 md5 依赖包
- 移除了 @neteasecloudmusicapienhanced/unblockmusic-utils 重复依赖
- 移除了 axios 重复依赖
- 移除了 dotenv 重复依赖
- 移除了 music-metadata 重复依赖
- 将开发依赖包版本从固定版本号更新为 ^ 版本范围
- 统一了依赖包版本管理格式
2026-02-18 17:13:50 +08:00
LaoShui 4087bafd7d fix(cloud): 解决临时文件清理和上传流程中的错误处理问题
- 修复了临时文件清理失败时的日志消息本地化
- 移除了重复的临时文件清理调用,统一在 finally 块中处理
- 优化了错误处理逻辑,确保在各种异常情况下正确返回错误响应
- 更新了日志消息为中文描述,提高可读性
- 修复了上传插件中的日志消息本地化问题
- 统一了错误处理流程,避免重复的清理操作
2026-02-18 17:09:02 +08:00
LaoShui 8951e32a0e refactor(server): 优化文件上传配置和MD5计算逻辑
- 移除cloud.js中的异步Promise包装,直接同步计算MD5哈希值
- 在server.js中提取上传大小限制为常量配置
- 统一使用字节单位常量管理文件上传大小限制
- 简化代码结构,提高可读性和维护性
2026-02-18 17:02:15 +08:00
LaoShui 33ccc83615 fix(cloud): 解决临时文件清理和异步操作问题
- 添加异步临时文件清理函数避免资源泄露
- 将同步文件操作改为异步操作提高性能
- 在令牌分配失败时执行临时文件清理
- 在上传失败时确保临时文件被清理
- 使用 Promise 包装 MD5 计算操作
- 统一临时文件清理逻辑到 finally 块
2026-02-18 16:57:20 +08:00
LaoShui 2d6173b2aa fix(cloud): 移除了重复的条件判断 2026-02-18 16:50:20 +08:00
LaoShui ba7d1a8574 feat(cloud): 支持临时文件上传功能
- 使用 crypto 模块替换 md5 模块进行文件哈希计算
- 添加对临时文件上传的支持,当存在 tempFilePath 时使用文件流处理
- 实现临时文件的 MD5 计算和元数据解析功能
- 在上传完成后自动清理临时文件
- 配置服务器端文件上传中间件启用临时文件支持
- 修改上传插件以支持临时文件读取流上传方式
- 增加文件大小获取和验证的兼容性处理
2026-02-18 16:44:19 +08:00
LaoShui 26d55255e0 fix(cloud): 解决云上传功能中的错误处理和代码清理
- 移除注释掉的废弃代码和调试信息
- 添加详细的错误处理和日志记录
- 验证token分配结果并处理失败情况
- 在上传过程中添加异常捕获和错误抛出
- 验证LBS响应的有效性并处理网络请求超时
- 改进上传流程的错误处理机制
2026-02-18 16:17:07 +08:00
LaoShui 4489f10f63 feat(server): 增加文件上传大小限制并优化配置
- 将请求体大小限制从 50MB 增加到 500MB
- 配置文件上传中间件支持 500MB 大小限制
- 设置临时文件目录为 /tmp/
- 启用 useTempFiles 选项以提高性能
- 配置达到限制时自动中止上传
2026-02-18 16:08:40 +08:00
ElyPrism 2047bdfa65 Merge branch 'main' into 'main'
refactor: Refactor random Chinese IP generator
2026-02-15 00:20:25 +08:00
MoeFurina bc9d7b949f fix: 修复注入随机ip不生效 2026-02-15 00:06:42 +08:00
MoeFurina f08f192328 refactor: 重构随机中国ip 2026-02-14 23:50:59 +08:00
ElyPrism b04b9d51fb Merge branch 'main' of 'main'
更加优雅的显示URL和调试按钮
2026-02-14 12:09:45 +08:00
BakaCookie520 c91f5f3714 更加优雅的显示URL和调试按钮 2026-02-14 00:01:19 +08:00
ElyPrism 7fceec12e4 Merge branch "Burial0268/main" into "main" 2026-02-12 19:28:43 +08:00
拜瑞andgemini-code-assist[bot] 1df147edab fix(server): prevent obj[2]=undefined if there is no options passed
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-02-12 19:21:02 +08:00
Burial0268 6d1f75f229 fix(server): Correctly inject client IP into request parameters 2026-02-12 18:59:32 +08:00
2a0b54e442 feat: Add user playlist endpoints & domain overrides (bump 4.30.1) (#105)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-11 16:49:11 +08:00
github-actions[bot]andgithub-actions[bot] a19418bbb6 Auto-build: Add compiled binaries for win, linux, macos (#104)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-10 11:38:47 +08:00
ce51da9150 build(version): bump 4.30.0 (#102)
* chore(deps): bump actions/checkout from 4 to 6

Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Squashed commit of the following:

commit f73cbbeec3
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Sun Feb 1 12:47:57 2026 +0000

    chore(deps): bump actions/download-artifact from 4 to 7

    Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 7.
    - [Release notes](https://github.com/actions/download-artifact/releases)
    - [Commits](https://github.com/actions/download-artifact/compare/v4...v7)

    ---
    updated-dependencies:
    - dependency-name: actions/download-artifact
      dependency-version: '7'
      dependency-type: direct:production
      update-type: version-update:semver-major
    ...

    Signed-off-by: dependabot[bot] <support@github.com>

* Squashed commit of the following:

commit 4da2d5f360
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Sun Feb 1 12:48:00 2026 +0000

    chore(deps): bump actions/github-script from 7 to 8

    Bumps [actions/github-script](https://github.com/actions/github-script) from 7 to 8.
    - [Release notes](https://github.com/actions/github-script/releases)
    - [Commits](https://github.com/actions/github-script/compare/v7...v8)

    ---
    updated-dependencies:
    - dependency-name: actions/github-script
      dependency-version: '8'
      dependency-type: direct:production
      update-type: version-update:semver-major
    ...

    Signed-off-by: dependabot[bot] <support@github.com>

* Squashed commit of the following:

commit 9e65b17625
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Sun Feb 1 12:47:49 2026 +0000

    chore(deps): bump actions/setup-node from 4 to 6

    Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
    - [Release notes](https://github.com/actions/setup-node/releases)
    - [Commits](https://github.com/actions/setup-node/compare/v4...v6)

    ---
    updated-dependencies:
    - dependency-name: actions/setup-node
      dependency-version: '6'
      dependency-type: direct:production
      update-type: version-update:semver-major
    ...

    Signed-off-by: dependabot[bot] <support@github.com>

* Squashed commit of the following:

commit a060f3c4cc
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Sun Feb 1 12:47:53 2026 +0000

    chore(deps): bump actions/upload-artifact from 4 to 6

    Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 6.
    - [Release notes](https://github.com/actions/upload-artifact/releases)
    - [Commits](https://github.com/actions/upload-artifact/compare/v4...v6)

    ---
    updated-dependencies:
    - dependency-name: actions/upload-artifact
      dependency-version: '6'
      dependency-type: direct:production
      update-type: version-update:semver-major
    ...

    Signed-off-by: dependabot[bot] <support@github.com>

* build(version): bump 4.30.0

* refactor: QR login and voice upload pages with improved UI and error handling

- Enhanced styling for better user experience on qrlogin-nocookie.html and qrlogin.html
- Added loading indicators and improved status messages during QR code login process
- Updated error handling for login status retrieval
- Refactored unblock_test.html for better layout and user interaction
- Improved voice upload page with a more intuitive design and better feedback for file uploads
- Added loading state management for voice list retrieval
- Enhanced accessibility and usability across all modified pages

* fix: Potential fix for code scanning alert no. 6: DOM text reinterpreted as HTML

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* Potential fix for code scanning alert no. 15: DOM text reinterpreted as HTML

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* build: update utils

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-02-09 23:33:26 +08:00
Yon8 27002d7665 feat: add musician_vip_tasks API, its module, and home.md documentation. (#95) 2026-02-05 00:29:02 +08:00
github-actions[bot]andgithub-actions[bot] 43d1c72f8f Auto-build: Add compiled binaries for win, linux, macos (#88)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-31 14:37:48 +08:00
MoeFurina 1d7e9cb6d8 fix(workflow): 修复低级错误 2026-01-31 14:32:42 +08:00
ElyPrism 609c910d5a ci: 支持action自动编译可执行文件 2026-01-31 14:22:00 +08:00
MoeFurina 2b69e9dda5 chore(packages): bump version 4.29.21 2026-01-30 23:13:13 +08:00
MoeFurina 796c2803df Merge remote-tracking branch 'origin/dependabot/npm_and_yarn/typescript-eslint/parser-8.53.0' 2026-01-30 23:08:07 +08:00
MoeFurina ab00919a93 Merge remote-tracking branch 'origin/dependabot/npm_and_yarn/types/node-25.0.9' 2026-01-30 23:07:58 +08:00
dependabot[bot] db2ca44bbc chore(packages): bump @typescript-eslint/parser from 8.51.0 to 8.53.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.51.0 to 8.53.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.53.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.53.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 14:35:05 +00:00
dependabot[bot] 6c79f7495b chore(packages): bump @types/node from 25.0.3 to 25.0.9
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.0.3 to 25.0.9.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 25.0.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 14:34:32 +00:00
dependabot[bot] fd0608adef chore(packages): bump eslint-plugin-prettier from 5.5.4 to 5.5.5
Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.5.4 to 5.5.5.
- [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.5.4...v5.5.5)

---
updated-dependencies:
- dependency-name: eslint-plugin-prettier
  dependency-version: 5.5.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 14:34:19 +00:00
f6fc452666 更新 README 以反映 Node.js 版本要求和 Docker 使用说明 (#80)
Co-authored-by: binaryify <binaryify@gmail.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-01-16 22:58:19 +08:00
MoeFurina 748d5da8fe fix(require): fix modules not defined 2026-01-09 21:44:03 +08:00
dependabot[bot] 6613fbf50d chore(packages): bump @types/node from 24.10.0 to 24.10.1 (#57)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-03 01:50:08 +08:00
dependabot[bot] c8493b93ad chore(packages): bump @typescript-eslint/parser from 8.46.3 to 8.48.0 (#67)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-03 01:49:49 +08:00
dependabot[bot] b93578a879 chore(packages): bump prettier from 3.6.2 to 3.7.3 (#66)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-03 01:47:59 +08:00
dependabot[bot] de54c7fe97 chore(packages): bump @typescript-eslint/eslint-plugin (#59)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-03 01:47:38 +08:00
MoeFurina 2e707e2f5e Merge remote-tracking branch 'origin/dependabot/npm_and_yarn/lint-staged-16.2.7' 2026-01-03 01:43:23 +08:00
MoeFurina 2994e2fadd Merge remote-tracking branch 'origin/dependabot/github_actions/peter-evans/create-or-update-comment-5' 2026-01-03 01:43:15 +08:00
MoeFurina eb08ed4ba3 Merge remote-tracking branch 'origin/dependabot/github_actions/actions/stale-10' 2026-01-03 01:43:09 +08:00
MoeFurina d5fedb5c54 Merge remote-tracking branch 'origin/dependabot/github_actions/actions/checkout-6' 2026-01-03 01:43:02 +08:00
MoeFurina f2f78b2774 fix(workflows): update branch references and remove unused push triggers
feat: enhance eapi_decrypt.html with styled decode result display

fix: update qrlogin and qrlogin-nocookie to include platform parameter in QR code creation URL

chore: bump music-metadata and other dependencies in package.json and pnpm-lock.yaml

docs: update README with important project usage notes
2026-01-03 01:36:21 +08:00
dependabot[bot] 871414f2e6 chore(deps): bump actions/checkout from 5 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-26 11:55:00 +00:00
MoeFurina 2d3f15f0e5 revert: revive back workflow 2025-12-26 19:54:03 +08:00
ElyPrismandgemini-code-assist[bot] 598dd8bd34 refactor(unblock): Refactor song URL matching to use new utils package (#73)
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-12-26 19:51:13 +08:00
ElyPrismandYiQing-House 30bd839809 feat(module): add vip daily signin (#72)
Co-authored-by: YiQing-House <72288016+1662187689@users.noreply.github.com>
2025-12-20 10:14:50 +08:00
MoeFurina d4ee3b88f8 docs: upd doc 2025-12-20 00:45:53 +08:00
MoeFurina 77eb154028 fix(eslint): replace double quotes with single quotes 2025-12-19 21:05:04 +08:00
ElyPrism 140ea858c4 Merge pull request #70 from apoint123/fix/phone-login 2025-12-19 20:59:24 +08:00
apoint123 f7f8c54236 fix: 修复验证码登录 2025-12-18 18:21:05 +08:00
MoeFurina bcda215a6c chore(deps): update dependences 2025-12-12 20:24:24 +08:00
MoeFurina ca6834b83f ci(docker): fix cannot be deployed by linux arm64 2025-12-06 23:00:49 +08:00
dependabot[bot] c8fba0f7d1 chore(deps): bump actions/stale from 8 to 10
Bumps [actions/stale](https://github.com/actions/stale) from 8 to 10.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v8...v10)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-version: '10'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 15:08:15 +00:00
dependabot[bot] 546a84b1b8 chore(deps): bump peter-evans/create-or-update-comment from 4 to 5
Bumps [peter-evans/create-or-update-comment](https://github.com/peter-evans/create-or-update-comment) from 4 to 5.
- [Release notes](https://github.com/peter-evans/create-or-update-comment/releases)
- [Commits](https://github.com/peter-evans/create-or-update-comment/compare/v4...v5)

---
updated-dependencies:
- dependency-name: peter-evans/create-or-update-comment
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 15:08:11 +00:00
ElyPrism 205ac7292f Merge pull request #62 from NeteaseCloudMusicApiEnhanced/chore/upd-deps 2025-11-29 12:36:11 +08:00
MoeFurina 1aba68561d 🐳 chore(deps): update dependences 2025-11-29 12:33:03 +08:00
ElyPrism bd2fdff5ae Merge pull request #55 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/music-metadata-11.10.3 2025-11-28 19:23:52 +08:00
dependabot[bot] 4af8323694 chore(packages): bump lint-staged from 16.2.6 to 16.2.7
Bumps [lint-staged](https://github.com/lint-staged/lint-staged) from 16.2.6 to 16.2.7.
- [Release notes](https://github.com/lint-staged/lint-staged/releases)
- [Changelog](https://github.com/lint-staged/lint-staged/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lint-staged/lint-staged/compare/v16.2.6...v16.2.7)

---
updated-dependencies:
- dependency-name: lint-staged
  dependency-version: 16.2.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 14:15:19 +00:00
dependabot[bot] a5a1a91dfa chore(packages): bump music-metadata from 11.10.0 to 11.10.3
Bumps [music-metadata](https://github.com/Borewit/music-metadata) from 11.10.0 to 11.10.3.
- [Release notes](https://github.com/Borewit/music-metadata/releases)
- [Commits](https://github.com/Borewit/music-metadata/compare/v11.10.0...v11.10.3)

---
updated-dependencies:
- dependency-name: music-metadata
  dependency-version: 11.10.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 14:15:05 +00:00
ElyPrism ee43878834 Merge pull request #53 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/mocha-11.7.5 2025-11-15 15:25:31 +08:00
MoeFurina 9d18639464 fix(eslint): fix files which have eslint problems 2025-11-15 13:25:09 +08:00
MoeFurina fe28194445 refactor(generateRandomChineseIP): 完善随机中国ip功能 2025-11-15 13:11:29 +08:00
dependabot[bot] b14cb9bb24 chore(packages): bump mocha from 11.7.4 to 11.7.5
Bumps [mocha](https://github.com/mochajs/mocha) from 11.7.4 to 11.7.5.
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/v11.7.5/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v11.7.4...v11.7.5)

---
updated-dependencies:
- dependency-name: mocha
  dependency-version: 11.7.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-15 03:18:39 +00:00
ElyPrism 06739b2d6d Merge pull request #51 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/typescript-eslint/parser-8.46.3 2025-11-15 00:31:26 +08:00
MoeFurina 8639c9d0f1 chore(deps): update dependences 2025-11-15 00:28:14 +08:00
dependabot[bot] bc4a0d4916 chore(packages): bump @typescript-eslint/parser from 8.46.2 to 8.46.3
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.46.2 to 8.46.3.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.46.3/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.46.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-10 14:48:48 +00:00
MoeFurina 4e00b94ee6 chore: 删除过时的issue模板和更新bug报告及功能请求模板 2025-11-09 10:51:14 +08:00
MoeFurina 9019a2a4a5 fix(type): covert "music-metadata" esm to cjs 2025-11-09 08:21:51 +08:00
MoeFurina 3a10a4d753 ci(debug): add more debug info 2025-11-08 15:28:36 +08:00
MoeFurina f39aafaff4 docs: update doc 2025-11-08 12:52:19 +08:00
ElyPrism 2a8fb72d1d Merge pull request #41 from NeteaseCloudMusicApiEnhanced/dependabot/github_actions/actions/setup-node-6 2025-11-07 22:13:52 +08:00
ElyPrism ea6ab4f6f7 Merge pull request #42 from NeteaseCloudMusicApiEnhanced/dependabot/github_actions/docker/build-push-action-6 2025-11-07 22:13:42 +08:00
ElyPrism 6fe19a71e3 Merge pull request #43 from NeteaseCloudMusicApiEnhanced/dependabot/github_actions/actions/checkout-5 2025-11-07 22:13:30 +08:00
ElyPrism abd3a79ecd Merge branch 'main' into dependabot/github_actions/actions/checkout-5 2025-11-07 22:13:21 +08:00
ElyPrism 044ef355c1 Merge pull request #47 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/types/node-24.10.0 2025-11-07 22:13:07 +08:00
ElyPrism 2944ca42ba Merge pull request #45 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/music-metadata-11.9.0 2025-11-07 22:12:52 +08:00
MoeFurina d4d465e731 chore(deps): update dependences 2025-11-07 19:03:04 +08:00
ElyPrism f49d3cac19 Merge pull request #48 from Cinvin/main 2025-11-07 19:00:32 +08:00
5unV 2f2755ac8c feat: 增加云盘歌词接口 2025-11-06 10:04:13 +08:00
dependabot[bot] f46c0d4a84 chore(packages): bump @types/node from 24.9.1 to 24.10.0
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.9.1 to 24.10.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.10.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-03 12:42:34 +00:00
dependabot[bot] 14ee86e15b chore(packages): bump music-metadata from 7.14.0 to 11.9.0
Bumps [music-metadata](https://github.com/Borewit/music-metadata) from 7.14.0 to 11.9.0.
- [Release notes](https://github.com/Borewit/music-metadata/releases)
- [Commits](https://github.com/Borewit/music-metadata/compare/v7.14.0...v11.9.0)

---
updated-dependencies:
- dependency-name: music-metadata
  dependency-version: 11.9.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-03 12:42:01 +00:00
dependabot[bot] 5e820187a1 chore(deps): bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 12:18:20 +00:00
dependabot[bot] 781299c1c5 chore(deps): bump docker/build-push-action from 5 to 6
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 6.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 12:18:15 +00:00
dependabot[bot] 8fc6ed1a76 chore(deps): bump actions/setup-node from 5 to 6
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 5 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 12:18:12 +00:00
MoeFurina 8bb68accee ci(action): fix workflows which pnpm is not installed 2025-11-01 13:23:30 +08:00
MoeFurina 55858d89d9 ci(action): switch GitHub Actions to use pnpm and update actions 2025-11-01 13:16:50 +08:00
MoeFurina 597ac1498f fix(eslint): fix files which have eslint problems 2025-11-01 13:11:38 +08:00
MoeFurina 398f410109 fix: update music search keyword and test case ID
- Changed the default search keyword in the API documentation from "这么可爱真是抱歉" to "妖精小姐的魔法邀约".
- Updated the test case for fetching song URL to use the correct song ID (from 1969519579 to 2756058128).
2025-11-01 12:16:29 +08:00
ElyPrism 97980b5ac3 Merge pull request #36 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/eslint-config-prettier-10.1.8
chore(packages): bump eslint-config-prettier from 8.5.0 to 10.1.8
2025-10-29 13:09:14 +08:00
ElyPrism 65ff21526a Merge pull request #37 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/types/mocha-10.0.10
chore(packages): bump @types/mocha from 9.1.1 to 10.0.10
2025-10-29 13:09:06 +08:00
ElyPrism fb052fdecd Merge pull request #38 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/typescript-5.9.3
chore(packages): bump typescript from 4.5.2 to 5.9.3
2025-10-29 13:08:58 +08:00
ElyPrism b6453a1c1b Merge pull request #39 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/yargs-18.0.0
chore(packages): bump yargs from 17.7.2 to 18.0.0
2025-10-29 13:08:49 +08:00
ElyPrism 0c3da3bcb7 Merge pull request #40 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/lint-staged-16.2.6
chore(packages): bump lint-staged from 16.2.4 to 16.2.6
2025-10-29 13:08:38 +08:00
dependabot[bot] 80fbd7a620 chore(packages): bump lint-staged from 16.2.4 to 16.2.6
Bumps [lint-staged](https://github.com/lint-staged/lint-staged) from 16.2.4 to 16.2.6.
- [Release notes](https://github.com/lint-staged/lint-staged/releases)
- [Changelog](https://github.com/lint-staged/lint-staged/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lint-staged/lint-staged/compare/v16.2.4...v16.2.6)

---
updated-dependencies:
- dependency-name: lint-staged
  dependency-version: 16.2.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 13:51:16 +00:00
dependabot[bot] a4c9c0edaf chore(packages): bump yargs from 17.7.2 to 18.0.0
Bumps [yargs](https://github.com/yargs/yargs) from 17.7.2 to 18.0.0.
- [Release notes](https://github.com/yargs/yargs/releases)
- [Changelog](https://github.com/yargs/yargs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/yargs/yargs/compare/v17.7.2...v18.0.0)

---
updated-dependencies:
- dependency-name: yargs
  dependency-version: 18.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 13:50:05 +00:00
dependabot[bot] 19e51bc39a chore(packages): bump typescript from 4.5.2 to 5.9.3
Bumps [typescript](https://github.com/microsoft/TypeScript) from 4.5.2 to 5.9.3.
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release-publish.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v4.5.2...v5.9.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-version: 5.9.3
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 13:39:32 +00:00
dependabot[bot] a914b5bc11 chore(packages): bump @types/mocha from 9.1.1 to 10.0.10
Bumps [@types/mocha](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/mocha) from 9.1.1 to 10.0.10.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/mocha)

---
updated-dependencies:
- dependency-name: "@types/mocha"
  dependency-version: 10.0.10
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 13:39:31 +00:00
dependabot[bot] 5eeeaeee8a chore(packages): bump eslint-config-prettier from 8.5.0 to 10.1.8
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 8.5.0 to 10.1.8.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v8.5.0...v10.1.8)

---
updated-dependencies:
- dependency-name: eslint-config-prettier
  dependency-version: 10.1.8
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 13:21:55 +00:00
ElyPrism 1ab9def4d5 Merge pull request #32 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/husky-9.1.7 2025-10-25 12:14:59 +08:00
dependabot[bot] 446ad4c871 chore(packages): bump husky from 7.0.4 to 9.1.7
Bumps [husky](https://github.com/typicode/husky) from 7.0.4 to 9.1.7.
- [Release notes](https://github.com/typicode/husky/releases)
- [Commits](https://github.com/typicode/husky/compare/v7.0.4...v9.1.7)

---
updated-dependencies:
- dependency-name: husky
  dependency-version: 9.1.7
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-25 04:14:44 +00:00
ElyPrism 316826dd81 Merge pull request #33 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/typescript-eslint/parser-5.62.0 2025-10-25 12:13:47 +08:00
ElyPrism 11a240cb18 Merge pull request #24 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/mocha-11.7.4 2025-10-25 12:13:39 +08:00
ElyPrism df2d0e6431 Merge pull request #34 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/types/node-24.8.1 2025-10-25 12:13:29 +08:00
ElyPrism a1436e1d64 Merge pull request #26 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/eslint-plugin-prettier-5.5.4 2025-10-25 12:13:19 +08:00
dependabot[bot] 1f87ccf080 chore(packages): bump @types/node from 24.6.1 to 24.8.1
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.6.1 to 24.8.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.8.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-25 04:12:03 +00:00
dependabot[bot] 323b1014d2 chore(packages): bump @typescript-eslint/parser from 5.0.0 to 5.62.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.0.0 to 5.62.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.62.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 5.62.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-25 04:12:00 +00:00
dependabot[bot] d2351f6f30 chore(packages): bump mocha from 11.7.3 to 11.7.4
Bumps [mocha](https://github.com/mochajs/mocha) from 11.7.3 to 11.7.4.
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v11.7.3...v11.7.4)

---
updated-dependencies:
- dependency-name: mocha
  dependency-version: 11.7.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-25 04:11:54 +00:00
dependabot[bot] dd653c07e9 chore(packages): bump eslint-plugin-prettier from 4.0.0 to 5.5.4
Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 4.0.0 to 5.5.4.
- [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v4.0.0...v5.5.4)

---
updated-dependencies:
- dependency-name: eslint-plugin-prettier
  dependency-version: 5.5.4
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-25 04:11:52 +00:00
MoeFurina 173496f305 build(ci): delete useless lock files 2025-10-25 12:10:23 +08:00
MoeFurina b45739b621 refactor(index): rewrite api index pages without ai and update dependences 2025-10-24 17:51:23 +08:00
ElyPrism f63068b386 Merge pull request #31 from NeteaseCloudMusicApiEnhanced/fix/user_accout-returns-null 2025-10-18 14:21:16 +08:00
ElyPrism 927b79030b edit funding sources in FUNDING.yml
Removed WeChat & Alipay from funding options.

Signed-off-by: ElyPrism <noreply@focalors.ltd>
2025-10-18 14:20:38 +08:00
ImFurina 6d6eee13b9 docs: upd readme 2025-10-17 22:01:32 +08:00
ElyPrism a7f086cf8f Merge pull request #30 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/lint-staged-16.2.4 2025-10-17 21:39:31 +08:00
dependabot[bot] a38d689de4 chore(packages): bump lint-staged from 12.1.7 to 16.2.4
Bumps [lint-staged](https://github.com/lint-staged/lint-staged) from 12.1.7 to 16.2.4.
- [Release notes](https://github.com/lint-staged/lint-staged/releases)
- [Changelog](https://github.com/lint-staged/lint-staged/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lint-staged/lint-staged/compare/v12.1.7...v16.2.4)

---
updated-dependencies:
- dependency-name: lint-staged
  dependency-version: 16.2.4
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-17 13:39:20 +00:00
ElyPrism 4ffb20c4ff Merge pull request #25 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-5.62.0 2025-10-17 21:37:34 +08:00
ElyPrism 84c19ee237 Merge pull request #22 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/dotenv-17.2.3 2025-10-17 21:37:22 +08:00
ImFurina f3d95f17b4 build(env): disable global dotenv file 2025-10-17 21:35:27 +08:00
ImFurina 6d33efee47 build(ci): change the package name 2025-10-17 20:06:30 +08:00
dependabot[bot] acc458f6cb chore(packages): bump @typescript-eslint/eslint-plugin
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.0.0 to 5.62.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.62.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 5.62.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-08 03:42:32 +00:00
ImFurina d78a20ea11 feat(randomCNIP): 添加随机中国IP选项 2025-10-08 11:40:40 +08:00
ImFurina 2cbd17a6d7 fix(typeerror): 尝试修复vercel调用 500错误 2025-10-07 15:08:05 +08:00
dependabot[bot] 240d8042fb chore(packages): bump dotenv from 16.6.1 to 17.2.3
Bumps [dotenv](https://github.com/motdotla/dotenv) from 16.6.1 to 17.2.3.
- [Changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md)
- [Commits](https://github.com/motdotla/dotenv/compare/v16.6.1...v17.2.3)

---
updated-dependencies:
- dependency-name: dotenv
  dependency-version: 17.2.3
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 14:52:04 +00:00
ElyPrism f9f6db3fee Merge pull request #23 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/multi-c1a69033e5
chore(packages): bump express and @types/express
2025-10-06 22:41:56 +08:00
dependabot[bot] 89e7c98412 chore(packages): bump express and @types/express
Bumps [express](https://github.com/expressjs/express) and [@types/express](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/express). These dependencies needed to be updated together.

Updates `express` from 4.21.2 to 5.1.0
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.21.2...v5.1.0)

Updates `@types/express` from 4.17.23 to 5.0.3
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/express)

---
updated-dependencies:
- dependency-name: express
  dependency-version: 5.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
- dependency-name: "@types/express"
  dependency-version: 5.0.3
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 12:58:19 +00:00
ElyPrism 16bf878135 ci(workflow): fix the workflow file that package name is illegal 2025-10-06 20:54:58 +08:00
ImFurina 8dcbe4db9d ci: add ghcr imagine 2025-10-06 20:28:44 +08:00
ElyPrism a1fbcf7008 add fundings 2025-10-06 17:38:12 +08:00
ImFurina c9c881ba7d docs(index): 指向官方文档 2025-10-06 14:11:09 +08:00
ImFurina 0e0777d175 feat: 支持全局cookie代理 2025-10-06 14:07:33 +08:00
ImFurina 765734cd2d chore(dep): update dependence 2025-10-06 10:10:02 +08:00
ImFurina 7f3be34fdd 4.29.8 2025-10-06 10:09:35 +08:00
ElyPrism 00af0c281d docs(doc): add docker deployment 2025-10-05 21:34:17 +08:00
ElyPrism 001f206a31 docs(readme): fix markdown grammar 2025-10-05 21:26:40 +08:00
ElyPrism 4d9045d597 docs(env-deploy): add env config 2025-10-05 21:25:08 +08:00
ElyPrism e001de3efa ci(dockerignore): add ignore 2025-10-05 21:19:18 +08:00
ElyPrism 6ae1ccd5e3 docs(readme): fix gammar in this readme file 2025-10-05 21:16:53 +08:00
ElyPrism cb72918c55 docs(readme): add docker deploy method 2025-10-05 21:15:14 +08:00
ElyPrism ba16f2f0ab ci(docker): add version tag to every deployment 2025-10-05 20:58:39 +08:00
ElyPrism a76576af23 ci(fix): fix workflow file conflicts 2025-10-05 20:54:52 +08:00
ElyPrism 72526ba20d ci(docker-deployment): add dockerhub push workflow file 2025-10-05 20:51:46 +08:00
ElyPrism db05eddb9c Merge pull request #18 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/prettier-3.6.2
chore(packages): bump prettier from 2.7.1 to 3.6.2
2025-10-05 20:26:09 +08:00
ElyPrism fb6804364a docs: 更新readme 2025-10-05 20:25:39 +08:00
ElyPrism 9e4626e905 Merge pull request #17 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/mocha-11.7.2
chore(packages): bump mocha from 10.0.0 to 11.7.2
2025-10-02 19:22:02 +08:00
ElyPrism 6c8f7be2a5 Merge branch 'main' into dependabot/npm_and_yarn/prettier-3.6.2 2025-10-01 21:56:02 +08:00
ElyPrism cf97ed45b7 Merge branch 'main' into dependabot/npm_and_yarn/mocha-11.7.2 2025-10-01 21:55:50 +08:00
ElyPrism 1d640a789f Merge pull request #15 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/types/node-24.6.0 2025-10-01 21:55:28 +08:00
ElyPrism 22e47582c4 Merge branch 'main' into dependabot/npm_and_yarn/types/node-24.6.0 2025-10-01 21:54:54 +08:00
ImFurina ed3959f545 docs(playlistSubscribe): 更新该内容文档 2025-10-01 21:53:05 +08:00
dependabot[bot] 771c2f9d52 chore(packages): bump prettier from 2.7.1 to 3.6.2
Bumps [prettier](https://github.com/prettier/prettier) from 2.7.1 to 3.6.2.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.7.1...3.6.2)

---
updated-dependencies:
- dependency-name: prettier
  dependency-version: 3.6.2
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-01 03:55:37 +00:00
dependabot[bot] f5b7fa2d26 chore(packages): bump @types/node from 16.11.19 to 24.6.0
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 16.11.19 to 24.6.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.6.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-01 03:54:16 +00:00
dependabot[bot] b798f1383b chore(packages): bump mocha from 10.0.0 to 11.7.2
Bumps [mocha](https://github.com/mochajs/mocha) from 10.0.0 to 11.7.2.
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v10.0.0...v11.7.2)

---
updated-dependencies:
- dependency-name: mocha
  dependency-version: 11.7.2
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-01 03:54:13 +00:00
ElyPrism 6a1b7d987c Merge pull request #16 from NeteaseCloudMusicApiEnhanced/dependabot/npm_and_yarn/eslint-plugin-html-8.1.3
chore(packages): bump eslint-plugin-html from 7.1.0 to 8.1.3
2025-10-01 11:52:29 +08:00
ElyPrism db95ee1987 Merge pull request #14 from NeteaseCloudMusicApiEnhanced/dependabot/github_actions/actions/cache-4
chore(deps): bump actions/cache from 3 to 4
2025-10-01 11:51:37 +08:00
dependabot[bot] edb9fbba09 chore(deps): bump actions/cache from 3 to 4
Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-01 03:50:53 +00:00
ElyPrism ede6534ebf Merge pull request #13 from NeteaseCloudMusicApiEnhanced/dependabot/github_actions/docker/setup-buildx-action-3
chore(deps): bump docker/setup-buildx-action from 2 to 3
2025-10-01 11:50:48 +08:00
ElyPrism 15c6ea7266 Merge pull request #12 from NeteaseCloudMusicApiEnhanced/dependabot/github_actions/actions/checkout-5
chore(deps): bump actions/checkout from 3 to 5
2025-10-01 11:50:10 +08:00
ElyPrism a719631607 Merge pull request #11 from NeteaseCloudMusicApiEnhanced/dependabot/github_actions/actions/setup-node-5
chore(deps): bump actions/setup-node from 3 to 5
2025-10-01 11:49:24 +08:00
dependabot[bot] e7d9d0fdf2 chore(packages): bump eslint-plugin-html from 7.1.0 to 8.1.3
Bumps [eslint-plugin-html](https://github.com/BenoitZugmeyer/eslint-plugin-html) from 7.1.0 to 8.1.3.
- [Changelog](https://github.com/BenoitZugmeyer/eslint-plugin-html/blob/main/CHANGELOG.md)
- [Commits](https://github.com/BenoitZugmeyer/eslint-plugin-html/compare/v7.1.0...v8.1.3)

---
updated-dependencies:
- dependency-name: eslint-plugin-html
  dependency-version: 8.1.3
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-30 11:57:34 +00:00
dependabot[bot] 27bba9ce55 chore(deps): bump docker/setup-buildx-action from 2 to 3
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-30 11:56:36 +00:00
dependabot[bot] 27562092b1 chore(deps): bump actions/checkout from 3 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-30 11:56:33 +00:00
dependabot[bot] 053640fd33 chore(deps): bump actions/setup-node from 3 to 5
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3 to 5.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v3...v5)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-30 11:56:28 +00:00
ElyPrism f7ad6b7d61 ci(bot): enable dependabot 2025-09-30 19:55:50 +08:00
ImFurina da6f590632 chore(package): update dependence 2025-09-30 19:52:17 +08:00
ImFurina 96148385c4 4.29.6 2025-09-30 19:52:01 +08:00
ImFurina 348b7569b8 4.29.5 2025-09-23 20:25:21 +08:00
ImFurina ea3acc0b14 feat(unblock): 新增bodian source 2025-09-23 20:19:47 +08:00
ImFurina 09f6b862fe chore(deps): 更新UNM至0.28.0 2025-09-23 20:12:45 +08:00
ImFurina 0535b88b24 chore(deps): 更新必要的依赖 2025-09-19 19:59:07 +08:00
ImFurina 9fe3a0f491 chores 2025-09-13 14:36:22 +08:00
ImFurinaandbinaryify b73685ace3 chore(deps): 更新axios依赖
Co-Authored-By: binaryify <binaryify@gmail.com>
2025-09-12 20:37:20 +08:00
ImFurina f16c92e825 chore(version): 更新版本号 2025-09-07 13:13:59 +08:00
ImFurinaandbinaryify abd0c9ca91 refactor: 重构模块加载
Refactored main.js to optimize module and server loading, improving code clarity and lazy loading. Updated several dependencies in package.json to their latest versions for better security and compatibility. Updated documentation cover page and home page to reflect project branding changes.

Co-Authored-By: binaryify <binaryify@gmail.com>
2025-09-07 13:08:26 +08:00
ImFurinaandbinaryify 4f4aa134d5 perf: 新增接口, 修复登录问题
Co-Authored-By: binaryify <binaryify@gmail.com>
2025-09-07 12:58:58 +08:00
557 changed files with 67808 additions and 35 deletions
+5
View File
@@ -0,0 +1,5 @@
# CodeGraph data files — local to each machine, not for committing.
# Ignore everything in .codegraph/ except this file itself, so transient
# files (the database, daemon.pid, sockets, logs) never show up in git.
*
!.gitignore
+15
View File
@@ -0,0 +1,15 @@
/**
!/module
!/plugins
!/public
!/static
!/util
!/app.js
!/server.js
!/package.json
!/index.js
!/generateConfig.js
!/main.js
!/data
!/.env
!/pnpm-lock.yaml
+34
View File
@@ -0,0 +1,34 @@
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
# Matches multiple files with brace expansion notation
# Set default charset
[*.{js,py}]
charset = utf-8
# 4 space indentation
[*.py]
indent_style = space
indent_size = 4
# Tab indentation (no size specified)
[Makefile]
indent_style = tab
# Indentation override for all JS under lib directory
[*.{js,ts}]
indent_style = space
indent_size = 2
# Matches the exact files either package.json or .travis.yml
[{package.json,.travis.yml}]
indent_style = space
indent_size = 2
+27
View File
@@ -0,0 +1,27 @@
### CORS资源共享设置
## 如果你需要配置, 请取消下面的注释并设置具体的域名
# CORS_ALLOW_ORIGIN = "*"
### 代理设置
## 启用反向代理
ENABLE_PROXY = false
## 代理配置
PROXY_URL = "https://your-proxy-url.com/?proxy="
### 随机IP设置
## 启用随机中国IP(默认关闭);启用后,所有请求默认使用随机中国IP,除非请求参数randomCNIP显式关闭
ENABLE_RANDOM_CN_IP = false
### UnblockNeteaseMusic 设置项
## 启用全局解灰, 无论是否调用参数都会使用解灰(不推荐开启)
ENABLE_GENERAL_UNBLOCK = false
## 歌曲启用无损音质
ENABLE_FLAC = true
## 启用无损音质时,是否选择音质最高的
SELECT_MAX_BR = false
## 严格按照配置音源设置顺序进行匹配
FOLLOW_SOURCE_ORDER = true
## Cookie设置项; 推荐在Vercel等平台进行环境变量的设置或者设置github secret
# 网易云 cookie
# 格式:MUSIC_U=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# NETEASE_COOKIE = ""
+1
View File
@@ -0,0 +1 @@
custom: ["https://rewards.focalors.ltd"]
+117
View File
@@ -0,0 +1,117 @@
name: 🐛 Bug报告
description: 报告API其中的错误或问题
title: "[Bug] "
labels: ["bug"]
assignees: []
body:
- type: markdown
attributes:
value: |
感谢您报告Bug!请填写以下信息帮助我们快速定位和修复问题。
- type: checkboxes
id: terms
attributes:
label: 确认事项
description: |
在提交Bug报告前,请确认以下事项:
- 我已经搜索了现有的issues,确认这不是重复问题
- 我使用的是最新版本的API, 而且是官方发布的版本,而不是fork或修改版
- 不处理别人搭建的线上服务的问题,此项目提供任何线上服务不保证质量
- 如果不是提建议,提 issues 如果不照着模版来将不会优先处理或放着不管
- 维护项目都是业余时间,精力有限,我只能挑容易解决的issues处理,为了节约双方时间,请尽可能提供足够的有用的信息,给的信息不够我只能根据精力和时间看情况处理,如果模板信息看都不看就删掉,我不会进行任何回复,并且一个月后close掉issue
options:
- label: 我已确认以上事项
required: true
- type: input
id: version
attributes:
label: API版本
description: 请提供您使用的API版本以及nodejs版本
placeholder: "v4.2x.x, Node.js v22.x.x"
validations:
required: true
- type: dropdown
id: deployment
attributes:
label: 部署方式
description: 此项目支持本地部署和云平台部署,您使用的是哪种方式?
options:
- 本机直接运行 (node / pm2)
- 本机 Docker 部署
- Vercel
- Heroku
- Railway
- 其他云平台 (请在描述中说明)
validations:
required: true
- type: textarea
id: bug-description
attributes:
label: Bug描述
description: 请详细描述您遇到的问题
placeholder: |
清晰简洁地描述bug的具体表现...
validations:
required: true
- type: textarea
id: reproduction-steps
attributes:
label: 重现步骤
description: 请提供详细的重现步骤
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: 期望行为
description: 请描述您期望发生的行为
placeholder: 清晰简洁地描述您期望应该发生什么...
validations:
required: true
- type: textarea
id: actual-behavior
attributes:
label: 实际行为
description: 请描述实际发生的行为
placeholder: 清晰简洁地描述实际发生了什么...
validations:
required: true
- type: textarea
id: error-output
attributes:
label: 错误输出日志
description: 请提供完整的错误信息日志
render: shell
placeholder: |
错误信息输出...
- type: textarea
id: additional-context
attributes:
label: 额外信息
description: 添加任何其他有助于理解问题的信息
placeholder: |
- 截图
- 相关配置文件
- 其他相关信息
- type: checkboxes
id: help
attributes:
label: 愿意协助
description: 您是否愿意帮助修复这个bug?
options:
- label: 我愿意提交PR来修复这个bug
- label: 我可以提供更多测试用例
- label: 我可以帮助测试修复方案
+8
View File
@@ -0,0 +1,8 @@
blank_issues_enabled: true
contact_links:
- name: ↑请尽量使用议题模板创建议题↑
url: https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced/issues/new/choose
about: 选择适合的议题模板可以帮助我们更快地定位和解决问题
- name: 提问的艺术
url: https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md
about: 默认所有 Issues 发起者均已了解此处的内容
@@ -0,0 +1,73 @@
name: ✨ 接口添加请求
description: 希望添加新接口
title: "[Feature] "
labels: ["enhancement"]
assignees: []
body:
- type: markdown
attributes:
value: |
感谢您提出新功能建议!请填写以下信息帮助我们理解您的需求。
- type: checkboxes
id: terms
attributes:
label: 确认事项
description: |
在提交功能请求前,请确认以下事项
- 我已经搜索了现有的issues,确认这不是重复请求
- 我已经查看了项目文档
- 该项目符合该项目的目标和范围
- 我确认我提供的接口请求是合理且有意义的
options:
- label: 我已确认以上事项
required: true
- type: textarea
id: proposed-solution
attributes:
label: 功能描述
description: 请详细描述您希望添加的功能,最好贴上对应客户端界面的截图
placeholder: |
请详细描述您期望的功能:
- 新的网易云音乐api 接口?
validations:
required: true
- type: dropdown
id: priority
attributes:
label: 优先级
description: 您认为这个功能的优先级如何?
options:
- 低 (可有可无的改进)
- 中 (会显著改善使用体验)
- 高 (严重影响了我使用)
- 紧急 (阻塞了重要工作)
validations:
required: true
- type: textarea
id: compatibility
attributes:
label: 兼容性考虑
description: 这个功能是否会影响现有代码的兼容性?
placeholder: |
- 是否是破坏性变更?
- 是否需要语法变更?
- 对性能的影响?
- type: checkboxes
id: implementation
attributes:
label: 实现意愿
description: 您是否愿意参与这个功能的实现?
options:
- label: 我愿意提交PR来实现这个功能
- label: 我可以协助设计API接口
- label: 我可以提供测试用例
- label: 我可以帮助编写文档
+41
View File
@@ -0,0 +1,41 @@
# .github/dependabot.yml
version: 2
updates:
# 更新 npm (JavaScript) 依赖
- package-ecosystem: "npm"
directory: "/" # package.json 所在的位置
schedule:
interval: "weekly" # 每周一检查
# 默认情况下,Dependabot 会自动获取最新版本。
# 你可以使用 `ignore` 来排除某些特定更新
ignore:
- dependency-name: "eslint"
# 对于 ESLint,忽略主版本 8 以上的所有更新
versions: ["> 8"]
# 自动合并小版本更新的 PR (可选)
# 可以设置针对 patch 或 minor 版本更新自动合并
commit-message:
prefix: "build(packages):" # PR 合并提交信息的前缀
# 更新 GitHub Actions 依赖
- package-ecosystem: "github-actions"
directory: "/" # .github/workflows/ 目录所在的位置
schedule:
interval: "monthly"
# 更新 Python (pip) 依赖,如果你的项目有 requirements.txt
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
# 如果你有多个目录(例如一个 monorepo),可以为每个目录单独配置
# - package-ecosystem: "npm"
# directory: "/packages/frontend"
# schedule:
# interval: "weekly"
# - package-ecosystem: "npm"
# directory: "/packages/backend"
# schedule:
# interval: "weekly"
+53
View File
@@ -0,0 +1,53 @@
name: Build Artifacts
on:
workflow_dispatch: # 手动触发
push:
branches: [main]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
include:
- os: ubuntu-latest
platform: linux
target: node18-linux-x64
output: precompiled/app
- os: windows-latest
platform: win
target: node18-win-x64
output: precompiled/app.exe
- os: macos-latest
platform: macos
target: node18-macos-x64
output: precompiled/app
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '18'
- name: Install dependencies
run: |
npm install -g pnpm
pnpm install
- name: Build for ${{ matrix.platform }}
run: |
npm run pkg${{ matrix.platform }}
env:
PKG_TARGET: ${{ matrix.target }}
- name: Upload artifacts
uses: actions/upload-artifact@v7
with:
name: app-${{ matrix.platform }}
path: ${{ matrix.output }}
if-no-files-found: error
+67
View File
@@ -0,0 +1,67 @@
name: CI
on:
push:
branches: [main]
pull_request:
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
check:
name: Lint / Unit / Docs
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 22, 24]
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
with:
version: 9
- uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
cache: pnpm
# frozen-lockfile: 顺带校验 package.json 与 pnpm-lock.yaml 是否一致
- name: Install dependencies (frozen lockfile)
run: pnpm install --frozen-lockfile
- name: Lint
run: pnpm lint
# 纯单测,不需要网络,稳定必过
- name: Unit tests
run: pnpm exec mocha -r intelli-espower-loader -t 60000 main.test.js --exit
- name: Docs format check
run: pnpm docs:check
integration:
# server.test.js 会启动真实服务器并请求真实网易云 API,
# 可能因上游风控/限流偶发失败,因此不阻塞合并
name: Integration tests (real NetEase API)
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
with:
version: 9
- uses: actions/setup-node@v6
with:
node-version: 22
cache: pnpm
- name: Install dependencies (frozen lockfile)
run: pnpm install --frozen-lockfile
- name: Run full test suite
run: pnpm test
+54
View File
@@ -0,0 +1,54 @@
name: Issue Management
permissions:
issues: write
contents: read
on:
issues:
types: [opened, labeled]
jobs:
welcome-new-issues:
if: github.event.action == 'opened'
runs-on: ubuntu-latest
steps:
- name: Welcome new issue
uses: peter-evans/create-or-update-comment@v5
with:
issue-number: ${{ github.event.issue.number }}
body: |
感谢您在该仓库提出问题!我们非常重视您的反馈,并希望尽快为您提供帮助。
如果您在一周左右的时间里没有收到我们的回复,请在下方留言,以便我们注意到。我们的大部分审核都是志愿者,有时难免会有疏漏。
你可能会想要尝试以下方法来获得更快的帮助:
- 📖 查看[项目文档](https://neteasecloudmusicapienhanced.js.org)
- 💬 加入[QQ交流群](https://qm.qq.com/q/TpeP9Uv2yk)
- 🔍 搜索[现有issues](https://github.com/neteasecloudmusicapienhanced/api-enhanced/issues) 看是否有类似问题
stale-issues:
if: github.event.action == 'opened'
runs-on: ubuntu-latest
steps:
- name: Mark stale issues
uses: actions/stale@v10
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: |
这个issue已经30天没有活动了。
如果这个问题仍然存在,请回复此评论说明当前状态。
否则,这个issue将在7天后自动关闭。
您可以随时重新打开已关闭的issue。
stale-pr-message: |
这个PR已经30天没有活动了。
如果您仍在处理这个PR,请回复此评论。
否则,这个PR将在7天后自动关闭。
days-before-stale: 30
days-before-close: 7
stale-issue-label: "stale"
stale-pr-label: "stale"
exempt-issue-labels: "pinned,enhancement,priority:high,ongoing,fatal"
exempt-pr-labels: "pinned,priority:high,ongoing,fatal"
+67
View File
@@ -0,0 +1,67 @@
name: OpenCode Automation
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: write
issues: write
pull-requests: write
concurrency:
group: auto-${{ github.event.issue.number || github.event.pull_request.number }}
cancel-in-progress: false
jobs:
automate:
# 排除其他机器人触发,防止自我循环;
# 但允许 takanashi-hoshino-agent 创建的 PR,这样 /oc 生成的测试 PR 也能被自动评审
if: |
github.actor != 'github-actions[bot]' &&
github.actor != 'opencode-agent[bot]'
runs-on: ubuntu-latest
steps:
- name: Fetch config from CF Worker
id: cfg
uses: MoeFurina/pull-oc-config@v1
with:
url: https://bot-storage.interface.focalors.ltd/config
- name: Generate bot token
id: token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ steps.cfg.outputs.app_id }}
private-key: ${{ steps.cfg.outputs.app_private_key }}
owner: ${{ github.repository_owner }}
- name: Checkout
uses: actions/checkout@v6
with:
token: ${{ steps.token.outputs.token }}
fetch-depth: 0
persist-credentials: true
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 22
- name: Install opencode
run: npm i -g opencode-ai@latest
- name: Run automation
env:
GITHUB_TOKEN: ${{ steps.token.outputs.token }}
MODEL: opencode/deepseek-v4-flash-free
OPENCODE_API_KEY: ${{ steps.cfg.outputs.opencode_api_key }}
ISSUE_PROMPT: ${{ steps.cfg.outputs.opencode_prompt }}
PR_PROMPT: |
${{ steps.cfg.outputs.opencode_prompt }}
${{ steps.cfg.outputs.pr_review_prompt }}
run: |
mkdir -p scripts
curl -fsSL "https://raw.githubusercontent.com/MoeFurina/pull-oc-config/v1/scripts/opencode-automation.mjs" \
-o scripts/opencode-automation.mjs
node scripts/opencode-automation.mjs
+66
View File
@@ -0,0 +1,66 @@
name: opencode
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
permissions:
contents: write
issues: write
pull-requests: write
jobs:
bot:
if: |
(contains(github.event.comment.body, ' /oc') ||
startsWith(github.event.comment.body, '/oc') ||
contains(github.event.comment.body, ' /opencode') ||
startsWith(github.event.comment.body, '/opencode')) &&
github.actor != 'opencode-agent[bot]' &&
github.actor != 'takanashi-hoshino-agent[bot]' &&
github.actor != 'github-actions[bot]'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Fetch config from CF Worker
id: cfg
uses: MoeFurina/pull-oc-config@v1
with:
url: https://bot-storage.interface.focalors.ltd/config
- name: Generate bot token
id: token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ steps.cfg.outputs.app_id }}
private-key: ${{ steps.cfg.outputs.app_private_key }}
owner: ${{ github.repository_owner }}
- name: Checkout
uses: actions/checkout@v6
with:
# 需要持久化凭证: opencode action 内部会 git fetch origin <分支> 拉取 PR 代码
persist-credentials: true
token: ${{ steps.token.outputs.token }}
- name: Configure git identity
run: |
git config --global user.name "takanashi-hoshino-agent[bot]"
git config --global user.email "takanashi-hoshino-agent[bot]@users.noreply.github.com"
- name: Run opencode
uses: anomalyco/opencode/github@latest
env:
OPENCODE_API_KEY: ${{ steps.cfg.outputs.opencode_api_key }}
GITHUB_TOKEN: ${{ steps.token.outputs.token }}
with:
model: opencode/deepseek-v4-flash-free
use_github_token: true
prompt: |
${{ steps.cfg.outputs.opencode_prompt }}
## 用户指令(来自触发评论,请严格按此执行)
${{ github.event.comment.body }}
@@ -0,0 +1,315 @@
name: Create Release on Version Change
on:
push:
branches:
- main
paths:
- package.json
workflow_dispatch:
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
jobs:
detect:
name: Detect Version Change
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.value }}
should_release: ${{ steps.check.outputs.should_release }}
tag_exists: ${{ steps.tagcheck.outputs.exists }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Extract version from package.json
id: version
run: |
echo "value=$(jq -r .version package.json)" >> $GITHUB_OUTPUT
- name: Check if version changed
id: check
shell: bash
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
echo "should_release=true" >> $GITHUB_OUTPUT
exit 0
fi
if git diff "${{ github.event.before }}" "${{ github.sha }}" -- package.json | grep -q '"version"'; then
echo "should_release=true" >> $GITHUB_OUTPUT
else
echo "should_release=false" >> $GITHUB_OUTPUT
fi
- name: Check if tag already exists
id: tagcheck
shell: bash
run: |
VERSION="${{ steps.version.outputs.value }}"
if git rev-parse "v$VERSION" >/dev/null 2>&1; then
echo "exists=true" >> $GITHUB_OUTPUT
else
echo "exists=false" >> $GITHUB_OUTPUT
fi
build:
name: Build ${{ matrix.platform }}
needs: detect
if: |
needs.detect.outputs.should_release == 'true' &&
needs.detect.outputs.tag_exists != 'true'
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
platform: linux
target: node18-linux-x64
output: ncm-api-linux-x64
- os: windows-latest
platform: windows
target: node18-win-x64
output: ncm-api-win-x64.exe
- os: macos-latest
platform: macos
target: node18-macos-x64
output: ncm-api-macos-x64
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup pnpm
uses: pnpm/action-setup@v6
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build binary
shell: bash
env:
PKG_TARGET: ${{ matrix.target }}
run: |
mkdir -p release-artifacts
case "${{ matrix.platform }}" in
linux)
npm run pkglinux
mv precompiled/app "release-artifacts/${{ matrix.output }}"
;;
windows)
npm run pkgwin
mv precompiled/app.exe "release-artifacts/${{ matrix.output }}"
;;
macos)
npm run pkgmacos
mv precompiled/app "release-artifacts/${{ matrix.output }}"
;;
esac
- name: Upload build artifact
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.platform }}-binary
path: release-artifacts/*
release:
name: Create GitHub Release
needs:
- detect
- build
if: |
needs.detect.outputs.should_release == 'true' &&
needs.detect.outputs.tag_exists != 'true'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
fetch-tags: true
- name: Download build artifacts
uses: actions/download-artifact@v8
with:
path: release-artifacts
merge-multiple: true
- name: List flattened artifacts
shell: bash
run: |
mkdir -p final-artifacts
cp release-artifacts/* final-artifacts/
ls -lah final-artifacts
- name: Generate release notes
shell: bash
run: |
VERSION="${{ needs.detect.outputs.version }}"
PREV_TAG=$(git tag --sort=-v:refname | head -1)
{
echo "# Release v${VERSION}"
echo ""
echo "## 更新内容 / Changelog"
echo ""
if [ -n "$PREV_TAG" ]; then
echo "从 \`$PREV_TAG\` 到 \`v$VERSION\` 的提交记录:"
echo ""
git log "$PREV_TAG..HEAD" \
--no-merges \
--pretty=format:"- %s (%h)"
else
echo "首次发布,包含以下提交:"
echo ""
git log \
--no-merges \
--pretty=format:"- %s (%h)"
fi
echo ""
echo ""
echo "---"
echo "自动发布 via GitHub Actions"
} > release-notes.md
cat release-notes.md
- name: Create Git tag
run: |
git tag "v${{ needs.detect.outputs.version }}"
git push origin "v${{ needs.detect.outputs.version }}"
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ needs.detect.outputs.version }}
name: Release v${{ needs.detect.outputs.version }}
body_path: release-notes.md
files: final-artifacts/*
draft: false
prerelease: false
publish-docker:
name: Publish Docker Image
needs: detect
if: |
needs.detect.outputs.should_release == 'true' &&
needs.detect.outputs.tag_exists != 'true'
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Read package version
id: pkg
run: echo "VERSION=$(jq -r .version package.json)" >> $GITHUB_ENV
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v7
with:
context: .
push: true
tags: |
moefurina/ncm-api:latest
moefurina/ncm-api:${{ env.VERSION }}
ghcr.io/neteasecloudmusicapienhanced/ncm-api:latest
ghcr.io/neteasecloudmusicapienhanced/ncm-api:${{ env.VERSION }}
platforms: linux/amd64,linux/arm64/v8
publish-npm:
name: Publish to npm
needs: detect
if: |
needs.detect.outputs.should_release == 'true' &&
needs.detect.outputs.tag_exists != 'true'
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
with:
version: 9
- uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm publish --access public --provenance
+36
View File
@@ -0,0 +1,36 @@
name: Upstream Sync
permissions:
contents: write
on:
schedule:
- cron: "0 4 * * *" # At 12PM UTC+8
workflow_dispatch:
jobs:
sync_latest_from_upstream:
name: Sync latest commits from upstream repo
runs-on: ubuntu-latest
if: ${{ github.event.repository.fork }}
steps:
# Step 1: run a standard checkout action
- name: Checkout target repo
uses: actions/checkout@v6
# Step 2: run the sync action
- name: Sync upstream changes
id: sync
uses: aormsby/Fork-Sync-With-Upstream-action@v3.4.3
with:
upstream_sync_repo: NeteaseCloudMusicApiEnhanced/api-enhanced
upstream_sync_branch: main
target_sync_branch: main
target_repo_token: ${{ secrets.GITHUB_TOKEN }}
- name: Sync check
if: failure()
run: |
echo "[Error] Due to a change in the workflow file of the upstream repository, GitHub has automatically suspended the scheduled automatic update. You need to manually sync your fork."
exit 1
+13 -1
View File
@@ -1 +1,13 @@
node_modules/
.DS_Store
node_modules
*.log
.idea
.vscode
.history
examples/moddef.json
bin
anonymous_token
.vercel
.env
IFLOW.md
precompiled
+1
View File
@@ -0,0 +1 @@
node_modules
+5
View File
@@ -0,0 +1,5 @@
{
"semi": false,
"trailingComma": "all",
"singleQuote": true
}
+4
View File
@@ -0,0 +1,4 @@
language: node_js
node_js:
- 22
+40
View File
@@ -0,0 +1,40 @@
# NeteaseCloudMusicApiEnhanced Agent 说明
## 快速开始
- **包管理器**:开发与 CI 使用 `pnpm`,`Dockerfile` 也用 pnpm(`pnpm@9 --frozen-lockfile`,匹配 `pnpm-lock.yaml`)。仓库没有 `yarn.lock`,不要引入 yarn。
- **Node 版本**:README 推荐 Node 22+;`package.json` 的 `engines` 声明 `>=12`;CI/打包在 Node 18–24 上运行。现代 Node 均可。
- **环境变量**:`server.js` 调用了 `dotenv.config()`,本地 `.env` 会被自动加载;所有支持的变量见 `.env.prod.example`。
## 常用命令
- 安装依赖:`pnpm i`
- 启动服务:`pnpm start`(等价 `node app.js`);热重载开发:`pnpm dev`(nodemon)
- 跑测试:`pnpm test`(Mocha,超时 60s)
- Lint:`pnpm lint`;自动修复:`pnpm lint-fix`
- 文档格式化检查/修复:`pnpm docs:check` / `pnpm docs:format`
- 打包独立二进制:`pnpm pkgwin` / `pkglinux` / `pkgmacos`
## 架构
- `app.js`(也是 `bin`)——服务入口。先确保 `os.tmpdir()` 里存在 `anonymous_token`,执行 `generateConfig()` 刷新匿名 cookie 与 xeapi 公钥,再调用 `server.serveNcmApi()`。
- `server.js`——Express 工厂。`constructServer()` 自动扫描 `module/*.js`,每个文件注册一条路由(文件名 `_` 转 `/`,如 `album_new.js` → `/album/new`;特例 `daily_signin`/`fm_trash`/`personal_fm` 硬编码在 `server.js` 的 `special` 对象里)。`serveNcmApi()` 监听 `PORT`(默认 3000)/`HOST`。
- `main.js`——作为依赖被引入时的入口(`main` 字段)。把每个 `module/*` 导出为同名函数 `name(data)`,另导出 `server`、`serveNcmApi`、`getModulesDefinitions`。
- `module/*.js`——每个接口一个文件,标准写法:`module.exports = (query, request) => request(path, data, createOption(query))`。`createOption` 在 `util/option.js`,负责 crypto、cookie(回退到 `NETEASE_COOKIE`)、proxy、realIP/randomCNIP、headers、timeout。
- `util/request.js`——唯一的对外 HTTP 层(axios)。按 `crypto`(`api`/`eapi`/`weapi`/`linuxapi`/`xeapi`)加密并设置 IP 头;在 require 时同步读取 `os.tmpdir()` 里的 `anonymous_token` 与 `xeapi_public_key`。
- `util/config.json`——运行时配置:网易域名 + `APP_CONF.encrypt: true`(默认走 eapi 加密)。已被 git 跟踪,改动会改变全局默认行为。
- `index.js` / `index.mjs`——`require('./app.js')` 的薄包装,供 Vercel(`vercel.json`)和 ESM 导入使用。
## 新增/修改接口
- 新建 `module/xxx.js` 会自动挂载路由,无需注册;**文件名即路由**。
- 照抄同目录模块的写法(选对 `crypto`),用 `createOption(query)` 生成请求选项。
- 改文件名/路由会破坏已有客户端,尽量保持旧路径兼容。
## 测试
- `pnpm test` 跑 `server.test.js` + `main.test.js`。`server.test.js` 在 `before()` 里启动真实服务器,`test/*.test.js` 全部请求**真实网易云 API**——必须联网,且可能因上游风控/限流偶发失败。`main.test.js` 是纯单测。
- 测试使用 `power-assert`(经 `intelli-espower-loader`),普通 `assert` 写法也会输出详细 diff。
- 只跑单个用例:`pnpm exec mocha -r intelli-espower-loader -t 60000 --grep "<describe/it 名字>" server.test.js main.test.js --exit`
## 坑与注意
- **改 `package.json` 的 `version` 会触发自动发布**:push 到 `main` 后会自动打 GitHub Release(`pkg` 二进制)、构建并推送 Docker 镜像(Docker Hub + GHCR)、`pnpm publish` 到 npm。别顺手改版本号。
- **没有实际 git hooks**:`package.json` 里配了 `lint-staged`,但 `.husky/` 下没有真正的 hook,commit 时不会自动跑任何检查,自己记得 `pnpm lint-fix`。
- **代理环境变量已失效**:README 里关于 `http_proxy`/`https_proxy` 的警告来自旧 `request` 库时代;现在 `util/request.js` 用 axios + 自定义 keep-alive agent,且显式 `proxy: false`,环境变量代理不会生效。按请求走 `query.proxy` 参数(支持 PAC 和 http 隧道)。
- **启动令牌在系统临时目录**:`anonymous_token`、`xeapi_public_key` 存放在 `os.tmpdir()`,`util/request.js` 在 require 时同步读取。文件过期或被清空就重启服务(或调用 `generateConfig()`);首次启动先写空文件再刷新。
- **ESLint 9 flat config**:`eslint.config.js`,风格由 `eslint-plugin-prettier` 强制(2 空格缩进、单引号、分号、`endOfLine: auto`)。
-1
View File
@@ -1 +0,0 @@
neteasecloudmusicapienhanced.js.org
+21
View File
@@ -0,0 +1,21 @@
FROM node:lts-alpine
RUN apk add --no-cache tini
ENV NODE_ENV=production
RUN npm install -g pnpm@9
USER node
WORKDIR /app
COPY --chown=node:node . ./
# --prod 模式下 husky 不会被安装,prepare 脚本会因找不到 husky 而失败,
# 故显式跳过生命周期脚本;本项目生产运行也不依赖任何 postinstall 步骤。
RUN pnpm install --frozen-lockfile --prod --ignore-scripts
EXPOSE 3000
CMD [ "/sbin/tini", "--", "node", "app.js" ]
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2013-2022 Binaryify
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+253
View File
@@ -0,0 +1,253 @@
<p align="center">
<img src="./public/static/neteaselogo.png" alt="网易云音乐 API Enhanced Logo" />
</p>
<p align="center">
<a href="https://www.npmjs.com/package/@neteasecloudmusicapienhanced/api">
<img src="https://img.shields.io/npm/v/@neteasecloudmusicapienhanced/api?style=flat-square" alt="NPM Version" />
</a>
<a href="https://www.npmjs.com/package/@neteasecloudmusicapienhanced/api">
<img src="https://img.shields.io/npm/dm/@neteasecloudmusicapienhanced/api?style=flat-square" alt="NPM Downloads" />
</a>
<a href="https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced">
<img src="https://img.shields.io/github/license/NeteaseCloudMusicApiEnhanced/api-enhanced?style=flat-square" alt="License" />
</a>
<a href="https://nodejs.org/">
<img src="https://img.shields.io/node/v/@neteasecloudmusicapienhanced/api?style=flat-square" alt="Node Version" />
</a>
<a href="https://hub.docker.com/r/moefurina/ncm-api">
<img src="https://img.shields.io/docker/v/moefurina/ncm-api?style=flat-square" alt="Docker Version" />
</a>
<a href="https://hub.docker.com/r/moefurina/ncm-api">
<img src="https://img.shields.io/docker/pulls/moefurina/ncm-api?style=flat-square" alt="Docker Pulls" />
</a>
<a href="https://www.typescriptlang.org/">
<img src="https://img.shields.io/badge/TypeScript-Ready-blue?style=flat-square&logo=typescript" alt="TypeScript" />
</a>
</p>
## 项目简介
网易云音乐第三方 Node.js API, 支持丰富的音乐相关接口,适合自建服务、二次开发和多平台部署
> [!IMPORTANT]
>
> ## 注意
>
> - 本项目是自由项目, 不带任何担保, 在基于`MIT License`的许可下, 任何人都可以自由使用、修改和分发本项目的代码, 包括用于商业目的.
> - 该项目是个合作计划, 有很多人参与了此次贡献, 前往 [Contributors](https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced/graphs/contributors) 页面查看所有贡献者
> - 原作者项目 [Binaryify/NeteaseCloudMusicApi](https://github.com/binaryify/NeteaseCloudMusicApi) 并非完全停止维护, 你可以在 [NeteaseCloudMusicApi 的 NPMJS 页面](https://www.npmjs.com/package/NeteaseCloudMusicApi) 查看最新版本信息。
> - 感谢尊重和理解!
## 快速开始
### 环境要求
- Node.js 22 及以上
- 推荐使用 pnpm 进行依赖管理
### 安装
```bash
git clone https://github.com/neteasecloudmusicapienhanced/api-enhanced.git
cd api-enhanced
pnpm i
```
### 启动服务
```bash
# 默认端口 3000
node app.js
# 指定端口(如 4000)
PORT=4000 node app.js # Mac/Linux
set PORT=4000 && node app.js # Windows
```
### 重要提示
- 调用前请务必阅读文档的 [调用前须知](https://neteasecloudmusicapienhanced.js.org/#/?id=%e8%b0%83%e7%94%a8%e5%89%8d%e9%a1%bb%e7%9f%a5) 部分。
- 推荐将敏感信息(如 cookie)通过部署平台的环境变量进行配置。
## 在线体验与文档
- [在线文档](https://neteasecloudmusicapienhanced.js.org/)
- [NPM 包地址](https://www.npmjs.com/package/@neteasecloudmusicapienhanced/api)
- [Dockerhub 主页](https://hub.docker.com/r/moefurina/ncm-api)
## 常见部署方式
- 推荐参考[在线文档](https://neteasecloudmusicapienhanced.js.org/)
## Docker 部署说明
本项目支持通过 Docker 一键部署,无需手动安装 Node.js 或依赖。
> 注意: 在 docker 中运行的时候, 由于使用了 request 来发请求, 所以会检查几个 proxy 相关的环境变量(如下所列), 这些环境变量 会影响到 request 的代理, 详情请参考[request 的文档](https://github.com/request/request#proxies), 如果这些环境变量 指向的代理不可用, 那么就会造成错误, 所以在使用 docker 的时候一定要注意这些环境变量. 不过, 要是你在 query 中加上了 proxy 参数, 那么环境变量会被覆盖, 就会用你通过 proxy 参数提供的代理了.
request 相关的环境变量
1. http_proxy
2. https_proxy
3. HTTP_PROXY
4. HTTPS_PROXY
5. no_proxy
6. NO_PROXY
```shell
docker pull moefurina/ncm-api:latest
docker run -d -p 3000:3000 --name ncm-api moefurina/ncm-api:latest
// 或者
docker run -d -p 3000:3000 moefurina/ncm-api:latest
// 去掉或者设置相关的环境变量
docker run -d -p 3000:3000 --name ncm-api -e http_proxy= -e https_proxy= -e no_proxy= -e HTTP_PROXY= -e HTTPS_PROXY= -e NO_PROXY= moefurina/ncm-api:latest
// 或者
docker run -d -p 3000:3000 -e http_proxy= -e https_proxy= -e no_proxy= -e HTTP_PROXY= -e HTTPS_PROXY= -e NO_PROXY= moefurina/ncm-api:latest
```
> 以下是自行 build docker 镜像方式
```shell
$ git clone https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced && cd api-enhanced
$ sudo docker build . -t ncm-api
$ sudo docker run -d -p 3000:3000 ncm-api
```
## 3. 环境变量
| 变量名 | 默认值 | 说明 |
|----------------------------|--------------------------------------|----------------------------------------------------|
| **CORS_ALLOW_ORIGIN** | `*` | 允许跨域请求的域名。可填写单个源,或使用逗号分隔多个源(例如 `https://a.com,https://b.com`)。 |
| **ENABLE_PROXY** | `false` | 是否启用反向代理功能。 |
| **PROXY_URL** | `https://your-proxy-url.com/?proxy=` | 代理服务地址。仅当 `ENABLE_PROXY=true` 时生效。 |
| **ENABLE_RANDOM_CN_IP** | `false` | 是否默认启用随机中国IP。启用后,所有请求默认使用随机中国IP,除非请求参数 `randomCNIP` 显式关闭。 |
| **ENABLE_GENERAL_UNBLOCK** | `true` | 是否启用全局解灰(推荐开启)。开启后所有歌曲都尝试自动解锁。 |
| **ENABLE_FLAC** | `true` | 是否启用无损音质(FLAC)。 |
| **SELECT_MAX_BR** | `false` | 启用无损音质时,是否选择最高码率音质。 |
| **FOLLOW_SOURCE_ORDER** | `true` | 是否严格按照音源列表顺序进行匹配。 |
---
### 4. 更新镜像
更新到最新版本:
```bash
docker pull moefurina/ncm-api:latest
docker stop ncm-api && docker rm ncm-api
docker run -d -p 3000:3000 moefurina/ncm-api:latest
```
## Vercel 一键部署
1. fork 本项目
2. 在 Vercel 官网新建项目,导入 fork 的仓库
3. 直接 Deploy
## 腾讯云 Serverless 部署
1. fork 本项目
2. 在腾讯云 serverless 控制台新建 Web 应用,选择 Express 框架
3. 代码仓库选择 fork 的项目,启动文件填写:
```bash
#!/bin/bash
export PORT=9000
/var/lang/node16/bin/node app.js
```
4. 完成部署后,访问 API 网关的 URL 即可
## Node.js 方式调用
支持直接在 Node.js 项目中引入和调用,返回 Promise:
```js
const {
login_cellphone,
user_cloud,
} = require('@neteasecloudmusicapienhanced/api')
async function main() {
const result = await login_cellphone({ phone: '手机号', password: '密码' })
console.log(result)
const result2 = await user_cloud({ cookie: result.body.cookie })
console.log(result2.body)
}
main()
```
## TypeScript 支持
```ts
import { banner } from '@neteasecloudmusicapienhanced/api'
banner({ type: 0 }).then((res) => console.log(res))
```
## 单元测试
```bash
pnpm test
```
## 主要功能特性
- 登录/注册/验证码
- 用户信息、歌单、动态、播放记录
- 歌曲、专辑、歌手、MV、歌词、评论、排行榜
- 搜索、推荐、私人 FM、签到、云盘
- 歌曲解锁(解灰)
## 贡献与社区
- 欢迎提交 PR、Issue 参与维护
- 要贡献新接口, 请参考[这篇文章](https://www.focalors.ltd/post/how-to-contribute-ncm-api)
### 致谢
原作者 [Binaryify/NeteaseCloudMusicApi](https://github.com/binaryify/NeteaseCloudMusicApi) 项目为本项目基础 (该项目在`npmjs`网站上仍持续维护, 但 github 仓库已不再更新)
感谢大佬们为逆向eapi, weapi, xeapi等加密算法所做的贡献
项目参考:
[trazyn/ieaseMusic](https://github.com/trazyn/ieaseMusic)
[listen1/listen1_chrome_extension](https://github.com/listen1/listen1_chrome_extension)
[chaunsin/netease-cloud-music](https://github.com/chaunsin/netease-cloud-music)
[folltoshe/netease-report-listen-song](https://github.com/folltoshe/netease-report-listen-song)
### SDK 生态
| 语言 | 作者 | 地址 | 类型 |
|--------|---------------------------------------------|------------------------------------------------------------------------------------------|-----|
| Java | [JackuXL](https://github.com/JackuXL) | [NeteaseCloudMusicApi-SDK](https://github.com/JackuXL/NeteaseCloudMusicApi-SDK) | 第三方 |
| Java | [1015770492](https://github.com/1015770492) | [yumbo-music-utils](https://github.com/1015770492/yumbo-music-utils) | 第三方 |
| Python | [盧瞳](https://github.com/2061360308) | [NeteaseCloudMusic_PythonSDK](https://github.com/2061360308/NeteaseCloudMusic_PythonSDK) | 第三方 |
| Swift | [Lincb522](https://github.com/Lincb522) | [NeteaseCloudMusicApi-Swift](https://github.com/Lincb522/NeteaseCloudMusicAPI-Swift) | 第三方 |
| Rust | [SPlayer-Dev](https://github.com/splayer-dev) | [ncm-api-rs](https://github.com/SPlayer-Dev/ncm-api-rs) | 第三方 |
### 依赖此项目的优秀开源项目
- [qier2222/YesPlayMusic](https://github.com/qier222/YesPlayMusic)
- [MaigoLabs/amaoke.app](https://github.com/MaigoLabs/amaoke.app)
- [Yueby/music-together](https://github.com/Yueby/music-together)
- [chthollyphlie/folia-major](https://github.com/chthollyphile/folia-major)
## License
[MIT License](https://github.com/MoeFurina/NeteaseCloudMusicApiEnhanced/blob/main/LICENSE)
-4
View File
@@ -1,4 +0,0 @@
## 这是什么
这是网易云音乐api enhanced的文档页面
## [前往](https://docs-neteasecloudmusicapi.focalors.ltd)
Executable
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env node
const fs = require('fs')
const path = require('path')
const tmpPath = require('os').tmpdir()
async function start() {
// 检测是否存在 anonymous_token 文件,没有则生成
if (!fs.existsSync(path.resolve(tmpPath, 'anonymous_token'))) {
fs.writeFileSync(path.resolve(tmpPath, 'anonymous_token'), '', 'utf-8')
}
// 启动时更新anonymous_token
const generateConfig = require('./generateConfig')
await generateConfig()
require('./server').serveNcmApi({
checkVersion: true,
})
}
start()
File diff suppressed because it is too large Load Diff
+24641
View File
File diff suppressed because it is too large Load Diff
+91
View File
@@ -0,0 +1,91 @@
const { defineConfig, globalIgnores } = require('eslint/config')
const html = require('eslint-plugin-html')
const globals = require('globals')
const tsParser = require('@typescript-eslint/parser')
const js = require('@eslint/js')
const { FlatCompat } = require('@eslint/eslintrc')
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
})
module.exports = defineConfig([
{
languageOptions: {
ecmaVersion: 2020,
sourceType: 'module',
parserOptions: {
parser: 'babel-eslint',
},
globals: {
...globals.browser,
...globals.node,
},
},
plugins: {
html,
},
extends: compat.extends('plugin:prettier/recommended'),
rules: {
'prettier/prettier': [
'error',
{
endOfLine: 'auto',
},
],
indent: [
'error',
2,
{
SwitchCase: 1,
},
],
'space-infix-ops': [
'error',
{
int32Hint: false,
},
],
'key-spacing': [
2,
{
beforeColon: false,
afterColon: true,
},
],
'no-octal': 2,
'no-redeclare': 2,
'comma-spacing': 2,
'no-new-object': 2,
'arrow-spacing': 2,
quotes: [
2,
'single',
{
avoidEscape: true,
allowTemplateLiterals: true,
},
],
},
},
globalIgnores(['**/public/']),
{
files: ['**/*.ts'],
languageOptions: {
parser: tsParser,
},
extends: compat.extends('plugin:@typescript-eslint/recommended'),
},
])
+23
View File
@@ -0,0 +1,23 @@
const fsPromises = require('fs/promises')
const path = require('path')
const server = require('../server')
const logger = require('../util/logger.js')
const exportFile = path.join(__dirname, 'moddef.json')
async function main() {
const def = await server.getModulesDefinitions(
path.join(__dirname, '..', 'module'),
{
'daily_signin.js': '/daily_signin',
'fm_trash.js': '/fm_trash',
'personal_fm.js': '/personal_fm',
},
false,
)
fsPromises.writeFile(exportFile, JSON.stringify(def, null, 4))
logger.info(`👍 Get your own definition at: ${exportFile}`)
}
main()
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

+41
View File
@@ -0,0 +1,41 @@
const fs = require('fs')
const path = require('path')
const { register_anonimous } = require('./main')
const { cookieToJson, generateRandomChineseIP } = require('./util/index')
const { getXeapiPublicKey } = require('./util/xeapiKey')
const tmpPath = require('os').tmpdir()
async function generateConfig() {
global.cnIp = generateRandomChineseIP()
try {
const res = await register_anonimous()
const cookie = res.body.cookie
if (cookie) {
const cookieObj = cookieToJson(cookie)
fs.writeFileSync(
path.resolve(tmpPath, 'anonymous_token'),
cookieObj.MUSIC_A,
'utf-8',
)
}
} catch (error) {
console.log(error)
}
try {
let currentPublicKey = {}
try {
currentPublicKey = JSON.parse(
fs.readFileSync(path.resolve(tmpPath, 'xeapi_public_key'), 'utf-8'),
)
} catch (_) {}
const publicKey = await getXeapiPublicKey(currentPublicKey, global.deviceId)
fs.writeFileSync(
path.resolve(tmpPath, 'xeapi_public_key'),
JSON.stringify(publicKey),
'utf-8',
)
} catch (error) {
console.log(error)
}
}
module.exports = generateConfig
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 858 KiB

+1
View File
@@ -0,0 +1 @@
require('./app.js')
+1
View File
@@ -0,0 +1 @@
import './app.js'
+2884
View File
File diff suppressed because it is too large Load Diff
+63
View File
@@ -0,0 +1,63 @@
const fs = require('fs')
const path = require('path')
const tmpPath = require('os').tmpdir()
const { cookieToJson } = require('./util')
const anonymousTokenPath = path.resolve(tmpPath, 'anonymous_token')
if (!fs.existsSync(anonymousTokenPath)) {
fs.writeFileSync(anonymousTokenPath, '', 'utf-8')
}
/** @type {Record<string, any>} */
let obj = {}
const modulePath = path.join(__dirname, 'module')
const moduleFiles = fs.readdirSync(modulePath).reverse()
let requestModule = null
moduleFiles.forEach((file) => {
if (!file.endsWith('.js')) return
const filePath = path.join(modulePath, file)
let fileModule = require(filePath)
let fn = file.split('.').shift() || ''
obj[fn] = function (data = {}) {
const cookie =
typeof data.cookie === 'string'
? cookieToJson(data.cookie)
: data.cookie || {}
return fileModule(
{
...data,
cookie,
},
async (...args) => {
if (!requestModule) {
requestModule = require('./util/request')
}
return requestModule(...args)
},
)
}
})
let serverModule = null
/**
* @type {Record<string, any> & import("./server")}
*/
module.exports = {
get server() {
if (!serverModule) {
serverModule = require('./server')
}
return serverModule
},
...obj,
}
Object.assign(module.exports, require('./server'))
+18
View File
@@ -0,0 +1,18 @@
const assert = require('assert')
const main = require('./main')
describe('methods in server.js', () => {
it('has serveNcmApi', () => {
assert.strictEqual(typeof main.serveNcmApi, 'function')
})
it('has getModulesDefinitions', () => {
assert.strictEqual(typeof main.getModulesDefinitions, 'function')
})
})
describe('methods in module', () => {
it('has activate_init_profile', () => {
assert.strictEqual(typeof main.activate_init_profile, 'function')
})
})
+9
View File
@@ -0,0 +1,9 @@
// 初始化名字
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
nickname: query.nickname,
}
return request(`/api/activate/initProfile`, data, createOption(query))
}
+51
View File
@@ -0,0 +1,51 @@
// 获取广告
const createOption = require('../util/option.js')
module.exports = async (query, request) => {
const data = {
type_ids: query.type_ids || '["400002_0"]',
}
const option = createOption(query, 'xeapi', 'v3')
const res = await request(`/api/ad/get`, data, option)
const raw = res.body
// 提取广告中的 req_id
let reqId = ''
try {
if (raw?.ads) {
const ad = Object.values(raw.ads)[0]
// 逆向 v9.5.61:客户端从 ad.adExtMap["req_id"] 取 reqUid
if (ad?.adExtMap) {
if (typeof ad.adExtMap === 'string') {
try {
reqId = JSON.parse(ad.adExtMap).req_id || ''
} catch (_) {}
} else {
reqId = ad.adExtMap.req_id || ''
}
}
// 兜底:adLogId.requestId / ad.reqId / extJson.contextInfo.req_id
if (!reqId && ad?.adLogId?.requestId) reqId = ad.adLogId.requestId
if (!reqId && ad?.reqId) reqId = ad.reqId
if (!reqId && ad?.extJson) {
try {
const ext = JSON.parse(ad.extJson)
reqId = ext?.contextInfo?.req_id || ''
} catch (_) {}
}
}
} catch (_) {}
return {
status: 200,
body: {
code: 200,
ads: raw?.ads || null,
message: raw?.message || null,
extra: { reqId },
},
}
}
+13
View File
@@ -0,0 +1,13 @@
// 获取免费听时长状态
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
entrance: 'FREE_LISTEN_RN',
}
return request(
`/api/ad/homepage/free/tab/extend/v2`,
data,
createOption(query, 'xeapi'),
)
}
+252
View File
@@ -0,0 +1,252 @@
// 看广告免费听歌 - 领取免费听权益
// 请求流程(基于逆向网易云音乐 v9.5.61 原生 Kotlin 源码,classes5/18/19.dex):
// 1. 从广告平台拉广告 → 用户看完/点击广告 → 获取 ad 对象的 extJson.contextInfo.req_id 作为 reqUid
// 2. 调用本接口传入 reqUid 及相关权益参数,领取权益
// 3. 服务器返回 gainFlag 等标识,用于展示领取结果
//
// 调用链(逆向还原):
// AdDSLIncentiveVideoRightsHelper.requestRightsGainInner
// → AdDSLUtils.requestRightGain(ad, exposeTime, clickTime, creativeType, cb)
// → 构造 ListeningRightRequestParams(21 字段)→ JSON.stringify
// → body = { "reqParam": "..." } → POST /api/ad/listening/rights/gain
// (注意:客户端 AdDSLIncentiveVideoRightsHelper 写死 creativeType=36)
//
// 接口不只领取听歌时长,还包含"看视频得云贝"等权益:
// rightsGainMethod=6 (LAXIN_EXPOSE_OR_DOWNLOAD 拉新曝光/下载分段权益) 时,
// 弹窗 AdLaxinSegmentedGuideDialog 展示 "获得X云贝"(2000 云贝等),
// 权益数值由广告下发的 AdLaxinSegmentedRightsGuidePopup.rightsValue 决定,
// extraRightsType 作为权益类型随本接口上传。
//
// rightsGainMethod 枚举(h80/a):
// 1=EXPOSE 曝光, 2=EXPOSE_CLICK 曝光+点击, 3=EXPOSE_DOWNLOAD 曝光+下载,
// 4=CLICK_STAY 点击+停留, 5=EXPOSURE_OR_CLICK_STAY 曝光或点击停留,
// 6=LAXIN_EXPOSE_OR_DOWNLOAD 拉新曝光/下载分段权益
const createOption = require('../util/option.js')
const adGet = require('./ad_get.js')
// 安全 JSON 解析(字符串字段可能是 JSON 文本)
function safeParse(str, fallback) {
if (typeof str !== 'string') return fallback
try {
return JSON.parse(str)
} catch (_) {
return fallback
}
}
module.exports = async (query, request) => {
const time = Date.now()
// 从广告对象自动补齐请求字段。
// 实测 v9.5.61 真实 API 返回(/ad/get)确认的字段路径:
// reqUid = ad.extJson.contextInfo.req_id(真实响应中唯一存在)
// contextInfo = ad.extJson.contextInfo(完整对象序列化)
// generalRightsInfo = ad.generalRightsInfo(字符串 JSON)
// creativeType = ad.creativeType
// rightsGainMethod / extraRightsType / rightsGainDuration / rightsGainType /
// extraRightsGainMethod / extraRightsGainDuration / nextRightsGainDuration /
// rightsExtJson / source / rightsUpperLimit / qualified
// = ad.generalRightsInfo(字符串)解析后取值
// (逆向类字段 adExtMap/adLogId/listeningRightHintInfo 真实响应中不存在,仅兜底)
// sniffTime = method==3 或 6 时 currentTimeMillis
let reqUid = query.reqUid || ''
let contextInfo = query.contextInfo
let creativeType = query.creativeType
let generalRightsInfo = query.generalRightsInfo
// 广告 hint 配置:仅当调用方未显式传参时用广告下发值兜底
const hint = {}
if (!reqUid || contextInfo === undefined || creativeType === undefined) {
try {
const adRes = await adGet(
{ ...query, type_ids: query.type_ids || '["400002_0"]' },
request,
)
const ad = Object.values(adRes?.body?.ads || {})[0]
if (!ad) throw new Error('ads 为空(未登录或广告位无广告)')
// reqUid:真实 API 返回中 req_id 在 ad.extJson.contextInfo.req_id(实测 v9.5.61)
// (逆向类字段 adExtMap/adLogId 在真实响应中不存在,仅作兜底)
if (!reqUid) {
const ext =
typeof ad?.extJson === 'string'
? safeParse(ad.extJson, {})
: ad?.extJson || {}
const extMap =
typeof ad?.adExtMap === 'string'
? safeParse(ad.adExtMap, {})
: ad?.adExtMap
reqUid =
ext?.contextInfo?.req_id ||
extMap?.req_id ||
ad?.adLogId?.requestId ||
ad?.reqId ||
adRes?.body?.extra?.reqId ||
''
}
// contextInfo:真实 API 返回中在 ad.extJson.contextInfo(实测 v9.5.61)
if (contextInfo === undefined) {
const ext =
typeof ad?.extJson === 'string'
? safeParse(ad.extJson, {})
: ad?.extJson || {}
const ci =
ext?.contextInfo || ad?.adLogId?.contextInfo || ad?.showContext
if (ci) {
contextInfo = typeof ci === 'string' ? ci : JSON.stringify(ci)
}
}
if (creativeType === undefined && ad?.creativeType !== undefined) {
creativeType = ad.creativeType
}
if (generalRightsInfo === undefined && ad?.generalRightsInfo) {
generalRightsInfo =
typeof ad.generalRightsInfo === 'string'
? ad.generalRightsInfo
: JSON.stringify(ad.generalRightsInfo)
}
// 缓存广告下发的领取配置(后续用于兜底)
// 实测 v9.5.61:rightsGainMethod/rightsUpperLimit/qualified 等在
// ad.generalRightsInfo(字符串)里,ad.listeningRightHintInfo 真实响应中不存在
const hintCfg =
typeof ad?.listeningRightHintInfo === 'string'
? safeParse(ad.listeningRightHintInfo, {})
: ad?.listeningRightHintInfo || {}
const gri =
typeof ad?.generalRightsInfo === 'string'
? safeParse(ad.generalRightsInfo, {})
: ad?.generalRightsInfo || {}
Object.assign(hint, hintCfg, gri)
console.log(`自动获取 reqUid: ${reqUid}`)
} catch (e) {
// 获取广告失败,后续请求会因缺少 reqUid 被拒绝
}
}
const rightsGainMethod = query.rightsGainMethod
? parseInt(query.rightsGainMethod)
: hint.rightsGainMethod || 2
const rightsParam = {
// 必填: 广告请求 ID,自动从 ad_get 获取
reqUid,
// 曝光时间戳
exposureTime: query.exposureTime ? parseInt(query.exposureTime) : time,
// 当前登录用户 ID(原版客户端从 Profile.getUserId() 获取)
userId: query.uid ? parseInt(query.uid) : undefined,
// 点击时间戳
clickTime: query.clickTime ? parseInt(query.clickTime) : time,
// 额外权益类型(拉新分段权益等,决定发放云贝/时长/下载,来自广告配置)
extraRightsType: query.extraRightsType
? parseInt(query.extraRightsType)
: hint.extraRightsType !== undefined
? parseInt(hint.extraRightsType)
: undefined,
// 是否连续播放(默认 false)
playContinuously: query.playContinuously ? true : false,
// 来源标识(原版从 ad.listeningRightHintInfo.source 读取)
source: query.source
? parseInt(query.source)
: hint.source !== undefined
? parseInt(hint.source)
: undefined,
// 广告创意类型(激励视频场景=36,优先取 query / 广告对象)
creativeType: creativeType !== undefined ? parseInt(creativeType) : 36,
// 权益领取方式(1~6 枚举,见文件头注释)
rightsGainMethod,
// 权益扩展方式与时长
extraRightsGainMethod: query.extraRightsGainMethod
? parseInt(query.extraRightsGainMethod)
: hint.extraRightsGainMethod !== undefined
? parseInt(hint.extraRightsGainMethod)
: undefined,
extraRightsGainDuration: query.extraRightsGainDuration
? parseInt(query.extraRightsGainDuration)
: hint.extraRightsGainDuration !== undefined
? parseInt(hint.extraRightsGainDuration)
: undefined,
nextRightsGainDuration: query.nextRightsGainDuration
? parseInt(query.nextRightsGainDuration)
: hint.nextRightsGainDuration !== undefined
? parseInt(hint.nextRightsGainDuration)
: undefined,
// 权益类型(含 RIGHTS_GAIN_TYPE_CURRENT_DAY 等取值)
rightsGainType: query.rightsGainType
? parseInt(query.rightsGainType)
: hint.rightsGainType !== undefined
? parseInt(hint.rightsGainType)
: undefined,
// 权益时长
rightsGainDuration: query.rightsGainDuration
? parseInt(query.rightsGainDuration)
: hint.rightsGainDuration !== undefined
? parseInt(hint.rightsGainDuration)
: undefined,
// 领取步骤(UNGAIN/GAINING/GAIN_FINISHED 对应的值)
gainMethodStep: query.gainMethodStep
? parseInt(query.gainMethodStep)
: undefined,
// 通用权益信息(ad.generalRightsInfo 序列化 JSON)
generalRightsInfo,
// 权益扩展信息
rightsExtJson: query.rightsExtJson || hint.rightsExtJson || undefined,
// 应用信息(下载类广告)
appInfo: query.appInfo ? JSON.parse(query.appInfo) : undefined,
// 广告上下文(ad.adLogId.contextInfo,客户端真实来源)
contextInfo,
// 应用是否已安装(下载类广告)
installed: query.installed ? parseInt(query.installed) : undefined,
// 嗅探时间:逆向确认(classes5.dex AdDSLUtils.requestRightGain):
// rightsGainMethod==3(曝光+下载) 或 6(LAXIN) 时传 currentTimeMillis
sniffTime:
rightsGainMethod === 3 || rightsGainMethod === 6
? query.sniffTime
? parseInt(query.sniffTime)
: time
: undefined,
}
// 清理 undefined 字段
Object.keys(rightsParam).forEach((key) => {
if (rightsParam[key] === undefined) delete rightsParam[key]
})
// 将参数序列化为 reqParam 字符串 (与原生源码一致)
const data = {
reqParam: JSON.stringify(rightsParam),
}
const res = await request(
`/api/ad/listening/rights/gain`,
data,
createOption(query, 'xeapi', 'v3'),
)
return {
status: 200,
body: {
code: 200,
data: res.body,
},
}
}
+28
View File
@@ -0,0 +1,28 @@
// 私人 DJ
// 实际请求参数如下, 部分内容省略, 敏感信息已进行混淆
// 可按需修改此 API 的代码
/* {"extInfo":"{\"lastRequestTimestamp\":1692358373509,\"lbsInfoList\":[{\"lat\":40.23076381,\"lon\":129.07545186,\"time\":1692358543},{\"lat\":40.23076381,\"lon\":129.07545186,\"time\":1692055283}],\"listenedTs\":false,\"noAidjToAidj\":true}","header":"{}"} */
const logger = require('../util/logger.js')
const createOption = require('../util/option.js')
module.exports = (query, request) => {
var extInfo = {}
if (query.latitude != undefined) {
extInfo.lbsInfoList = [
{
lat: query.latitude,
lon: query.longitude,
time: Date.parse(new Date()) / 1000,
},
]
}
extInfo.noAidjToAidj = false
extInfo.lastRequestTimestamp = new Date().getTime()
extInfo.listenedTs = false
const data = {
extInfo: JSON.stringify(extInfo),
}
// logger.info(data)
return request(`/api/aidj/content/rcmd/info`, data, createOption(query))
}
+6
View File
@@ -0,0 +1,6 @@
// 专辑内容
const createOption = require('../util/option.js')
module.exports = (query, request) => {
return request(`/api/v1/album/${query.id}`, {}, createOption(query, 'weapi'))
}
+12
View File
@@ -0,0 +1,12 @@
// 数字专辑详情
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
id: query.id,
}
return request(
`/api/vipmall/albumproduct/detail`,
data,
createOption(query, 'weapi'),
)
}
+12
View File
@@ -0,0 +1,12 @@
// 专辑动态信息
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
id: query.id,
}
return request(
`/api/album/detail/dynamic`,
data,
createOption(query, 'weapi'),
)
}
+16
View File
@@ -0,0 +1,16 @@
// 数字专辑-新碟上架
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
limit: query.limit || 30,
offset: query.offset || 0,
total: true,
area: query.area || 'ALL', //ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本
type: query.type,
}
return request(
`/api/vipmall/albumproduct/list`,
data,
createOption(query, 'weapi'),
)
}
+15
View File
@@ -0,0 +1,15 @@
// 数字专辑-语种风格馆
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
limit: query.limit || 10,
offset: query.offset || 0,
total: true,
area: query.area || 'Z_H', //Z_H:华语,E_A:欧美,KR:韩国,JP:日本
}
return request(
`/api/vipmall/appalbum/album/style`,
data,
createOption(query, 'weapi'),
)
}
+11
View File
@@ -0,0 +1,11 @@
// 全部新碟
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
limit: query.limit || 30,
offset: query.offset || 0,
total: true,
area: query.area || 'ALL', //ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本
}
return request(`/api/album/new`, data, createOption(query, 'weapi'))
}
+6
View File
@@ -0,0 +1,6 @@
// 最新专辑
const createOption = require('../util/option.js')
module.exports = (query, request) => {
return request(`/api/discovery/newAlbum`, {}, createOption(query, 'weapi'))
}
+9
View File
@@ -0,0 +1,9 @@
// 获取专辑歌曲的音质
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
id: query.id,
}
return request(`/api/album/privilege`, data, createOption(query))
}
+19
View File
@@ -0,0 +1,19 @@
// 数字专辑&数字单曲-榜单
const createOption = require('../util/option.js')
module.exports = (query, request) => {
let data = {
albumType: query.albumType || 0, //0为数字专辑,1为数字单曲
}
const type = query.type || 'daily' // daily,week,year,total
if (type === 'year') {
data = {
...data,
year: query.year,
}
}
return request(
`/api/feealbum/songsaleboard/${type}/type`,
data,
createOption(query, 'weapi'),
)
}
+10
View File
@@ -0,0 +1,10 @@
// 收藏/取消收藏专辑
const createOption = require('../util/option.js')
module.exports = (query, request) => {
query.t = query.t == 1 ? 'sub' : 'unsub'
const data = {
id: query.id,
}
return request(`/api/album/${query.t}`, data, createOption(query, 'weapi'))
}
+11
View File
@@ -0,0 +1,11 @@
// 已收藏专辑列表
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
limit: query.limit || 25,
offset: query.offset || 0,
total: true,
}
return request(`/api/album/sublist`, data, createOption(query, 'weapi'))
}
+21
View File
@@ -0,0 +1,21 @@
const { cookieToJson } = require('../util/index')
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const uri = query.uri
let data = {}
try {
data =
typeof query.data === 'string' ? JSON.parse(query.data) : query.data || {}
if (typeof data.cookie === 'string') {
data.cookie = cookieToJson(data.cookie)
query.cookie = data.cookie
}
} catch (e) {
data = {}
}
const crypto = query.crypto || ''
const res = request(uri, data, createOption(query, crypto))
return res
}
+15
View File
@@ -0,0 +1,15 @@
// 歌手专辑列表
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
limit: query.limit || 30,
offset: query.offset || 0,
total: true,
}
return request(
`/api/artist/albums/${query.id}`,
data,
createOption(query, 'weapi'),
)
}
+9
View File
@@ -0,0 +1,9 @@
// 歌手介绍
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
id: query.id,
}
return request(`/api/artist/introduction`, data, createOption(query, 'weapi'))
}
+10
View File
@@ -0,0 +1,10 @@
const createOption = require('../util/option.js')
module.exports = (query, request) => {
return request(
`/api/artist/head/info/get`,
{
id: query.id,
},
createOption(query),
)
}
+9
View File
@@ -0,0 +1,9 @@
// 歌手动态信息
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
id: query.id,
}
return request(`/api/artist/detail/dynamic`, data, createOption(query))
}
+11
View File
@@ -0,0 +1,11 @@
// 歌手粉丝
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
id: query.id,
limit: query.limit || 20,
offset: query.offset || 0,
}
return request(`/api/artist/fans/get`, data, createOption(query, 'weapi'))
}
+13
View File
@@ -0,0 +1,13 @@
// 歌手粉丝数量
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
id: query.id,
}
return request(
`/api/artist/follow/count/get`,
data,
createOption(query, 'weapi'),
)
}
+33
View File
@@ -0,0 +1,33 @@
// 歌手分类
/*
type 取值
1:男歌手
2:女歌手
3:乐队
area 取值
-1:全部
7华语
96欧美
8:日本
16韩国
0:其他
initial 取值 a-z/A-Z
*/
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
initial: isNaN(query.initial)
? (query.initial || '').toUpperCase().charCodeAt() || undefined
: query.initial,
offset: query.offset || 0,
limit: query.limit || 30,
total: true,
type: query.type || '1',
area: query.area,
}
return request(`/api/v1/artist/list`, data, createOption(query, 'weapi'))
}
+12
View File
@@ -0,0 +1,12 @@
// 歌手相关MV
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
artistId: query.id,
limit: query.limit,
offset: query.offset,
total: true,
}
return request(`/api/artist/mvs`, data, createOption(query, 'weapi'))
}
+12
View File
@@ -0,0 +1,12 @@
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
limit: query.limit || 20,
startTimestamp: query.before || Date.now(),
}
return request(
`/api/sub/artist/new/works/mv/list`,
data,
createOption(query, 'weapi'),
)
}
+12
View File
@@ -0,0 +1,12 @@
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
limit: query.limit || 20,
startTimestamp: query.before || Date.now(),
}
return request(
`/api/sub/artist/new/works/song/list`,
data,
createOption(query, 'weapi'),
)
}
+16
View File
@@ -0,0 +1,16 @@
// 获取关注歌手的新歌曲和 MV
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
startTimestamp: query.startTimestamp || query.before || Date.now(),
sourceType: query.sourceType || 1,
limit: query.limit || 10,
firstRequest: query.firstRequest ?? true,
}
return request(
`/api/sub/artist/new/works/song-mv/list/v2`,
data,
createOption(query, 'eapi'),
)
}
+10
View File
@@ -0,0 +1,10 @@
// 获取所有关注歌手最近的 50 首新歌
const createOption = require('../util/option.js')
module.exports = (query, request) => {
return request(
`/api/sub/artist/new/works/song/playall`,
{},
createOption(query, 'eapi'),
)
}
+12
View File
@@ -0,0 +1,12 @@
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
id: query.id,
private_cloud: 'true',
work_type: 1,
order: query.order || 'hot', //hot,time
offset: query.offset || 0,
limit: query.limit || 100,
}
return request(`/api/v1/artist/songs`, data, createOption(query))
}
+11
View File
@@ -0,0 +1,11 @@
// 收藏与取消收藏歌手
const createOption = require('../util/option.js')
module.exports = (query, request) => {
query.t = query.t == 1 ? 'sub' : 'unsub'
const data = {
artistId: query.id,
artistIds: '[' + query.id + ']',
}
return request(`/api/artist/${query.t}`, data, createOption(query, 'weapi'))
}
+11
View File
@@ -0,0 +1,11 @@
// 关注歌手列表
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
limit: query.limit || 25,
offset: query.offset || 0,
total: true,
}
return request(`/api/artist/sublist`, data, createOption(query, 'weapi'))
}
+8
View File
@@ -0,0 +1,8 @@
// 歌手热门 50 首歌曲
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
id: query.id,
}
return request(`/api/artist/top/song`, data, createOption(query, 'weapi'))
}
+15
View File
@@ -0,0 +1,15 @@
// 歌手相关视频
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
artistId: query.id,
page: JSON.stringify({
size: query.size || 10,
cursor: query.cursor || 0,
}),
tab: 0,
order: query.order || 0,
}
return request(`/api/mlog/artist/video`, data, createOption(query, 'weapi'))
}
+6
View File
@@ -0,0 +1,6 @@
// 歌手单曲
const createOption = require('../util/option.js')
module.exports = (query, request) => {
return request(`/api/v1/artist/${query.id}`, {}, createOption(query, 'weapi'))
}
+19
View File
@@ -0,0 +1,19 @@
const { default: axios } = require('axios')
const createOption = require('../util/option.js')
module.exports = async (query, request) => {
const res = await axios({
method: 'get',
url: `https://interface.music.163.com/api/music/audio/match?sessionId=0123456789abcdef&algorithmCode=shazam_v2&duration=${
query.duration
}&rawdata=${encodeURIComponent(query.audioFP)}&times=1&decrypt=1`,
data: null,
})
return {
status: 200,
body: {
code: 200,
data: res.data.data,
},
}
}
+22
View File
@@ -0,0 +1,22 @@
const uploadPlugin = require('../plugins/upload')
const createOption = require('../util/option.js')
module.exports = async (query, request) => {
const uploadInfo = await uploadPlugin(query, request)
const res = await request(
`/api/user/avatar/upload/v1`,
{
imgid: uploadInfo.imgId,
},
createOption(query),
)
return {
status: 200,
body: {
code: 200,
data: {
...uploadInfo,
...res.body,
},
},
}
}
+16
View File
@@ -0,0 +1,16 @@
// 首页轮播图
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const type =
{
0: 'pc',
1: 'android',
2: 'iphone',
3: 'ipad',
}[query.type || 0] || 'pc'
return request(
`/api/v2/banner/get`,
{ clientType: type },
createOption(query),
)
}
+12
View File
@@ -0,0 +1,12 @@
// 批量请求接口
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {}
Object.keys(query).forEach((i) => {
if (/^\/api\//.test(i)) {
data[i] = query[i]
}
})
return request(`/api/batch`, data, createOption(query))
}
+11
View File
@@ -0,0 +1,11 @@
// 广播电台 - 分类/地区信息
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {}
return request(
`/api/voice/broadcast/category/region/get`,
data,
createOption(query),
)
}
+12
View File
@@ -0,0 +1,12 @@
// 广播电台 - 我的收藏
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
contentType: 'BROADCAST',
limit: query.limit || '99999',
timeReverseOrder: 'true',
startDate: '4762584922000',
}
return request(`/api/content/channel/collect/list`, data, createOption(query))
}
+13
View File
@@ -0,0 +1,13 @@
// 广播电台 - 电台信息
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
channelId: query.id,
}
return request(
`/api/voice/broadcast/channel/currentinfo`,
data,
createOption(query),
)
}
+13
View File
@@ -0,0 +1,13 @@
// 广播电台 - 全部电台
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
categoryId: query.categoryId || '0',
regionId: query.regionId || '0',
limit: query.limit || '20',
lastId: query.lastId || '0',
score: query.score || '-1',
}
return request(`/api/voice/broadcast/channel/list`, data, createOption(query))
}
+12
View File
@@ -0,0 +1,12 @@
// 广播电台 - 收藏/取消收藏电台
const createOption = require('../util/option.js')
module.exports = (query, request) => {
query.t = query.t == 1 ? 'false' : 'true'
const data = {
contentType: 'BROADCAST',
contentId: query.id,
cancelCollect: query.t,
}
return request(`/api/content/interact/collect`, data, createOption(query))
}
+8
View File
@@ -0,0 +1,8 @@
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
startTime: query.startTime || Date.now(),
endTime: query.endTime || Date.now(),
}
return request(`/api/mcalendar/detail`, data, createOption(query, 'weapi'))
}
+13
View File
@@ -0,0 +1,13 @@
// 发送安全验证码
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
ctcode: query.ctcode || '86',
}
return request(
`/api/sms/captcha/safe/sent`,
data,
createOption(query, 'eapi'),
)
}
+11
View File
@@ -0,0 +1,11 @@
// 发送验证码
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
ctcode: query.ctcode || '86',
secrete: 'music_middleuser_pclogin',
cellphone: query.phone,
}
return request(`/api/sms/captcha/sent`, data, createOption(query, 'weapi'))
}
+16
View File
@@ -0,0 +1,16 @@
// 发送验证码
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
ctcode: query.ctcode || '86',
secrete: 'music_middleuser_pclogin',
cellphone: query.phone,
scene: '0',
}
return request(
`/api/middle/captcha/sent/v1`,
data,
createOption(query, 'eapi'),
)
}
+11
View File
@@ -0,0 +1,11 @@
// 校验验证码
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
ctcode: query.ctcode || '86',
cellphone: query.phone,
captcha: query.captcha,
}
return request(`/api/sms/captcha/verify`, data, createOption(query, 'weapi'))
}
+14
View File
@@ -0,0 +1,14 @@
// 检测手机号码是否已注册
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
cellphone: query.phone,
countrycode: query.countrycode,
}
return request(
`/api/cellphone/existence/check`,
data,
createOption(query, 'eapi'),
)
}
+11
View File
@@ -0,0 +1,11 @@
// 获取指定维度音乐排行榜详情
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
chartCode: query.chartCode,
targetId: query.targetId,
targetType: query.targetType,
}
return request(`/api/chart/detail`, data, createOption(query))
}
+11
View File
@@ -0,0 +1,11 @@
// 获取指定维度音乐排行榜列表
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
chartCode: query.chartCode,
targetId: query.targetId,
targetType: query.targetType,
}
return request(`/api/chart/song/detail`, data, createOption(query))
}
+30
View File
@@ -0,0 +1,30 @@
// 歌曲可用性
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
ids: '[' + parseInt(query.id) + ']',
br: parseInt(query.br || 999000),
}
return request(
`/api/song/enhance/player/url`,
data,
createOption(query, 'weapi'),
).then((response) => {
let playable = false
if (response.body.code == 200) {
if (response.body.data[0].code == 200) {
playable = true
}
}
if (playable) {
response.body = { code: 200, success: true, message: 'ok' }
return response
} else {
// response.status = 404
response.body = { code: 200, success: false, message: '亲爱的,暂无版权' }
return response
// return Promise.reject(response)
}
})
}
+164
View File
@@ -0,0 +1,164 @@
const uploadPlugin = require('../plugins/songUpload')
const createOption = require('../util/option.js')
const logger = require('../util/logger.js')
const {
isTempFile,
getFileSize,
getFileMd5,
cleanupTempFile,
getFileExtension,
sanitizeFilename,
} = require('../util/fileHelper')
let mm
module.exports = async (query, request) => {
mm = require('music-metadata')
query.songFile.name = Buffer.from(query.songFile.name, 'latin1').toString(
'utf-8',
)
const ext = getFileExtension(query.songFile.name)
const filename = sanitizeFilename(query.songFile.name)
const bitrate = 999000
if (!query.songFile) {
return Promise.reject({
status: 500,
body: {
msg: '请上传音乐文件',
code: 500,
},
})
}
const useTemp = isTempFile(query.songFile)
let fileSize = await getFileSize(query.songFile)
let fileMd5 = await getFileMd5(query.songFile)
query.songFile.md5 = fileMd5
query.songFile.size = fileSize
try {
const res = await request(
`/api/cloud/upload/check`,
{
bitrate: String(bitrate),
ext: '',
length: fileSize,
md5: fileMd5,
songId: '0',
version: 1,
},
createOption(query),
)
let artist = ''
let album = ''
let songName = ''
try {
let metadata
if (useTemp) {
metadata = await mm.parseFile(query.songFile.tempFilePath)
} else {
metadata = await mm.parseBuffer(
query.songFile.data,
query.songFile.mimetype,
)
}
const info = metadata.common
if (info.title) songName = info.title
if (info.album) album = info.album
if (info.artist) artist = info.artist
} catch (error) {
logger.info('元数据解析错误:', error.message)
}
const tokenRes = await request(
`/api/nos/token/alloc`,
{
bucket: '',
ext: ext,
filename: filename,
local: false,
nos_product: 3,
type: 'audio',
md5: fileMd5,
},
createOption(query),
)
if (!tokenRes.body.result || !tokenRes.body.result.resourceId) {
logger.error('Token分配失败:', tokenRes.body)
return Promise.reject({
status: 500,
body: {
code: 500,
msg: '获取上传token失败',
detail: tokenRes.body,
},
})
}
if (res.body.needUpload) {
logger.info('需要上传,开始上传流程...')
try {
const uploadInfo = await uploadPlugin(query, request)
logger.info('上传完成:', uploadInfo?.body?.result?.resourceId)
} catch (uploadError) {
logger.error('上传失败:', uploadError)
return Promise.reject(uploadError)
}
} else {
logger.info('文件已存在,跳过上传')
}
const res2 = await request(
`/api/upload/cloud/info/v2`,
{
md5: fileMd5,
songid: res.body.songId,
filename: query.songFile.name,
song: songName || filename,
album: album || '未知专辑',
artist: artist || '未知艺术家',
bitrate: String(bitrate),
resourceId: tokenRes.body.result.resourceId,
},
createOption(query),
)
if (res2.body.code !== 200) {
logger.error('云盘信息上传失败:', res2.body)
return Promise.reject({
status: res2.status || 500,
body: {
code: res2.body.code || 500,
msg: res2.body.msg || '上传云盘信息失败',
detail: res2.body,
},
})
}
const res3 = await request(
`/api/cloud/pub/v2`,
{
songid: res2.body.songId,
},
createOption(query),
)
return {
status: 200,
body: {
...res.body,
...res3.body,
},
cookie: res.cookie,
}
} finally {
if (useTemp) {
await cleanupTempFile(query.songFile.tempFilePath)
}
}
}
+39
View File
@@ -0,0 +1,39 @@
// 云盘导入歌曲
const createOption = require('../util/option.js')
module.exports = async (query, request) => {
query.id = query.id || -2
query.artist = query.artist || '未知'
query.album = query.album || '未知'
const checkData = {
uploadType: 0,
songs: JSON.stringify([
{
md5: query.md5,
songId: query.id,
bitrate: query.bitrate,
fileSize: query.fileSize,
},
]),
}
const res = await request(
`/api/cloud/upload/check/v2`,
checkData,
createOption(query),
)
//res.body.data[0].upload 0:文件可导入,1:文件已在云盘,2:不能导入
//只能用song决定云盘文件名,且上传后的文件名后缀固定为mp3
const importData = {
uploadType: 0,
songs: JSON.stringify([
{
songId: res.body.data[0].songId,
bitrate: query.bitrate,
song: query.song,
artist: query.artist,
album: query.album,
fileName: query.song + '.' + query.fileType,
},
]),
}
return request(`/api/cloud/user/song/import`, importData, createOption(query))
}
+11
View File
@@ -0,0 +1,11 @@
// 获取云盘歌词
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
userId: query.uid,
songId: query.sid,
lv: -1,
kv: -1,
}
return request(`/api/cloud/lyric/get`, data, createOption(query, 'eapi'))
}
+13
View File
@@ -0,0 +1,13 @@
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
userId: query.uid,
songId: query.sid,
adjustSongId: query.asid,
}
return request(
`/api/cloud/user/song/match`,
data,
createOption(query, 'weapi'),
)
}
+72
View File
@@ -0,0 +1,72 @@
const createOption = require('../util/option.js')
module.exports = async (query, request) => {
const {
songId,
resourceId,
md5,
filename,
song,
artist,
album,
bitrate = 999000,
} = query
if (!songId || !resourceId || !md5 || !filename) {
return Promise.reject({
status: 400,
body: {
code: 400,
msg: '缺少必要参数: songId, resourceId, md5, filename',
},
})
}
const songName = song || filename.replace(/\.[^.]+$/, '')
const res2 = await request(
`/api/upload/cloud/info/v2`,
{
md5: md5,
songid: songId,
filename: filename,
song: songName,
album: album || '未知专辑',
artist: artist || '未知艺术家',
bitrate: String(bitrate),
resourceId: resourceId,
},
createOption(query),
)
if (res2.body.code !== 200) {
return Promise.reject({
status: res2.status || 500,
body: {
code: res2.body.code || 500,
msg: res2.body.msg || '上传云盘信息失败',
detail: res2.body,
},
})
}
const res3 = await request(
`/api/cloud/pub/v2`,
{
songid: res2.body.songId,
},
createOption(query),
)
return {
status: 200,
body: {
code: 200,
data: {
songId: res2.body.songId,
...res3.body,
},
},
cookie: res2.cookie,
}
}
+111
View File
@@ -0,0 +1,111 @@
const { default: axios } = require('axios')
const createOption = require('../util/option.js')
module.exports = async (query, request) => {
const { md5, fileSize, filename, bitrate = 999000 } = query
if (!md5 || !fileSize || !filename) {
return Promise.reject({
status: 400,
body: {
code: 400,
msg: '缺少必要参数: md5, fileSize, filename',
},
})
}
const ext = filename.includes('.') ? filename.split('.').pop() : 'mp3'
const checkRes = await request(
`/api/cloud/upload/check`,
{
bitrate: String(bitrate),
ext: '',
length: fileSize,
md5: md5,
songId: '0',
version: 1,
},
createOption(query),
)
const bucket = 'jd-musicrep-privatecloud-audio-public'
const tokenRes = await request(
`/api/nos/token/alloc`,
{
bucket: bucket,
ext: ext,
filename: filename
.replace(/\.[^.]+$/, '')
.replace(/\s/g, '')
.replace(/\./g, '_'),
local: false,
nos_product: 3,
type: 'audio',
md5: md5,
},
createOption(query, 'weapi'),
)
if (!tokenRes.body.result || !tokenRes.body.result.objectKey) {
return Promise.reject({
status: 500,
body: {
code: 500,
msg: '获取上传token失败',
detail: tokenRes.body,
},
})
}
let lbs
try {
lbs = (
await axios({
method: 'get',
url: `https://wanproxy.127.net/lbs?version=1.0&bucketname=${bucket}`,
timeout: 10000,
})
).data
} catch (error) {
return Promise.reject({
status: 500,
body: {
code: 500,
msg: '获取上传服务器地址失败',
detail: error.message,
},
})
}
if (!lbs || !lbs.upload || !lbs.upload[0]) {
return Promise.reject({
status: 500,
body: {
code: 500,
msg: '获取上传服务器地址无效',
detail: lbs,
},
})
}
return {
status: 200,
body: {
code: 200,
data: {
needUpload: checkRes.body.needUpload,
songId: checkRes.body.songId,
uploadToken: tokenRes.body.result.token,
objectKey: tokenRes.body.result.objectKey,
resourceId: tokenRes.body.result.resourceId,
uploadUrl: `${lbs.upload[0]}/${bucket}/${tokenRes.body.result.objectKey.replace(/\//g, '%2F')}?offset=0&complete=true&version=1.0`,
bucket: bucket,
md5: md5,
fileSize: fileSize,
filename: filename,
},
},
cookie: checkRes.cookie,
}
}
+13
View File
@@ -0,0 +1,13 @@
// 搜索
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
s: query.keywords,
type: query.type || 1, // 1: 单曲, 10: 专辑, 100: 歌手, 1000: 歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频
limit: query.limit || 30,
offset: query.offset || 0,
total: true,
}
return request(`/api/cloudsearch/pc`, data, createOption(query))
}
+30
View File
@@ -0,0 +1,30 @@
const { resourceTypeMap } = require('../util/config.json')
// 发送与删除评论
const createOption = require('../util/option.js')
module.exports = (query, request) => {
query.t = {
1: 'add',
0: 'delete',
2: 'reply',
}[query.t]
query.type = resourceTypeMap[query.type]
const data = {
threadId: query.type + query.id,
}
if (query.type == 'A_EV_2_') {
data.threadId = query.threadId
}
if (query.t == 'add') data.content = query.content
else if (query.t == 'delete') data.commentId = query.commentId
else if (query.t == 'reply') {
data.commentId = query.commentId
data.content = query.content
}
return request(
`/api/resource/comments/${query.t}`,
data,
createOption(query, 'eapi', 'v2'),
)
}

Some files were not shown because too many files have changed in this diff Show More