├── .editorconfig
├── .eslintrc.js
├── .github
├── ISSUE_TEMPLATE
│ ├── ------.md
│ └── ----.md
└── workflows
│ ├── Build_Image.yml
│ └── node.js.yml
├── .gitignore
├── .husky
├── .gitignore
└── pre-commit
├── .npmignore
├── .prettierrc
├── .travis.yml
├── CHANGELOG.MD
├── Dockerfile
├── LICENSE
├── README.MD
├── app.js
├── docs
├── .nojekyll
├── README.md
├── _coverpage.md
├── favicon.ico
├── icon.png
├── index.html
├── sw.js
└── v2.md
├── examples
└── get_static_moddef.js
├── index.js
├── interface.d.ts
├── issue_template.md
├── main.js
├── main.test.js
├── module
├── activate_init_profile.js
├── album.js
├── album_detail.js
├── album_detail_dynamic.js
├── album_list.js
├── album_list_style.js
├── album_new.js
├── album_newest.js
├── album_songsaleboard.js
├── album_sub.js
├── album_sublist.js
├── artist_album.js
├── artist_desc.js
├── artist_detail.js
├── artist_fans.js
├── artist_follow_count.js
├── artist_list.js
├── artist_mv.js
├── artist_new_mv.js
├── artist_new_song.js
├── artist_songs.js
├── artist_sub.js
├── artist_sublist.js
├── artist_top_song.js
├── artist_video.js
├── artists.js
├── audio_match.js
├── avatar_upload.js
├── banner.js
├── batch.js
├── calendar.js
├── captcha_sent.js
├── captcha_verify.js
├── cellphone_existence_check.js
├── check_music.js
├── cloud.js
├── cloud_match.js
├── cloudsearch.js
├── comment.js
├── comment_album.js
├── comment_dj.js
├── comment_event.js
├── comment_floor.js
├── comment_hot.js
├── comment_hug_list.js
├── comment_like.js
├── comment_music.js
├── comment_mv.js
├── comment_new.js
├── comment_playlist.js
├── comment_video.js
├── countries_code_list.js
├── daily_signin.js
├── digitalAlbum_detail.js
├── digitalAlbum_ordering.js
├── digitalAlbum_purchased.js
├── digitalAlbum_sales.js
├── dj_banner.js
├── dj_category_excludehot.js
├── dj_category_recommend.js
├── dj_catelist.js
├── dj_detail.js
├── dj_hot.js
├── dj_paygift.js
├── dj_personalize_recommend.js
├── dj_program.js
├── dj_program_detail.js
├── dj_program_toplist.js
├── dj_program_toplist_hours.js
├── dj_radio_hot.js
├── dj_recommend.js
├── dj_recommend_type.js
├── dj_sub.js
├── dj_sublist.js
├── dj_subscriber.js
├── dj_today_perfered.js
├── dj_toplist.js
├── dj_toplist_hours.js
├── dj_toplist_newcomer.js
├── dj_toplist_pay.js
├── dj_toplist_popular.js
├── event.js
├── event_del.js
├── event_forward.js
├── fm_trash.js
├── follow.js
├── history_recommend_songs.js
├── history_recommend_songs_detail.js
├── homepage_block_page.js
├── homepage_dragon_ball.js
├── hot_topic.js
├── hug_comment.js
├── inner_version.js
├── like.js
├── likelist.js
├── listen_together_status.js
├── login.js
├── login_cellphone.js
├── login_qr_check.js
├── login_qr_create.js
├── login_qr_key.js
├── login_refresh.js
├── login_status.js
├── logout.js
├── lyric.js
├── mlog_music_rcmd.js
├── mlog_to_video.js
├── mlog_url.js
├── msg_comments.js
├── msg_forwards.js
├── msg_notices.js
├── msg_private.js
├── msg_private_history.js
├── msg_recentcontact.js
├── musician_cloudbean.js
├── musician_cloudbean_obtain.js
├── musician_data_overview.js
├── musician_play_trend.js
├── musician_sign.js
├── musician_tasks.js
├── musician_tasks_new.js
├── mv_all.js
├── mv_detail.js
├── mv_detail_info.js
├── mv_exclusive_rcmd.js
├── mv_first.js
├── mv_sub.js
├── mv_sublist.js
├── mv_url.js
├── nickname_check.js
├── personal_fm.js
├── personalized.js
├── personalized_djprogram.js
├── personalized_mv.js
├── personalized_newsong.js
├── personalized_privatecontent.js
├── personalized_privatecontent_list.js
├── playlist_catlist.js
├── playlist_cover_update.js
├── playlist_create.js
├── playlist_delete.js
├── playlist_desc_update.js
├── playlist_detail.js
├── playlist_detail_dynamic.js
├── playlist_highquality_tags.js
├── playlist_hot.js
├── playlist_mylike.js
├── playlist_name_update.js
├── playlist_order_update.js
├── playlist_privacy.js
├── playlist_subscribe.js
├── playlist_subscribers.js
├── playlist_tags_update.js
├── playlist_track_add.js
├── playlist_track_all.js
├── playlist_track_delete.js
├── playlist_tracks.js
├── playlist_update.js
├── playlist_update_playcount.js
├── playlist_video_recent.js
├── playmode_intelligence_list.js
├── program_recommend.js
├── rebind.js
├── recommend_resource.js
├── recommend_songs.js
├── record_recent_album.js
├── record_recent_dj.js
├── record_recent_playlist.js
├── record_recent_song.js
├── record_recent_video.js
├── record_recent_voice.js
├── register_cellphone.js
├── related_allvideo.js
├── related_playlist.js
├── resource_like.js
├── scrobble.js
├── search.js
├── search_default.js
├── search_hot.js
├── search_hot_detail.js
├── search_multimatch.js
├── search_suggest.js
├── send_album.js
├── send_playlist.js
├── send_song.js
├── send_text.js
├── setting.js
├── share_resource.js
├── sign_happy_info.js
├── signin_progress.js
├── simi_artist.js
├── simi_mv.js
├── simi_playlist.js
├── simi_song.js
├── simi_user.js
├── song_detail.js
├── song_download_url.js
├── song_order_update.js
├── song_purchased.js
├── song_url.js
├── top_album.js
├── top_artists.js
├── top_list.js
├── top_mv.js
├── top_playlist.js
├── top_playlist_highquality.js
├── top_song.js
├── topic_detail.js
├── topic_detail_event_hot.js
├── topic_sublist.js
├── toplist.js
├── toplist_artist.js
├── toplist_detail.js
├── user_account.js
├── user_audio.js
├── user_binding.js
├── user_bindingcellphone.js
├── user_cloud.js
├── user_cloud_del.js
├── user_cloud_detail.js
├── user_comment_history.js
├── user_detail.js
├── user_dj.js
├── user_event.js
├── user_followeds.js
├── user_follows.js
├── user_level.js
├── user_playlist.js
├── user_record.js
├── user_replacephone.js
├── user_subcount.js
├── user_update.js
├── video_category_list.js
├── video_detail.js
├── video_detail_info.js
├── video_group.js
├── video_group_list.js
├── video_sub.js
├── video_timeline_all.js
├── video_timeline_recommend.js
├── video_url.js
├── vip_growthpoint.js
├── vip_growthpoint_details.js
├── vip_growthpoint_get.js
├── vip_info.js
├── vip_tasks.js
├── vip_timemachine.js
├── weblog.js
├── yunbei.js
├── yunbei_expense.js
├── yunbei_info.js
├── yunbei_rcmd_song.js
├── yunbei_rcmd_song_history.js
├── yunbei_receipt.js
├── yunbei_sign.js
├── yunbei_task_finish.js
├── yunbei_tasks.js
├── yunbei_tasks_todo.js
└── yunbei_today.js
├── module_example
├── avatar_upload.js
├── multi_song_upload.js
├── song_upload.js
├── test.jpg
├── test.js
├── test.mp3
└── test.ts
├── package-lock.json
├── package.json
├── plugins
├── songUpload.js
└── upload.js
├── public
├── avatar_update.html
├── cloud.html
├── home.html
├── index.html
├── login.html
├── playlist_cover_update.html
├── qrlogin.html
└── test.html
├── renovate.json
├── server.js
├── server.test.js
├── static
├── artist_album.png
├── artists.png
├── banner.png
├── comment.png
├── docs.png
├── fm_trash.png
├── like.png
├── likeSuccess.png
├── mv.png
├── new_albums.png
├── personal_fm.png
├── play_mv.png
├── screenshot1.png
├── screenshot2.png
├── signinError.png
├── signinSuccess.png
├── songDetail.png
├── top_artists.png
├── top_list.png
├── top_playlist.png
├── 专辑.png
├── 推荐歌单.png
├── 推荐歌曲.png
├── 搜索.png
├── 歌单详情.png
├── 歌词.png
├── 用户歌单.png
├── 登录.png
└── 音乐 url.png
├── test
├── album.test.js
├── comment.test.js
├── login.test.js
├── lyric.test.js
├── music_url.test.js
└── search.test.js
├── tsconfig.json
├── util
├── apicache.js
├── config.json
├── crypto.js
├── index.js
├── memory-cache.js
└── request.js
└── vercel.json
/.editorconfig:
--------------------------------------------------------------------------------
1 |
2 | # EditorConfig is awesome: http://EditorConfig.org
3 |
4 | # top-most EditorConfig file
5 | root = true
6 |
7 | # Unix-style newlines with a newline ending every file
8 | [*]
9 | end_of_line = lf
10 | insert_final_newline = true
11 |
12 | # Matches multiple files with brace expansion notation
13 | # Set default charset
14 | [*.{js,py}]
15 | charset = utf-8
16 |
17 | # 4 space indentation
18 | [*.py]
19 | indent_style = space
20 | indent_size = 4
21 |
22 | # Tab indentation (no size specified)
23 | [Makefile]
24 | indent_style = tab
25 |
26 | # Indentation override for all JS under lib directory
27 | [*.{js,ts}]
28 | indent_style = space
29 | indent_size = 2
30 |
31 | # Matches the exact files either package.json or .travis.yml
32 | [{package.json,.travis.yml}]
33 | indent_style = space
34 | indent_size = 2
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parserOptions: {
4 | parser: 'babel-eslint',
5 | ecmaVersion: 2018,
6 | sourceType: 'module',
7 | },
8 | plugins: ['html'],
9 | extends: ['plugin:prettier/recommended'],
10 | env: {
11 | browser: true,
12 | node: true,
13 | },
14 |
15 | rules: {
16 | indent: ['error', 2, { SwitchCase: 1 }],
17 | 'space-infix-ops': ['error', { int32Hint: false }],
18 | 'key-spacing': [
19 | 2,
20 | {
21 | beforeColon: false,
22 | afterColon: true,
23 | },
24 | ],
25 | 'no-octal': 2,
26 | 'no-redeclare': 2,
27 | 'comma-spacing': 2,
28 | 'no-new-object': 2,
29 | 'arrow-spacing': 2,
30 | quotes: [
31 | 2,
32 | 'single',
33 | {
34 | avoidEscape: true,
35 | allowTemplateLiterals: true,
36 | },
37 | ],
38 | },
39 | overrides: [
40 | {
41 | files: ['**/*.ts'],
42 | parser: '@typescript-eslint/parser',
43 | extends: [
44 | 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
45 | // 'prettier/@typescript-eslint',
46 | ],
47 | },
48 | ],
49 | }
50 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/------.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 创建问题反馈
3 | about: 问题反馈
4 | title: "<不按照模版格式或者删除模版信息将得不到处理,确认看完了调用前须知再发 issues>"
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | ## 环境
11 | - 系统/平台: <你的系统和平台>
12 |
13 | - nodejs 版本: <你的 NodeJS 版本号>
14 |
15 | - API版本: <运行的云音乐 API 的版本号, 对应 package.json 里面的 version>
16 |
17 | ## 出现问题
18 | <请清晰描述出现的问题,不要使用xxx不行之类的模糊不清的语句,我没有读心术>
19 |
20 | ## 重现步骤
21 | <请清晰描述重现步骤,调用的接口链接和参数以及命令行错误信息,最好贴上截图(命令行错误信息和接口返回内容)>
22 |
23 | ## 期待效果
24 | <请清晰描述现在的效果和期待的效果>
25 |
26 |
27 |
28 | ---
29 |
30 | >维护项目都是业余时间,精力有限,我只能挑容易解决的issues处理,为了节约双方时间,请尽可能提供足够的有用的信息,给的信息不够我只能根据精力和时间看情况处理,如果模板信息看都不看就删掉,我不会进行任何回复,并且一个月后close掉issue
31 |
32 | >先看文档有没有相关说明,调用前须知必看,确认看完了调用前须知再发 issues
33 |
34 | >先在 issues 搜一下是否有相似问题,没有再发,否则直接关闭
35 |
36 | >不处理别人搭建的线上服务的问题,此项目不提供任何线上服务,请自行搭建
37 |
38 | >重现步骤尽量详细,不能含糊不清,包含请求地址和对应参数以及操作过程描述,不是每个人都喜欢猜别人遇到了什么问题和找参数一个个试,也比较浪费时间
39 |
40 | >如果不是提建议,提 issues 如果不照着模版来将不会优先处理或放着不管
41 |
42 | >460 cheating 的问题把 `utils/request.js` 里面的 `headers['X-Real-IP']` 的注释取消掉就好
43 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/----.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 功能需求
3 | about: 希望添加新接口
4 | title: ''
5 | labels: 功能需求
6 | assignees: ''
7 |
8 | ---
9 |
10 | **功能描述**
11 | - 请清晰描述你所希望添加的功能,最好贴上对应客户端界面的截图
12 |
--------------------------------------------------------------------------------
/.github/workflows/Build_Image.yml:
--------------------------------------------------------------------------------
1 | name: Build Image
2 |
3 | on:
4 | push:
5 | tags:
6 | - v*
7 |
8 | jobs:
9 | build:
10 | if: github.event.base_ref == 'refs/heads/master'
11 | runs-on: ubuntu-latest
12 | name: Build image job
13 |
14 | steps:
15 | - name: Checkout master
16 | uses: actions/checkout@v3
17 | - name: Get version
18 | id: get_version
19 | if: startsWith(github.ref, 'refs/tags/') && startsWith(github.repository, 'Binaryify/NeteaseCloudMusicApi')
20 | run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
21 | - name: Build and publish image
22 | uses: ilteoood/docker_buildx@master
23 | if: startsWith(github.ref, 'refs/tags/') && startsWith(github.repository, 'Binaryify/NeteaseCloudMusicApi')
24 | with:
25 | publish: true
26 | imageName: binaryify/netease_cloud_music_api # dockerid/imageName
27 | platform: linux/ppc64le,linux/s390x,linux/arm64,linux/amd64,linux/arm/v6,linux/arm/v7 # 你准备构建的镜像平台
28 | tag: latest,${{ steps.get_version.outputs.VERSION }}
29 | dockerUser: ${{ secrets.DOCKER_USERNAME }} # docker hub userid 在setting创建secrets name=DOCKER_USERNAME value=dockerid
30 | dockerPassword: ${{ secrets.DOCKER_PASSWORD }} # docker hub password,在setting创建secrets name=DOCKER_PASSWORD value=dockerpassword
31 |
--------------------------------------------------------------------------------
/.github/workflows/node.js.yml:
--------------------------------------------------------------------------------
1 | name: Node.js CI
2 |
3 | on:
4 | pull_request:
5 | branches: [ master ]
6 | push:
7 | branches: [ master ]
8 | permissions:
9 | contents: read
10 |
11 | jobs:
12 | test:
13 | name: Test
14 | runs-on: ubuntu-latest
15 | strategy:
16 | matrix:
17 | node-version: [12.x, 14.x]
18 | steps:
19 | - uses: actions/checkout@v3
20 | - name: Use Node.js ${{ matrix.node-version }}
21 | uses: actions/setup-node@v3
22 | with:
23 | node-version: ${{ matrix.node-version }}
24 | - uses: actions/cache@v3
25 | with:
26 | path: ~/.npm
27 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
28 | restore-keys: |
29 | ${{ runner.os }}-node-
30 | - run: npm ci
31 | name: Install dependencies
32 | - name: Test
33 | env:
34 | NCM_API_TEST_LOGIN_COUNTRY_CODE: ${{ secrets.NCM_API_TEST_LOGIN_COUNTRY_CODE }}
35 | NCM_API_TEST_LOGIN_PHONE: ${{ secrets.NCM_API_TEST_LOGIN_PHONE }}
36 | NCM_API_TEST_LOGIN_PASSWORD: ${{ secrets.NCM_API_TEST_LOGIN_PASSWORD }}
37 | run: npm test
38 | lint:
39 | name: Lint
40 | runs-on: ubuntu-latest
41 | strategy:
42 | matrix:
43 | node-version: [14.x]
44 | steps:
45 | - uses: actions/checkout@v3
46 | - name: Use Node.js ${{ matrix.node-version }}
47 | uses: actions/setup-node@v3
48 | with:
49 | node-version: ${{ matrix.node-version }}
50 | - uses: actions/cache@v3
51 | with:
52 | path: ~/.npm
53 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
54 | restore-keys: |
55 | ${{ runner.os }}-node-
56 | - run: npm ci
57 | name: Install dependencies
58 | - name: Lint
59 | run: npm run lint
60 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | *.log
4 | .idea
5 | .vscode
6 | .history
7 | examples/moddef.json
8 |
--------------------------------------------------------------------------------
/.husky/.gitignore:
--------------------------------------------------------------------------------
1 | _
2 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npx lint-staged
5 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | static
2 | docs
3 | node_modules
4 | module_example
5 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": false,
3 | "trailingComma": "all",
4 | "singleQuote": true
5 | }
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 |
3 | node_js:
4 | - 12
5 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:lts-alpine
2 |
3 | WORKDIR /app
4 | COPY . /app
5 |
6 | RUN npm config set registry "https://registry.npmmirror.com/" \
7 | && npm install -g npm husky \
8 | && npm install --production
9 |
10 | EXPOSE 3000
11 | CMD ["node", "app.js"]
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013-2022 Binaryify
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | require('./server').serveNcmApi({
3 | checkVersion: true,
4 | })
5 |
--------------------------------------------------------------------------------
/docs/.nojekyll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/docs/.nojekyll
--------------------------------------------------------------------------------
/docs/_coverpage.md:
--------------------------------------------------------------------------------
1 | # 网易云音乐 API
2 |
3 | > 网易云音乐 NodeJS 版 API
4 |
5 | - 全部接口已升级到最新
6 | - 具备登录接口,多达200多个接口
7 | - 更完善的文档
8 |
9 |
10 | [GitHub](https://github.com/Binaryify/NeteaseCloudMusicApi)
11 | [Get Started](#neteasecloudmusicapi)
12 |
13 | 
14 |
--------------------------------------------------------------------------------
/docs/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/docs/favicon.ico
--------------------------------------------------------------------------------
/docs/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/docs/icon.png
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 网易云音乐 NodeJS 版 API
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
21 |
22 |
23 |
24 |
31 |
32 |
37 |
38 |
39 |
46 |
47 |
--------------------------------------------------------------------------------
/examples/get_static_moddef.js:
--------------------------------------------------------------------------------
1 | const fsPromises = require('fs/promises')
2 | const path = require('path')
3 | const server = require('../server')
4 |
5 | const exportFile = path.join(__dirname, 'moddef.json')
6 |
7 | async function main() {
8 | const def = await server.getModulesDefinitions(
9 | path.join(__dirname, '..', 'module'),
10 | {
11 | 'daily_signin.js': '/daily_signin',
12 | 'fm_trash.js': '/fm_trash',
13 | 'personal_fm.js': '/personal_fm',
14 | },
15 | false,
16 | )
17 |
18 | fsPromises.writeFile(exportFile, JSON.stringify(def, null, 4))
19 | console.log(`👍 Get your own definition at: ${exportFile}`)
20 | }
21 |
22 | main()
23 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | require('./app.js')
2 |
--------------------------------------------------------------------------------
/issue_template.md:
--------------------------------------------------------------------------------
1 | ## 环境
2 | - 系统/平台: <你的系统和平台>
3 |
4 | - nodejs 版本: <你的 NodeJS 版本号>
5 |
6 | - API版本:<运行的云音乐 API 的版本号, 对应 package.json 里面的 version>
7 |
8 | ## 出现问题
9 | <出现的问题>
10 |
11 | ## 重现步骤
12 | <重现步骤>
13 |
14 | ## 期待效果
15 | <现在的效果,期待的效果>
16 |
17 |
18 |
19 | >先看文档有没有相关说明,调用前须知必看
20 |
21 | >先在 issues 搜一下是否有相似问题,没有再发,否则直接关闭
22 |
23 | >不处理别人搭建的线上服务的问题,此项目不提供任何线上服务,请自行搭建
24 |
25 | >重现步骤尽量详细,不能含糊不清,包含请求地址和对应参数以及操作过程描述,不是每个人都喜欢猜别人遇到了什么问题和找参数一个个试,也比较浪费时间
26 |
27 | >如果不是提建议,提 issues 如果不照着模版来将不会优先处理或直接关闭
28 |
29 | >460 cheating 的问题把 `utils/request.js` 里面的 `headers['X-Real-IP']` 的注释取消掉就好
30 |
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const path = require('path')
3 | const { cookieToJson } = require('./util')
4 | const request = require('./util/request')
5 |
6 | /** @type {Record} */
7 | let obj = {}
8 | fs.readdirSync(path.join(__dirname, 'module'))
9 | .reverse()
10 | .forEach((file) => {
11 | if (!file.endsWith('.js')) return
12 | let fileModule = require(path.join(__dirname, 'module', file))
13 | let fn = file.split('.').shift() || ''
14 | obj[fn] = function (data) {
15 | if (typeof data.cookie === 'string') {
16 | data.cookie = cookieToJson(data.cookie)
17 | }
18 | return fileModule(
19 | {
20 | ...data,
21 | cookie: data.cookie ? data.cookie : {},
22 | },
23 | request,
24 | )
25 | }
26 | })
27 |
28 | /**
29 | * @type {Record & import("./server")}
30 | */
31 | module.exports = {
32 | ...require('./server'),
33 | ...obj,
34 | }
35 |
--------------------------------------------------------------------------------
/main.test.js:
--------------------------------------------------------------------------------
1 | const assert = require('assert')
2 | const main = require('./main')
3 |
4 | describe('methods in server.js', () => {
5 | it('has serveNcmApi', () => {
6 | assert.strictEqual(typeof main.serveNcmApi, 'function')
7 | })
8 |
9 | it('has getModulesDefinitions', () => {
10 | assert.strictEqual(typeof main.getModulesDefinitions, 'function')
11 | })
12 | })
13 |
14 | describe('methods in module', () => {
15 | it('has activate_init_profile', () => {
16 | assert.strictEqual(typeof main.activate_init_profile, 'function')
17 | })
18 | })
19 |
--------------------------------------------------------------------------------
/module/activate_init_profile.js:
--------------------------------------------------------------------------------
1 | // 初始化名字
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | nickname: query.nickname,
6 | }
7 | return request(
8 | 'POST',
9 | `https://music.163.com/eapi/activate/initProfile`,
10 | data,
11 | {
12 | crypto: 'eapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | url: '/api/activate/initProfile',
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/album.js:
--------------------------------------------------------------------------------
1 | // 专辑内容
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/v1/album/${query.id}`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/album_detail.js:
--------------------------------------------------------------------------------
1 | // 数字专辑详情
2 | module.exports = (query, request) => {
3 | const data = {
4 | id: query.id,
5 | }
6 | return request(
7 | 'POST',
8 | `https://music.163.com/weapi/vipmall/albumproduct/detail`,
9 | data,
10 | {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | },
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/module/album_detail_dynamic.js:
--------------------------------------------------------------------------------
1 | // 专辑动态信息
2 | module.exports = (query, request) => {
3 | const data = {
4 | id: query.id,
5 | }
6 | return request(
7 | 'POST',
8 | `https://music.163.com/api/album/detail/dynamic`,
9 | data,
10 | {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | },
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/module/album_list.js:
--------------------------------------------------------------------------------
1 | // 数字专辑-新碟上架
2 | module.exports = (query, request) => {
3 | const data = {
4 | limit: query.limit || 30,
5 | offset: query.offset || 0,
6 | total: true,
7 | area: query.area || 'ALL', //ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本
8 | type: query.type,
9 | }
10 | return request(
11 | 'POST',
12 | `https://music.163.com/weapi/vipmall/albumproduct/list`,
13 | data,
14 | {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | },
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/module/album_list_style.js:
--------------------------------------------------------------------------------
1 | // 数字专辑-语种风格馆
2 | module.exports = (query, request) => {
3 | const data = {
4 | limit: query.limit || 10,
5 | offset: query.offset || 0,
6 | total: true,
7 | area: query.area || 'Z_H', //Z_H:华语,E_A:欧美,KR:韩国,JP:日本
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/weapi/vipmall/appalbum/album/style`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/album_new.js:
--------------------------------------------------------------------------------
1 | // 全部新碟
2 | module.exports = (query, request) => {
3 | const data = {
4 | limit: query.limit || 30,
5 | offset: query.offset || 0,
6 | total: true,
7 | area: query.area || 'ALL', //ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本
8 | }
9 | return request('POST', `https://music.163.com/weapi/album/new`, data, {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | })
15 | }
16 |
--------------------------------------------------------------------------------
/module/album_newest.js:
--------------------------------------------------------------------------------
1 | // 最新专辑
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/api/discovery/newAlbum`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/album_songsaleboard.js:
--------------------------------------------------------------------------------
1 | // 数字专辑&数字单曲-榜单
2 | module.exports = (query, request) => {
3 | let data = {
4 | albumType: query.albumType || 0, //0为数字专辑,1为数字单曲
5 | }
6 | const type = query.type || 'daily' // daily,week,year,total
7 | if (type === 'year') {
8 | data = {
9 | ...data,
10 | year: query.year,
11 | }
12 | }
13 | return request(
14 | 'POST',
15 | `https://music.163.com/api/feealbum/songsaleboard/${type}/type`,
16 | data,
17 | {
18 | crypto: 'weapi',
19 | cookie: query.cookie,
20 | proxy: query.proxy,
21 | realIP: query.realIP,
22 | },
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/module/album_sub.js:
--------------------------------------------------------------------------------
1 | // 收藏/取消收藏专辑
2 |
3 | module.exports = (query, request) => {
4 | query.t = query.t == 1 ? 'sub' : 'unsub'
5 | const data = {
6 | id: query.id,
7 | }
8 | return request('POST', `https://music.163.com/api/album/${query.t}`, data, {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/module/album_sublist.js:
--------------------------------------------------------------------------------
1 | // 已收藏专辑列表
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 25,
6 | offset: query.offset || 0,
7 | total: true,
8 | }
9 | return request('POST', `https://music.163.com/weapi/album/sublist`, data, {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | })
15 | }
16 |
--------------------------------------------------------------------------------
/module/artist_album.js:
--------------------------------------------------------------------------------
1 | // 歌手专辑列表
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 30,
6 | offset: query.offset || 0,
7 | total: true,
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/weapi/artist/albums/${query.id}`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/artist_desc.js:
--------------------------------------------------------------------------------
1 | // 歌手介绍
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | }
7 | return request(
8 | 'POST',
9 | `https://music.163.com/weapi/artist/introduction`,
10 | data,
11 | {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | },
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/module/artist_detail.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | return request(
3 | 'POST',
4 | `https://music.163.com/api/artist/head/info/get`,
5 | {
6 | id: query.id,
7 | },
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/artist_fans.js:
--------------------------------------------------------------------------------
1 | // 歌手粉丝
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | limit: query.limit || 20,
7 | offset: query.offset || 0,
8 | }
9 | return request('POST', `https://music.163.com/weapi/artist/fans/get`, data, {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | })
15 | }
16 |
--------------------------------------------------------------------------------
/module/artist_follow_count.js:
--------------------------------------------------------------------------------
1 | // 歌手粉丝数量
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | }
7 | return request(
8 | 'POST',
9 | `https://music.163.com/weapi/artist/follow/count/get`,
10 | data,
11 | {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | },
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/module/artist_list.js:
--------------------------------------------------------------------------------
1 | // 歌手分类
2 |
3 | /*
4 | type 取值
5 | 1:男歌手
6 | 2:女歌手
7 | 3:乐队
8 |
9 | area 取值
10 | -1:全部
11 | 7华语
12 | 96欧美
13 | 8:日本
14 | 16韩国
15 | 0:其他
16 |
17 | initial 取值 a-z/A-Z
18 | */
19 |
20 | module.exports = (query, request) => {
21 | const data = {
22 | initial: isNaN(query.initial)
23 | ? (query.initial || '').toUpperCase().charCodeAt() || undefined
24 | : query.initial,
25 | offset: query.offset || 0,
26 | limit: query.limit || 30,
27 | total: true,
28 | type: query.type || '1',
29 | area: query.area,
30 | }
31 | return request('POST', `https://music.163.com/api/v1/artist/list`, data, {
32 | crypto: 'weapi',
33 | cookie: query.cookie,
34 | proxy: query.proxy,
35 | realIP: query.realIP,
36 | })
37 | }
38 |
--------------------------------------------------------------------------------
/module/artist_mv.js:
--------------------------------------------------------------------------------
1 | // 歌手相关MV
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | artistId: query.id,
6 | limit: query.limit,
7 | offset: query.offset,
8 | total: true,
9 | }
10 | return request('POST', `https://music.163.com/weapi/artist/mvs`, data, {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | })
16 | }
17 |
--------------------------------------------------------------------------------
/module/artist_new_mv.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | query.cookie.os = 'ios'
3 | query.cookie.appver = '8.7.01'
4 | const data = {
5 | limit: query.limit || 20,
6 | startTimestamp: query.before || Date.now(),
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/api/sub/artist/new/works/mv/list`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/artist_new_song.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | query.cookie.os = 'ios'
3 | query.cookie.appver = '8.7.01'
4 | const data = {
5 | limit: query.limit || 20,
6 | startTimestamp: query.before || Date.now(),
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/api/sub/artist/new/works/song/list`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/artist_songs.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | query.cookie.os = 'pc'
3 | const data = {
4 | id: query.id,
5 | private_cloud: 'true',
6 | work_type: 1,
7 | order: query.order || 'hot', //hot,time
8 | offset: query.offset || 0,
9 | limit: query.limit || 100,
10 | }
11 | return request('POST', `https://music.163.com/api/v1/artist/songs`, data, {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | })
17 | }
18 |
--------------------------------------------------------------------------------
/module/artist_sub.js:
--------------------------------------------------------------------------------
1 | // 收藏与取消收藏歌手
2 |
3 | module.exports = (query, request) => {
4 | query.t = query.t == 1 ? 'sub' : 'unsub'
5 | const data = {
6 | artistId: query.id,
7 | artistIds: '[' + query.id + ']',
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/weapi/artist/${query.t}`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/artist_sublist.js:
--------------------------------------------------------------------------------
1 | // 关注歌手列表
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 25,
6 | offset: query.offset || 0,
7 | total: true,
8 | }
9 | return request('POST', `https://music.163.com/weapi/artist/sublist`, data, {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | })
15 | }
16 |
--------------------------------------------------------------------------------
/module/artist_top_song.js:
--------------------------------------------------------------------------------
1 | // 歌手热门 50 首歌曲
2 | module.exports = (query, request) => {
3 | const data = {
4 | id: query.id,
5 | }
6 | return request('POST', `https://music.163.com/api/artist/top/song`, data, {
7 | crypto: 'weapi',
8 | cookie: query.cookie,
9 | proxy: query.proxy,
10 | realIP: query.realIP,
11 | })
12 | }
13 |
--------------------------------------------------------------------------------
/module/artist_video.js:
--------------------------------------------------------------------------------
1 | // 歌手相关视频
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | artistId: query.id,
6 | page: JSON.stringify({
7 | size: query.size || 10,
8 | cursor: query.cursor || 0,
9 | }),
10 | tab: 0,
11 | order: query.order || 0,
12 | }
13 | return request(
14 | 'POST',
15 | `https://music.163.com/weapi/mlog/artist/video`,
16 | data,
17 | {
18 | crypto: 'weapi',
19 | cookie: query.cookie,
20 | proxy: query.proxy,
21 | realIP: query.realIP,
22 | },
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/module/artists.js:
--------------------------------------------------------------------------------
1 | // 歌手单曲
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/v1/artist/${query.id}`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/audio_match.js:
--------------------------------------------------------------------------------
1 | const realData =
2 | 'eJx10mtIU2EcBvDtnCwNMfO2klUSmSQ5ZugKW/v/0TIjJVdhDStbXpqXrhY5Kwhtrcwiut9VSqMUMxX6IFqsD92sD1YgWGHRBcowKrpnPa/v+drg4flt572ds2PQ6XQut7MwJ940w2TOyS0pzF+/BV/MJrNO+3TVLOHUzKx5iw3/H5uZ7yxegct3tTl7Cr6QEa0gZ/dZOFsvfe5YHe1D+yFZxpncqEj/cCdwoirdVxHNnZrX3xygU5g7Eh6I9uOx8Ch4y9FQjlKkDz1pYrFXIJLUOovFGcYivqJgXqaXDqu7Rzc0XzmZxG81B/fF8wRVusn2jN5rDnwca8tFhyAJP4L4qiI9vX8cWzEmVKzT/46qxNpIdZOZz2HNcHhSkZ3D4AjYFpfGFkX6+dB+FvcSBe/SWbkLPVnEOJ1DFelXxVVci/Wj4TsBLhrQ/LGoaU4HxsTA28L76Cc8Dfau/U6F6FgkyBDDJar0g8tesmOvOHioWeXXmme6l3MLbIIre6wciU5E2t/k8WVxHfHvuUWXsH4SPCv1NW1Cz0aivgYO34vw1AEvi3MlIw0xHl6JNVPEGW41UJsqPaXYYTuEnotMdHwYfv7CFR/i+aXmrY5wrlSkEwr+0EJ0GvLmdw4/RS9Amj93UAbGZMIF40ezE3PtcG/yBWrT3L6oh66hFyMXK4xsUKT7aufzapxnFTwiNc3Wis5Bdm+OYCvmOuHj/ZeoQPOI00PUrUjXpG+kMFU61tFFDvQaZOn5DH4mzoLw4Hsaj14rzu/K4jF66fSWTnJinW3wBvcveqjZN3iFjKp0qKuF1mi21keST3NtTcbwu1eG3Dussr9eemljLIco0tVH7HwA493wOr+FlIjfy+GvkR4uwfjt4v/6G8K3NX8K38lt6B1ISa+Bv2O8Fy69foZOovci2S4Lr1aku4P9OEWVTt9wgMQ7exgJ8JXyI0W694WFyuBjcH75XyrEXsfhg+ZSvqZIf/Lct8Wp0md2tJN4PifEfjcm8gu02Ptbj459eum8eg8bFWlLXTb/A+uo9bM='
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'pc'
5 | const data = {
6 | algorithmCode: 'shazam_v2',
7 | times: 1,
8 | sessionId: 'C999431ACDC84EDBB984763654E6F8D7',
9 | duration: 3.3066249999999995,
10 | from: 'recognize-song',
11 | rawdata: realData,
12 | }
13 | return request('POST', `https://music.163.com/api/music/audio/match`, data, {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/module/avatar_upload.js:
--------------------------------------------------------------------------------
1 | const uploadPlugin = require('../plugins/upload')
2 | module.exports = async (query, request) => {
3 | const uploadInfo = await uploadPlugin(query, request)
4 | const res = await request(
5 | 'POST',
6 | `https://music.163.com/weapi/user/avatar/upload/v1`,
7 | {
8 | imgid: uploadInfo.imgId,
9 | },
10 | {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | },
16 | )
17 | return {
18 | status: 200,
19 | body: {
20 | code: 200,
21 | data: {
22 | ...uploadInfo,
23 | ...res.body,
24 | },
25 | },
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/module/banner.js:
--------------------------------------------------------------------------------
1 | // 首页轮播图
2 |
3 | module.exports = (query, request) => {
4 | const type =
5 | {
6 | 0: 'pc',
7 | 1: 'android',
8 | 2: 'iphone',
9 | 3: 'ipad',
10 | }[query.type || 0] || 'pc'
11 | return request(
12 | 'POST',
13 | `https://music.163.com/api/v2/banner/get`,
14 | { clientType: type },
15 | { crypto: 'api', proxy: query.proxy, realIP: query.realIP },
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/module/batch.js:
--------------------------------------------------------------------------------
1 | // 批量请求接口
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | e_r: true,
6 | }
7 | Object.keys(query).forEach((i) => {
8 | if (/^\/api\//.test(i)) {
9 | data[i] = query[i]
10 | }
11 | })
12 | return request('POST', `https://music.163.com/eapi/batch`, data, {
13 | crypto: 'eapi',
14 | proxy: query.proxy,
15 | url: '/api/batch',
16 | cookie: query.cookie,
17 | realIP: query.realIP,
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/module/calendar.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {
3 | startTime: query.startTime || Date.now(),
4 | endTime: query.endTime || Date.now(),
5 | }
6 | return request('POST', `https://music.163.com/api/mcalendar/detail`, data, {
7 | crypto: 'weapi',
8 | cookie: query.cookie,
9 | proxy: query.proxy,
10 | realIP: query.realIP,
11 | })
12 | }
13 |
--------------------------------------------------------------------------------
/module/captcha_sent.js:
--------------------------------------------------------------------------------
1 | // 发送验证码
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | ctcode: query.ctcode || '86',
6 | cellphone: query.phone,
7 | }
8 | return request('POST', `https://music.163.com/api/sms/captcha/sent`, data, {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/module/captcha_verify.js:
--------------------------------------------------------------------------------
1 | // 校验验证码
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | ctcode: query.ctcode || '86',
6 | cellphone: query.phone,
7 | captcha: query.captcha,
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/weapi/sms/captcha/verify`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/cellphone_existence_check.js:
--------------------------------------------------------------------------------
1 | // 检测手机号码是否已注册
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | cellphone: query.phone,
6 | countrycode: query.countrycode,
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/eapi/cellphone/existence/check`,
11 | data,
12 | {
13 | crypto: 'eapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | url: '/api/cellphone/existence/check',
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/check_music.js:
--------------------------------------------------------------------------------
1 | // 歌曲可用性
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | ids: '[' + parseInt(query.id) + ']',
6 | br: parseInt(query.br || 999000),
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/weapi/song/enhance/player/url`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | ).then((response) => {
19 | let playable = false
20 | if (response.body.code == 200) {
21 | if (response.body.data[0].code == 200) {
22 | playable = true
23 | }
24 | }
25 | if (playable) {
26 | response.body = { success: true, message: 'ok' }
27 | return response
28 | } else {
29 | response.status = 404
30 | response.body = { success: false, message: '亲爱的,暂无版权' }
31 | return Promise.reject(response)
32 | }
33 | })
34 | }
35 |
--------------------------------------------------------------------------------
/module/cloud_match.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | query.cookie.os = 'ios'
3 | query.cookie.appver = '8.7.01'
4 | const data = {
5 | userId: query.uid,
6 | songId: query.sid,
7 | adjustSongId: query.asid,
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/api/cloud/user/song/match`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/cloudsearch.js:
--------------------------------------------------------------------------------
1 | // 搜索
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | s: query.keywords,
6 | type: query.type || 1, // 1: 单曲, 10: 专辑, 100: 歌手, 1000: 歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频
7 | limit: query.limit || 30,
8 | offset: query.offset || 0,
9 | total: true,
10 | }
11 | return request('POST', `https://music.163.com/api/cloudsearch/pc`, data, {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | })
17 | }
18 |
--------------------------------------------------------------------------------
/module/comment.js:
--------------------------------------------------------------------------------
1 | const { resourceTypeMap } = require('../util/config.json')
2 | // 发送与删除评论
3 |
4 | module.exports = (query, request) => {
5 | query.cookie.os = 'android'
6 | query.t = {
7 | 1: 'add',
8 | 0: 'delete',
9 | 2: 'reply',
10 | }[query.t]
11 | query.type = resourceTypeMap[query.type]
12 | const data = {
13 | threadId: query.type + query.id,
14 | }
15 |
16 | if (query.type == 'A_EV_2_') {
17 | data.threadId = query.threadId
18 | }
19 | if (query.t == 'add') data.content = query.content
20 | else if (query.t == 'delete') data.commentId = query.commentId
21 | else if (query.t == 'reply') {
22 | data.commentId = query.commentId
23 | data.content = query.content
24 | }
25 | return request(
26 | 'POST',
27 | `https://music.163.com/weapi/resource/comments/${query.t}`,
28 | data,
29 | {
30 | crypto: 'weapi',
31 | cookie: query.cookie,
32 | proxy: query.proxy,
33 | realIP: query.realIP,
34 | },
35 | )
36 | }
37 |
--------------------------------------------------------------------------------
/module/comment_album.js:
--------------------------------------------------------------------------------
1 | // 专辑评论
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'pc'
5 | const data = {
6 | rid: query.id,
7 | limit: query.limit || 20,
8 | offset: query.offset || 0,
9 | beforeTime: query.before || 0,
10 | }
11 | return request(
12 | 'POST',
13 | `https://music.163.com/weapi/v1/resource/comments/R_AL_3_${query.id}`,
14 | data,
15 | {
16 | crypto: 'weapi',
17 | cookie: query.cookie,
18 | proxy: query.proxy,
19 | realIP: query.realIP,
20 | },
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/module/comment_dj.js:
--------------------------------------------------------------------------------
1 | // 电台评论
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'pc'
5 | const data = {
6 | rid: query.id,
7 | limit: query.limit || 20,
8 | offset: query.offset || 0,
9 | beforeTime: query.before || 0,
10 | }
11 | return request(
12 | 'POST',
13 | `https://music.163.com/weapi/v1/resource/comments/A_DJ_1_${query.id}`,
14 | data,
15 | {
16 | crypto: 'weapi',
17 | cookie: query.cookie,
18 | proxy: query.proxy,
19 | realIP: query.realIP,
20 | },
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/module/comment_event.js:
--------------------------------------------------------------------------------
1 | // 获取动态评论
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 20,
6 | offset: query.offset || 0,
7 | beforeTime: query.before || 0,
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/weapi/v1/resource/comments/${query.threadId}`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/comment_floor.js:
--------------------------------------------------------------------------------
1 | const { resourceTypeMap } = require('../util/config.json')
2 | module.exports = (query, request) => {
3 | query.type = resourceTypeMap[query.type]
4 | const data = {
5 | parentCommentId: query.parentCommentId,
6 | threadId: query.type + query.id,
7 | time: query.time || -1,
8 | limit: query.limit || 20,
9 | }
10 | return request(
11 | 'POST',
12 | `https://music.163.com/api/resource/comment/floor/get`,
13 | data,
14 | {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | },
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/module/comment_hot.js:
--------------------------------------------------------------------------------
1 | const { resourceTypeMap } = require('../util/config.json')
2 | // 热门评论
3 |
4 | module.exports = (query, request) => {
5 | query.cookie.os = 'pc'
6 | query.type = resourceTypeMap[query.type]
7 | const data = {
8 | rid: query.id,
9 | limit: query.limit || 20,
10 | offset: query.offset || 0,
11 | beforeTime: query.before || 0,
12 | }
13 | return request(
14 | 'POST',
15 | `https://music.163.com/weapi/v1/resource/hotcomments/${query.type}${query.id}`,
16 | data,
17 | {
18 | crypto: 'weapi',
19 | cookie: query.cookie,
20 | proxy: query.proxy,
21 | realIP: query.realIP,
22 | },
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/module/comment_hug_list.js:
--------------------------------------------------------------------------------
1 | const { resourceTypeMap } = require('../util/config.json')
2 | module.exports = (query, request) => {
3 | query.cookie.os = 'ios'
4 | query.cookie.appver = '8.7.01'
5 | query.type = resourceTypeMap[query.type || 0]
6 | const threadId = query.type + query.sid
7 | const data = {
8 | targetUserId: query.uid,
9 | commentId: query.cid,
10 | cursor: query.cursor || '-1',
11 | threadId: threadId,
12 | pageNo: query.page || 1,
13 | idCursor: query.idCursor || -1,
14 | pageSize: query.pageSize || 100,
15 | }
16 | return request(
17 | 'POST',
18 | `https://music.163.com/api/v2/resource/comments/hug/list`,
19 | data,
20 | {
21 | crypto: 'api',
22 | cookie: query.cookie,
23 | proxy: query.proxy,
24 | realIP: query.realIP,
25 | },
26 | )
27 | }
28 |
--------------------------------------------------------------------------------
/module/comment_like.js:
--------------------------------------------------------------------------------
1 | const { resourceTypeMap } = require('../util/config.json')
2 | // 点赞与取消点赞评论
3 |
4 | module.exports = (query, request) => {
5 | query.cookie.os = 'pc'
6 | query.t = query.t == 1 ? 'like' : 'unlike'
7 | query.type = resourceTypeMap[query.type]
8 | const data = {
9 | threadId: query.type + query.id,
10 | commentId: query.cid,
11 | }
12 | if (query.type == 'A_EV_2_') {
13 | data.threadId = query.threadId
14 | }
15 | return request(
16 | 'POST',
17 | `https://music.163.com/weapi/v1/comment/${query.t}`,
18 | data,
19 | {
20 | crypto: 'weapi',
21 | cookie: query.cookie,
22 | proxy: query.proxy,
23 | realIP: query.realIP,
24 | },
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/module/comment_music.js:
--------------------------------------------------------------------------------
1 | // 歌曲评论
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'pc'
5 | const data = {
6 | rid: query.id,
7 | limit: query.limit || 20,
8 | offset: query.offset || 0,
9 | beforeTime: query.before || 0,
10 | }
11 | return request(
12 | 'POST',
13 | `https://music.163.com/api/v1/resource/comments/R_SO_4_${query.id}`,
14 | data,
15 | {
16 | crypto: 'weapi',
17 | cookie: query.cookie,
18 | proxy: query.proxy,
19 | realIP: query.realIP,
20 | },
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/module/comment_mv.js:
--------------------------------------------------------------------------------
1 | // MV评论
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'pc'
5 | const data = {
6 | rid: query.id,
7 | limit: query.limit || 20,
8 | offset: query.offset || 0,
9 | beforeTime: query.before || 0,
10 | }
11 | return request(
12 | 'POST',
13 | `https://music.163.com/weapi/v1/resource/comments/R_MV_5_${query.id}`,
14 | data,
15 | {
16 | crypto: 'weapi',
17 | cookie: query.cookie,
18 | proxy: query.proxy,
19 | realIP: query.realIP,
20 | },
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/module/comment_new.js:
--------------------------------------------------------------------------------
1 | const { resourceTypeMap } = require('../util/config.json')
2 | // 评论
3 |
4 | module.exports = (query, request) => {
5 | query.cookie.os = 'pc'
6 | query.type = resourceTypeMap[query.type]
7 | const threadId = query.type + query.id
8 | const pageSize = query.pageSize || 20
9 | const pageNo = query.pageNo || 1
10 | let sortType = Number(query.sortType) || 99
11 | if (sortType === 1) {
12 | sortType = 99
13 | }
14 | let cursor = ''
15 | switch (sortType) {
16 | case 99:
17 | cursor = (pageNo - 1) * pageSize
18 | break
19 | case 2:
20 | cursor = 'normalHot#' + (pageNo - 1) * pageSize
21 | break
22 | case 3:
23 | cursor = query.cursor || '0'
24 | break
25 | default:
26 | break
27 | }
28 | const data = {
29 | threadId: threadId,
30 | pageNo,
31 | showInner: query.showInner || true,
32 | pageSize,
33 | cursor: cursor,
34 | sortType: sortType, //99:按推荐排序,2:按热度排序,3:按时间排序
35 | }
36 | return request(
37 | 'POST',
38 | `https://music.163.com/api/v2/resource/comments`,
39 | data,
40 | {
41 | crypto: 'eapi',
42 | cookie: query.cookie,
43 | proxy: query.proxy,
44 | realIP: query.realIP,
45 | url: '/api/v2/resource/comments',
46 | },
47 | )
48 | }
49 |
--------------------------------------------------------------------------------
/module/comment_playlist.js:
--------------------------------------------------------------------------------
1 | // 歌单评论
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'pc'
5 | const data = {
6 | rid: query.id,
7 | limit: query.limit || 20,
8 | offset: query.offset || 0,
9 | beforeTime: query.before || 0,
10 | }
11 | return request(
12 | 'POST',
13 | `https://music.163.com/weapi/v1/resource/comments/A_PL_0_${query.id}`,
14 | data,
15 | {
16 | crypto: 'weapi',
17 | cookie: query.cookie,
18 | proxy: query.proxy,
19 | realIP: query.realIP,
20 | },
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/module/comment_video.js:
--------------------------------------------------------------------------------
1 | // 视频评论
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'pc'
5 | const data = {
6 | rid: query.id,
7 | limit: query.limit || 20,
8 | offset: query.offset || 0,
9 | beforeTime: query.before || 0,
10 | }
11 | return request(
12 | 'POST',
13 | `https://music.163.com/weapi/v1/resource/comments/R_VI_62_${query.id}`,
14 | data,
15 | {
16 | crypto: 'weapi',
17 | cookie: query.cookie,
18 | proxy: query.proxy,
19 | realIP: query.realIP,
20 | },
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/module/countries_code_list.js:
--------------------------------------------------------------------------------
1 | // 国家编码列表
2 | module.exports = (query, request) => {
3 | const data = {}
4 | return request(
5 | 'POST',
6 | `https://interface3.music.163.com/eapi/lbs/countries/v1`,
7 | data,
8 | {
9 | crypto: 'eapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | url: '/api/lbs/countries/v1',
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/daily_signin.js:
--------------------------------------------------------------------------------
1 | // 签到
2 |
3 | /*
4 | 0为安卓端签到 3点经验, 1为网页签到,2点经验
5 | 签到成功 {'android': {'point': 3, 'code': 200}, 'web': {'point': 2, 'code': 200}}
6 | 重复签到 {'android': {'code': -2, 'msg': '重复签到'}, 'web': {'code': -2, 'msg': '重复签到'}}
7 | 未登录 {'android': {'code': 301}, 'web': {'code': 301}}
8 | */
9 |
10 | module.exports = (query, request) => {
11 | const data = {
12 | type: query.type || 0,
13 | }
14 | return request('POST', `https://music.163.com/weapi/point/dailyTask`, data, {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | })
20 | }
21 |
--------------------------------------------------------------------------------
/module/digitalAlbum_detail.js:
--------------------------------------------------------------------------------
1 | // 数字专辑详情
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | }
7 | return request(
8 | 'POST',
9 | `https://music.163.com/weapi/vipmall/albumproduct/detail`,
10 | data,
11 | {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | },
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/module/digitalAlbum_ordering.js:
--------------------------------------------------------------------------------
1 | // 购买数字专辑
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | business: 'Album',
6 | paymentMethod: query.payment,
7 | digitalResources: JSON.stringify([
8 | {
9 | business: 'Album',
10 | resourceID: query.id,
11 | quantity: query.quantity,
12 | },
13 | ]),
14 | from: 'web',
15 | }
16 | return request(
17 | 'POST',
18 | `https://music.163.com/api/ordering/web/digital`,
19 | data,
20 | {
21 | crypto: 'weapi',
22 | cookie: query.cookie,
23 | proxy: query.proxy,
24 | realIP: query.realIP,
25 | },
26 | )
27 | }
28 |
--------------------------------------------------------------------------------
/module/digitalAlbum_purchased.js:
--------------------------------------------------------------------------------
1 | // 我的数字专辑
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 30,
6 | offset: query.offset || 0,
7 | total: true,
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/api/digitalAlbum/purchased`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/digitalAlbum_sales.js:
--------------------------------------------------------------------------------
1 | // 数字专辑销量
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | albumIds: query.ids,
6 | }
7 | return request(
8 | 'POST',
9 | `https://music.163.com/weapi/vipmall/albumproduct/album/query/sales`,
10 | data,
11 | {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | },
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/module/dj_banner.js:
--------------------------------------------------------------------------------
1 | // 电台banner
2 |
3 | module.exports = (query, request) => {
4 | const data = {}
5 | query.cookie.os = 'pc'
6 | return request(
7 | 'POST',
8 | `https://music.163.com/weapi/djradio/banner/get`,
9 | {},
10 | {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | },
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/module/dj_category_excludehot.js:
--------------------------------------------------------------------------------
1 | // 电台非热门类型
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/djradio/category/excludehot`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/dj_category_recommend.js:
--------------------------------------------------------------------------------
1 | // 电台推荐类型
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/djradio/home/category/recommend`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/dj_catelist.js:
--------------------------------------------------------------------------------
1 | // 电台分类列表
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/djradio/category/get`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/dj_detail.js:
--------------------------------------------------------------------------------
1 | // 电台详情
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.rid,
6 | }
7 | return request('POST', `https://music.163.com/api/djradio/v2/get`, data, {
8 | crypto: 'weapi',
9 | cookie: query.cookie,
10 | proxy: query.proxy,
11 | realIP: query.realIP,
12 | })
13 | }
14 |
--------------------------------------------------------------------------------
/module/dj_hot.js:
--------------------------------------------------------------------------------
1 | // 热门电台
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 30,
6 | offset: query.offset || 0,
7 | }
8 | return request('POST', `https://music.163.com/weapi/djradio/hot/v1`, data, {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/module/dj_paygift.js:
--------------------------------------------------------------------------------
1 | // 付费电台
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 30,
6 | offset: query.offset || 0,
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/weapi/djradio/home/paygift/list?_nmclfl=1`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/dj_personalize_recommend.js:
--------------------------------------------------------------------------------
1 | // 电台个性推荐
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/api/djradio/personalize/rcmd`,
7 | {
8 | limit: query.limit || 6,
9 | },
10 | {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | },
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/module/dj_program.js:
--------------------------------------------------------------------------------
1 | // 电台节目列表
2 | const { toBoolean } = require('../util')
3 | module.exports = (query, request) => {
4 | const data = {
5 | radioId: query.rid,
6 | limit: query.limit || 30,
7 | offset: query.offset || 0,
8 | asc: toBoolean(query.asc),
9 | }
10 | return request(
11 | 'POST',
12 | `https://music.163.com/weapi/dj/program/byradio`,
13 | data,
14 | {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | },
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/module/dj_program_detail.js:
--------------------------------------------------------------------------------
1 | // 电台节目详情
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | }
7 | return request('POST', `https://music.163.com/api/dj/program/detail`, data, {
8 | crypto: 'weapi',
9 | cookie: query.cookie,
10 | proxy: query.proxy,
11 | realIP: query.realIP,
12 | })
13 | }
14 |
--------------------------------------------------------------------------------
/module/dj_program_toplist.js:
--------------------------------------------------------------------------------
1 | // 电台节目榜
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 100,
6 | offset: query.offset || 0,
7 | }
8 | return request('POST', `https://music.163.com/api/program/toplist/v1`, data, {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/module/dj_program_toplist_hours.js:
--------------------------------------------------------------------------------
1 | // 电台24小时节目榜
2 | module.exports = (query, request) => {
3 | const data = {
4 | limit: query.limit || 100,
5 | // 不支持 offset
6 | }
7 | return request(
8 | 'POST',
9 | `https://music.163.com/api/djprogram/toplist/hours`,
10 | data,
11 | {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | },
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/module/dj_radio_hot.js:
--------------------------------------------------------------------------------
1 | // 类别热门电台
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | cateId: query.cateId,
6 | limit: query.limit || 30,
7 | offset: query.offset || 0,
8 | }
9 | return request('POST', `https://music.163.com/api/djradio/hot`, data, {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | })
15 | }
16 |
--------------------------------------------------------------------------------
/module/dj_recommend.js:
--------------------------------------------------------------------------------
1 | // 精选电台
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/djradio/recommend/v1`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/dj_recommend_type.js:
--------------------------------------------------------------------------------
1 | // 精选电台分类
2 |
3 | /*
4 | 有声书 10001
5 | 知识技能 453050
6 | 商业财经 453051
7 | 人文历史 11
8 | 外语世界 13
9 | 亲子宝贝 14
10 | 创作|翻唱 2001
11 | 音乐故事 2
12 | 3D|电子 10002
13 | 相声曲艺 8
14 | 情感调频 3
15 | 美文读物 6
16 | 脱口秀 5
17 | 广播剧 7
18 | 二次元 3001
19 | 明星做主播 1
20 | 娱乐|影视 4
21 | 科技科学 453052
22 | 校园|教育 4001
23 | 旅途|城市 12
24 | */
25 |
26 | module.exports = (query, request) => {
27 | const data = {
28 | cateId: query.type,
29 | }
30 | return request(
31 | 'POST',
32 | `https://music.163.com/weapi/djradio/recommend`,
33 | data,
34 | {
35 | crypto: 'weapi',
36 | cookie: query.cookie,
37 | proxy: query.proxy,
38 | realIP: query.realIP,
39 | },
40 | )
41 | }
42 |
--------------------------------------------------------------------------------
/module/dj_sub.js:
--------------------------------------------------------------------------------
1 | // 订阅与取消电台
2 |
3 | module.exports = (query, request) => {
4 | query.t = query.t == 1 ? 'sub' : 'unsub'
5 | const data = {
6 | id: query.rid,
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/weapi/djradio/${query.t}`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/dj_sublist.js:
--------------------------------------------------------------------------------
1 | // 订阅电台列表
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 30,
6 | offset: query.offset || 0,
7 | total: true,
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/weapi/djradio/get/subed`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/dj_subscriber.js:
--------------------------------------------------------------------------------
1 | // 电台详情
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | time: query.time || '-1',
6 | id: query.id,
7 | limit: query.limit || '20',
8 | total: 'true',
9 | }
10 | return request('POST', `https://music.163.com/api/djradio/subscriber`, data, {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | })
16 | }
17 |
--------------------------------------------------------------------------------
/module/dj_today_perfered.js:
--------------------------------------------------------------------------------
1 | // 电台今日优选
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | page: query.page || 0,
6 | }
7 | return request(
8 | 'POST',
9 | `https://music.163.com/weapi/djradio/home/today/perfered`,
10 | data,
11 | {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | },
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/module/dj_toplist.js:
--------------------------------------------------------------------------------
1 | // 新晋电台榜/热门电台榜
2 | const typeMap = {
3 | new: 0,
4 | hot: 1,
5 | }
6 | module.exports = (query, request) => {
7 | const data = {
8 | limit: query.limit || 100,
9 | offset: query.offset || 0,
10 | type: typeMap[query.type || 'new'] || '0', //0为新晋,1为热门
11 | }
12 | return request('POST', `https://music.163.com/api/djradio/toplist`, data, {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/module/dj_toplist_hours.js:
--------------------------------------------------------------------------------
1 | // 电台24小时主播榜
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 100,
6 | // 不支持 offset
7 | }
8 | return request('POST', `https://music.163.com/api/dj/toplist/hours`, data, {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/module/dj_toplist_newcomer.js:
--------------------------------------------------------------------------------
1 | // 电台新人榜
2 | module.exports = (query, request) => {
3 | const data = {
4 | limit: query.limit || 100,
5 | offset: query.offset || 0,
6 | }
7 | return request(
8 | 'POST',
9 | `https://music.163.com/api/dj/toplist/newcomer`,
10 | data,
11 | {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | },
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/module/dj_toplist_pay.js:
--------------------------------------------------------------------------------
1 | // 付费精品
2 | module.exports = (query, request) => {
3 | const data = {
4 | limit: query.limit || 100,
5 | // 不支持 offset
6 | }
7 | return request(
8 | 'POST',
9 | `https://music.163.com/api/djradio/toplist/pay`,
10 | data,
11 | {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | },
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/module/dj_toplist_popular.js:
--------------------------------------------------------------------------------
1 | // 电台最热主播榜
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 100,
6 | // 不支持 offset
7 | }
8 | return request('POST', `https://music.163.com/api/dj/toplist/popular`, data, {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/module/event.js:
--------------------------------------------------------------------------------
1 | // 动态
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | pagesize: query.pagesize || 20,
6 | lasttime: query.lasttime || -1,
7 | }
8 | return request('POST', `https://music.163.com/weapi/v1/event/get`, data, {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/module/event_del.js:
--------------------------------------------------------------------------------
1 | // 删除动态
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.evId,
6 | }
7 | return request('POST', `https://music.163.com/eapi/event/delete`, data, {
8 | crypto: 'weapi',
9 | cookie: query.cookie,
10 | proxy: query.proxy,
11 | realIP: query.realIP,
12 | })
13 | }
14 |
--------------------------------------------------------------------------------
/module/event_forward.js:
--------------------------------------------------------------------------------
1 | // 转发动态
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'pc'
5 | const data = {
6 | forwards: query.forwards,
7 | id: query.evId,
8 | eventUserId: query.uid,
9 | }
10 | return request('POST', `https://music.163.com/weapi/event/forward`, data, {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | })
16 | }
17 |
--------------------------------------------------------------------------------
/module/fm_trash.js:
--------------------------------------------------------------------------------
1 | // 垃圾桶
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | songId: query.id,
6 | }
7 | return request(
8 | 'POST',
9 | `https://music.163.com/weapi/radio/trash/add?alg=RT&songId=${
10 | query.id
11 | }&time=${query.time || 25}`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/follow.js:
--------------------------------------------------------------------------------
1 | // 关注与取消关注用户
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'pc'
5 | query.t = query.t == 1 ? 'follow' : 'delfollow'
6 | return request(
7 | 'POST',
8 | `https://music.163.com/weapi/user/${query.t}/${query.id}`,
9 | {},
10 | {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | },
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/module/history_recommend_songs.js:
--------------------------------------------------------------------------------
1 | // 历史每日推荐歌曲
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'ios'
5 | const data = {}
6 | return request(
7 | 'POST',
8 | `https://music.163.com/api/discovery/recommend/songs/history/recent`,
9 | data,
10 | {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | },
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/module/history_recommend_songs_detail.js:
--------------------------------------------------------------------------------
1 | // 历史每日推荐歌曲详情
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'ios'
5 | const data = {
6 | date: query.date || '',
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/api/discovery/recommend/songs/history/detail`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/homepage_block_page.js:
--------------------------------------------------------------------------------
1 | // 首页-发现 block page
2 | // 这个接口为移动端接口,首页-发现页,数据结构可以参考 https://github.com/hcanyz/flutter-netease-music-api/blob/master/lib/src/api/uncategorized/bean.dart#L259 HomeBlockPageWrap
3 | // query.refresh 是否刷新数据
4 | module.exports = (query, request) => {
5 | query.cookie.os = 'ios'
6 | query.cookie.appver = '8.7.01'
7 | const data = { refresh: query.refresh || false, cursor: query.cursor }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/api/homepage/block/page`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/homepage_dragon_ball.js:
--------------------------------------------------------------------------------
1 | // 首页-发现 dragon ball
2 | // 这个接口为移动端接口,首页-发现页(每日推荐、歌单、排行榜 那些入口)
3 | // 数据结构可以参考 https://github.com/hcanyz/flutter-netease-music-api/blob/master/lib/src/api/uncategorized/bean.dart#L290 HomeDragonBallWrap
4 | // !需要登录或者匿名登录,非登录返回 []
5 | const config = require('../util/config.json')
6 | module.exports = (query, request) => {
7 | if (!('MUSIC_U' in query.cookie))
8 | query.cookie.MUSIC_A = config.anonymous_token
9 | const data = {}
10 | query.cookie.os = 'ios'
11 | query.cookie.appver = '8.7.01'
12 | return request(
13 | 'POST',
14 | `https://music.163.com/eapi/homepage/dragon/ball/static`,
15 | data,
16 | {
17 | crypto: 'eapi',
18 | cookie: query.cookie,
19 | proxy: query.proxy,
20 | url: '/api/homepage/dragon/ball/static',
21 | realIP: query.realIP,
22 | },
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/module/hot_topic.js:
--------------------------------------------------------------------------------
1 | //热门话题
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 20,
6 | offset: query.offset || 0,
7 | }
8 | return request('POST', `https://music.163.com/api/act/hot`, data, {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/module/hug_comment.js:
--------------------------------------------------------------------------------
1 | const { resourceTypeMap } = require('../util/config.json')
2 | module.exports = (query, request) => {
3 | query.cookie.os = 'ios'
4 | query.cookie.appver = '8.7.01'
5 | query.type = resourceTypeMap[query.type || 0]
6 | const threadId = query.type + query.sid
7 | const data = {
8 | targetUserId: query.uid,
9 | commentId: query.cid,
10 | threadId: threadId,
11 | }
12 | return request(
13 | 'POST',
14 | `https://music.163.com/api/v2/resource/comments/hug/listener`,
15 | data,
16 | {
17 | crypto: 'api',
18 | cookie: query.cookie,
19 | proxy: query.proxy,
20 | realIP: query.realIP,
21 | },
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/module/inner_version.js:
--------------------------------------------------------------------------------
1 | const pkg = require('../package.json')
2 | module.exports = (query, request) => {
3 | return new Promise((resolve) => {
4 | return resolve({
5 | code: 200,
6 | status: 200,
7 | body: {
8 | code: 200,
9 | data: {
10 | version: pkg.version,
11 | },
12 | },
13 | })
14 | })
15 | }
16 |
--------------------------------------------------------------------------------
/module/like.js:
--------------------------------------------------------------------------------
1 | // 红心与取消红心歌曲
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'pc'
5 | query.cookie.appver = '2.9.7'
6 | query.like = query.like == 'false' ? false : true
7 | const data = {
8 | alg: 'itembased',
9 | trackId: query.id,
10 | like: query.like,
11 | time: '3',
12 | }
13 | return request('POST', `https://music.163.com/api/radio/like`, data, {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/module/likelist.js:
--------------------------------------------------------------------------------
1 | // 喜欢的歌曲(无序)
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | uid: query.uid,
6 | }
7 | return request('POST', `https://music.163.com/weapi/song/like/get`, data, {
8 | crypto: 'weapi',
9 | cookie: query.cookie,
10 | proxy: query.proxy,
11 | realIP: query.realIP,
12 | })
13 | }
14 |
--------------------------------------------------------------------------------
/module/listen_together_status.js:
--------------------------------------------------------------------------------
1 | // 一起听状态
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/api/listen/together/status/get`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/login.js:
--------------------------------------------------------------------------------
1 | // 邮箱登录
2 |
3 | const crypto = require('crypto')
4 |
5 | module.exports = async (query, request) => {
6 | query.cookie.os = 'pc'
7 | query.cookie.appver = '2.9.7'
8 | const data = {
9 | username: query.email,
10 | password:
11 | query.md5_password ||
12 | crypto.createHash('md5').update(query.password).digest('hex'),
13 | rememberLogin: 'true',
14 | }
15 | let result = await request('POST', `https://music.163.com/api/login`, data, {
16 | crypto: 'weapi',
17 | ua: 'pc',
18 | cookie: query.cookie,
19 | proxy: query.proxy,
20 | realIP: query.realIP,
21 | })
22 | if (result.body.code === 502) {
23 | return {
24 | status: 200,
25 | body: {
26 | msg: '账号或密码错误',
27 | code: 502,
28 | message: '账号或密码错误',
29 | },
30 | }
31 | }
32 | if (result.body.code === 200) {
33 | result = {
34 | status: 200,
35 | body: {
36 | ...result.body,
37 | cookie: result.cookie.join(';'),
38 | },
39 | cookie: result.cookie,
40 | }
41 | }
42 | return result
43 | }
44 |
--------------------------------------------------------------------------------
/module/login_cellphone.js:
--------------------------------------------------------------------------------
1 | // 手机登录
2 |
3 | const crypto = require('crypto')
4 |
5 | module.exports = async (query, request) => {
6 | query.cookie.os = 'pc'
7 | query.cookie.appver = '2.9.7'
8 | const data = {
9 | phone: query.phone,
10 | countrycode: query.countrycode || '86',
11 | captcha: query.captcha,
12 | [query.captcha ? 'captcha' : 'password']: query.captcha
13 | ? query.captcha
14 | : query.md5_password ||
15 | crypto.createHash('md5').update(query.password).digest('hex'),
16 | rememberLogin: 'true',
17 | }
18 | let result = await request(
19 | 'POST',
20 | `https://music.163.com/api/login/cellphone`,
21 | data,
22 | {
23 | crypto: 'weapi',
24 | ua: 'pc',
25 | cookie: query.cookie,
26 | proxy: query.proxy,
27 | realIP: query.realIP,
28 | },
29 | )
30 |
31 | if (result.body.code === 200) {
32 | result = {
33 | status: 200,
34 | body: {
35 | ...result.body,
36 | cookie: result.cookie.join(';'),
37 | },
38 | cookie: result.cookie,
39 | }
40 | }
41 | return result
42 | }
43 |
--------------------------------------------------------------------------------
/module/login_qr_check.js:
--------------------------------------------------------------------------------
1 | module.exports = async (query, request) => {
2 | const data = {
3 | key: query.key,
4 | type: 1,
5 | }
6 | try {
7 | let result = await request(
8 | 'POST',
9 | `https://music.163.com/weapi/login/qrcode/client/login`,
10 | data,
11 | {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | },
17 | )
18 | result = {
19 | status: 200,
20 | body: {
21 | ...result.body,
22 | cookie: result.cookie.join(';'),
23 | },
24 | cookie: result.cookie,
25 | }
26 | return result
27 | } catch (error) {
28 | return {
29 | status: 200,
30 | body: {},
31 | cookie: result.cookie,
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/module/login_qr_create.js:
--------------------------------------------------------------------------------
1 | const QRCode = require('qrcode')
2 |
3 | module.exports = (query, request) => {
4 | return new Promise(async (resolve) => {
5 | const url = `https://music.163.com/login?codekey=${query.key}`
6 | return resolve({
7 | code: 200,
8 | status: 200,
9 | body: {
10 | code: 200,
11 | data: {
12 | qrurl: url,
13 | qrimg: query.qrimg ? await QRCode.toDataURL(url) : '',
14 | },
15 | },
16 | })
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/module/login_qr_key.js:
--------------------------------------------------------------------------------
1 | module.exports = async (query, request) => {
2 | const data = {
3 | type: 1,
4 | }
5 | const result = await request(
6 | 'POST',
7 | `https://music.163.com/weapi/login/qrcode/unikey`,
8 | data,
9 | {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | return {
17 | status: 200,
18 | body: {
19 | data: result.body,
20 | code: 200,
21 | },
22 | cookie: result.cookie,
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/module/login_refresh.js:
--------------------------------------------------------------------------------
1 | // 登录刷新
2 |
3 | module.exports = async (query, request) => {
4 | let result = await request(
5 | 'POST',
6 | `https://music.163.com/weapi/login/token/refresh`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | ua: 'pc',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | if (result.body.code === 200) {
17 | result = {
18 | status: 200,
19 | body: {
20 | ...result.body,
21 | cookie: result.cookie.join(';'),
22 | },
23 | cookie: result.cookie,
24 | }
25 | }
26 | return result
27 | }
28 |
--------------------------------------------------------------------------------
/module/login_status.js:
--------------------------------------------------------------------------------
1 | module.exports = async (query, request) => {
2 | const data = {}
3 | let result = await request(
4 | 'POST',
5 | `https://music.163.com/weapi/w/nuser/account/get`,
6 | data,
7 | {
8 | crypto: 'weapi',
9 | cookie: query.cookie,
10 | proxy: query.proxy,
11 | realIP: query.realIP,
12 | },
13 | )
14 | if (result.body.code === 200) {
15 | result = {
16 | status: 200,
17 | body: {
18 | data: {
19 | ...result.body,
20 | },
21 | },
22 | cookie: result.cookie,
23 | }
24 | }
25 | return result
26 | }
27 |
--------------------------------------------------------------------------------
/module/logout.js:
--------------------------------------------------------------------------------
1 | // 退出登录
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/logout`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | ua: 'pc',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/lyric.js:
--------------------------------------------------------------------------------
1 | // 歌词
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'ios'
5 |
6 | const data = {
7 | id: query.id,
8 | tv: -1,
9 | lv: -1,
10 | rv: -1,
11 | kv: -1,
12 | }
13 | return request(
14 | 'POST',
15 | `https://music.163.com/api/song/lyric?_nmclfl=1`,
16 | data,
17 | {
18 | crypto: 'api',
19 | cookie: query.cookie,
20 | proxy: query.proxy,
21 | realIP: query.realIP,
22 | },
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/module/mlog_music_rcmd.js:
--------------------------------------------------------------------------------
1 | // 歌曲相关视频
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.mvid || 0,
6 | type: 2,
7 | rcmdType: 20,
8 | limit: query.limit || 10,
9 | extInfo: JSON.stringify({ songId: query.songid }),
10 | }
11 | return request(
12 | 'POST',
13 | `https://interface.music.163.com/eapi/mlog/rcmd/feed/list`,
14 | data,
15 | {
16 | crypto: 'eapi',
17 | cookie: query.cookie,
18 | proxy: query.proxy,
19 | url: '/api/mlog/rcmd/feed/list',
20 | realIP: query.realIP,
21 | },
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/module/mlog_to_video.js:
--------------------------------------------------------------------------------
1 | // 将mlog id转为video id
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | mlogId: query.id,
6 | }
7 | return request(
8 | 'POST',
9 | `https://music.163.com/weapi/mlog/video/convert/id`,
10 | data,
11 | {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | },
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/module/mlog_url.js:
--------------------------------------------------------------------------------
1 | // mlog链接
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | resolution: query.res || 1080,
7 | type: 1,
8 | }
9 | return request('POST', `https://music.163.com/weapi/mlog/detail/v1`, data, {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | })
15 | }
16 |
--------------------------------------------------------------------------------
/module/msg_comments.js:
--------------------------------------------------------------------------------
1 | // 评论
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | beforeTime: query.before || '-1',
6 | limit: query.limit || 30,
7 | total: 'true',
8 | uid: query.uid,
9 | }
10 |
11 | return request(
12 | 'POST',
13 | `https://music.163.com/api/v1/user/comments/${query.uid}`,
14 | data,
15 | {
16 | crypto: 'weapi',
17 | cookie: query.cookie,
18 | proxy: query.proxy,
19 | realIP: query.realIP,
20 | },
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/module/msg_forwards.js:
--------------------------------------------------------------------------------
1 | // @我
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | offset: query.offset || 0,
6 | limit: query.limit || 30,
7 | total: 'true',
8 | }
9 | return request('POST', `https://music.163.com/api/forwards/get`, data, {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | })
15 | }
16 |
--------------------------------------------------------------------------------
/module/msg_notices.js:
--------------------------------------------------------------------------------
1 | // 通知
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 30,
6 | time: query.lasttime || -1,
7 | }
8 | return request('POST', `https://music.163.com/api/msg/notices`, data, {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/module/msg_private.js:
--------------------------------------------------------------------------------
1 | // 私信
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | offset: query.offset || 0,
6 | limit: query.limit || 30,
7 | total: 'true',
8 | }
9 | return request('POST', `https://music.163.com/api/msg/private/users`, data, {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | })
15 | }
16 |
--------------------------------------------------------------------------------
/module/msg_private_history.js:
--------------------------------------------------------------------------------
1 | // 私信内容
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | userId: query.uid,
6 | limit: query.limit || 30,
7 | time: query.before || 0,
8 | total: 'true',
9 | }
10 | return request(
11 | 'POST',
12 | `https://music.163.com/api/msg/private/history`,
13 | data,
14 | {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | },
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/module/msg_recentcontact.js:
--------------------------------------------------------------------------------
1 | // 最近联系
2 |
3 | module.exports = (query, request) => {
4 | const data = {}
5 | return request(
6 | 'POST',
7 | `https://music.163.com/api/msg/recentcontact/get`,
8 | data,
9 | {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/musician_cloudbean.js:
--------------------------------------------------------------------------------
1 | // 账号云豆数
2 |
3 | module.exports = (query, request) => {
4 | const data = {}
5 | return request('POST', `https://music.163.com/weapi/cloudbean/get`, data, {
6 | crypto: 'weapi',
7 | cookie: query.cookie,
8 | proxy: query.proxy,
9 | realIP: query.realIP,
10 | })
11 | }
12 |
--------------------------------------------------------------------------------
/module/musician_cloudbean_obtain.js:
--------------------------------------------------------------------------------
1 | // 领取云豆
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | userMissionId: query.id,
6 | period: query.period,
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/weapi/nmusician/workbench/mission/reward/obtain/new`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/musician_data_overview.js:
--------------------------------------------------------------------------------
1 | // 音乐人数据概况
2 |
3 | module.exports = (query, request) => {
4 | const data = {}
5 | return request(
6 | 'POST',
7 | `https://music.163.com/weapi/creator/musician/statistic/data/overview/get`,
8 | data,
9 | {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/musician_play_trend.js:
--------------------------------------------------------------------------------
1 | // 音乐人歌曲播放趋势
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | startTime: query.startTime,
6 | endTime: query.endTime,
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/weapi/creator/musician/play/count/statistic/data/trend/get`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/musician_sign.js:
--------------------------------------------------------------------------------
1 | // 音乐人签到
2 |
3 | module.exports = (query, request) => {
4 | const data = {}
5 | return request(
6 | 'POST',
7 | `https://music.163.com/weapi/creator/user/access`,
8 | data,
9 | {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/musician_tasks.js:
--------------------------------------------------------------------------------
1 | // 获取音乐人任务
2 |
3 | module.exports = (query, request) => {
4 | const data = {}
5 | return request(
6 | 'POST',
7 | `https://music.163.com/weapi/nmusician/workbench/mission/cycle/list`,
8 | data,
9 | {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/musician_tasks_new.js:
--------------------------------------------------------------------------------
1 | // 获取音乐人任务
2 |
3 | module.exports = (query, request) => {
4 | const data = {}
5 | return request(
6 | 'POST',
7 | `https://music.163.com/api/nmusician/workbench/mission/stage/list `,
8 | data,
9 | {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/mv_all.js:
--------------------------------------------------------------------------------
1 | // 全部MV
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | tags: JSON.stringify({
6 | 地区: query.area || '全部',
7 | 类型: query.type || '全部',
8 | 排序: query.order || '上升最快',
9 | }),
10 | offset: query.offset || 0,
11 | total: 'true',
12 | limit: query.limit || 30,
13 | }
14 | return request('POST', `https://interface.music.163.com/api/mv/all`, data, {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | })
20 | }
21 |
--------------------------------------------------------------------------------
/module/mv_detail.js:
--------------------------------------------------------------------------------
1 | // MV详情
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.mvid,
6 | }
7 | return request('POST', `https://music.163.com/api/v1/mv/detail`, data, {
8 | crypto: 'weapi',
9 | cookie: query.cookie,
10 | proxy: query.proxy,
11 | realIP: query.realIP,
12 | })
13 | }
14 |
--------------------------------------------------------------------------------
/module/mv_detail_info.js:
--------------------------------------------------------------------------------
1 | // MV 点赞转发评论数数据
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | threadid: `R_MV_5_${query.mvid}`,
6 | composeliked: true,
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/api/comment/commentthread/info`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/mv_exclusive_rcmd.js:
--------------------------------------------------------------------------------
1 | // 网易出品
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | offset: query.offset || 0,
6 | limit: query.limit || 30,
7 | }
8 | return request(
9 | 'POST',
10 | `https://interface.music.163.com/api/mv/exclusive/rcmd`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/mv_first.js:
--------------------------------------------------------------------------------
1 | // 最新MV
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | // 'offset': query.offset || 0,
6 | area: query.area || '',
7 | limit: query.limit || 30,
8 | total: true,
9 | }
10 | return request(
11 | 'POST',
12 | `https://interface.music.163.com/weapi/mv/first`,
13 | data,
14 | {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | },
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/module/mv_sub.js:
--------------------------------------------------------------------------------
1 | // 收藏与取消收藏MV
2 |
3 | module.exports = (query, request) => {
4 | query.t = query.t == 1 ? 'sub' : 'unsub'
5 | const data = {
6 | mvId: query.mvid,
7 | mvIds: '["' + query.mvid + '"]',
8 | }
9 | return request('POST', `https://music.163.com/weapi/mv/${query.t}`, data, {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | })
15 | }
16 |
--------------------------------------------------------------------------------
/module/mv_sublist.js:
--------------------------------------------------------------------------------
1 | // 已收藏MV列表
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 25,
6 | offset: query.offset || 0,
7 | total: true,
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/weapi/cloudvideo/allvideo/sublist`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/mv_url.js:
--------------------------------------------------------------------------------
1 | // MV链接
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | r: query.r || 1080,
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/weapi/song/enhance/play/mv/url`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/nickname_check.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {
3 | nickname: query.nickname,
4 | }
5 | return request(
6 | 'POST',
7 | `https://music.163.com/api/nickname/duplicated`,
8 | data,
9 | {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/personal_fm.js:
--------------------------------------------------------------------------------
1 | // 私人FM
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/v1/radio/get`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/personalized.js:
--------------------------------------------------------------------------------
1 | // 推荐歌单
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 30,
6 | // offset: query.offset || 0,
7 | total: true,
8 | n: 1000,
9 | }
10 | return request(
11 | 'POST',
12 | `https://music.163.com/weapi/personalized/playlist`,
13 | data,
14 | {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | },
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/module/personalized_djprogram.js:
--------------------------------------------------------------------------------
1 | // 推荐电台
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/personalized/djprogram`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/personalized_mv.js:
--------------------------------------------------------------------------------
1 | // 推荐MV
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/personalized/mv`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/personalized_newsong.js:
--------------------------------------------------------------------------------
1 | // 推荐新歌
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'pc'
5 | const data = {
6 | type: 'recommend',
7 | limit: query.limit || 10,
8 | areaId: query.areaId || 0,
9 | }
10 | return request(
11 | 'POST',
12 | `https://music.163.com/api/personalized/newsong`,
13 | data,
14 | {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | },
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/module/personalized_privatecontent.js:
--------------------------------------------------------------------------------
1 | // 独家放送
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/personalized/privatecontent`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/personalized_privatecontent_list.js:
--------------------------------------------------------------------------------
1 | // 独家放送列表
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | offset: query.offset || 0,
6 | total: 'true',
7 | limit: query.limit || 60,
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/api/v2/privatecontent/list`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/playlist_catlist.js:
--------------------------------------------------------------------------------
1 | // 全部歌单分类
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/playlist/catalogue`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/playlist_cover_update.js:
--------------------------------------------------------------------------------
1 | const uploadPlugin = require('../plugins/upload')
2 | module.exports = async (query, request) => {
3 | if (!query.imgFile) {
4 | return {
5 | status: 400,
6 | body: {
7 | code: 400,
8 | msg: 'imgFile is required',
9 | },
10 | }
11 | }
12 | const uploadInfo = await uploadPlugin(query, request)
13 | const res = await request(
14 | 'POST',
15 | `https://music.163.com/weapi/playlist/cover/update`,
16 | {
17 | id: query.id,
18 | coverImgId: uploadInfo.imgId,
19 | },
20 | {
21 | crypto: 'weapi',
22 | cookie: query.cookie,
23 | proxy: query.proxy,
24 | realIP: query.realIP,
25 | },
26 | )
27 | return {
28 | status: 200,
29 | body: {
30 | code: 200,
31 | data: {
32 | ...uploadInfo,
33 | ...res.body,
34 | },
35 | },
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/module/playlist_create.js:
--------------------------------------------------------------------------------
1 | // 创建歌单
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'pc'
5 | const data = {
6 | name: query.name,
7 | privacy: query.privacy, //0 为普通歌单,10 为隐私歌单
8 | type: query.type || 'NORMAL', // NORMAL|VIDEO|SHARED
9 | }
10 | return request('POST', `https://music.163.com/api/playlist/create`, data, {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | })
16 | }
17 |
--------------------------------------------------------------------------------
/module/playlist_delete.js:
--------------------------------------------------------------------------------
1 | // 删除歌单
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'pc'
5 | const data = {
6 | ids: '[' + query.id + ']',
7 | }
8 | return request('POST', `https://music.163.com/weapi/playlist/remove`, data, {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/module/playlist_desc_update.js:
--------------------------------------------------------------------------------
1 | // 更新歌单描述
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | desc: query.desc,
7 | }
8 | return request(
9 | 'POST',
10 | `https://interface3.music.163.com/eapi/playlist/desc/update`,
11 | data,
12 | {
13 | crypto: 'eapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | url: '/api/playlist/desc/update',
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/playlist_detail.js:
--------------------------------------------------------------------------------
1 | // 歌单详情
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | n: 100000,
7 | s: query.s || 8,
8 | }
9 | return request('POST', `https://music.163.com/api/v6/playlist/detail`, data, {
10 | crypto: 'api',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | })
15 | }
16 |
--------------------------------------------------------------------------------
/module/playlist_detail_dynamic.js:
--------------------------------------------------------------------------------
1 | // 初始化名字
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | n: 100000,
7 | s: query.s || 8,
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/api/playlist/detail/dynamic`,
12 | data,
13 | {
14 | crypto: 'api',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/playlist_highquality_tags.js:
--------------------------------------------------------------------------------
1 | // 精品歌单 tags
2 | module.exports = (query, request) => {
3 | const data = {}
4 | return request(
5 | 'POST',
6 | `https://music.163.com/api/playlist/highquality/tags`,
7 | data,
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/playlist_hot.js:
--------------------------------------------------------------------------------
1 | // 热门歌单分类
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/playlist/hottags`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/playlist_mylike.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {
3 | time: query.time || '-1',
4 | limit: query.limit || '12',
5 | }
6 | return request(
7 | 'POST',
8 | `https://music.163.com/api/mlog/playlist/mylike/bytime/get`,
9 | data,
10 | {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | },
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/module/playlist_name_update.js:
--------------------------------------------------------------------------------
1 | // 更新歌单名
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | name: query.name,
7 | }
8 | return request(
9 | 'POST',
10 | `https://interface3.music.163.com/eapi/playlist/update/name`,
11 | data,
12 | {
13 | crypto: 'eapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | url: '/api/playlist/update/name',
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/playlist_order_update.js:
--------------------------------------------------------------------------------
1 | // 编辑歌单顺序
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'pc'
5 | const data = {
6 | ids: query.ids,
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/api/playlist/order/update`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/playlist_privacy.js:
--------------------------------------------------------------------------------
1 | // 公开隐私歌单
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | privacy: 0,
7 | }
8 | return request(
9 | 'POST',
10 | `https://interface.music.163.com/eapi/playlist/update/privacy`,
11 | data,
12 | {
13 | crypto: 'eapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | url: '/api/playlist/update/privacy',
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/playlist_subscribe.js:
--------------------------------------------------------------------------------
1 | // 收藏与取消收藏歌单
2 |
3 | module.exports = (query, request) => {
4 | query.t = query.t == 1 ? 'subscribe' : 'unsubscribe'
5 | const data = {
6 | id: query.id,
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/weapi/playlist/${query.t}`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/playlist_subscribers.js:
--------------------------------------------------------------------------------
1 | // 歌单收藏者
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | limit: query.limit || 20,
7 | offset: query.offset || 0,
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/weapi/playlist/subscribers`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/playlist_tags_update.js:
--------------------------------------------------------------------------------
1 | // 更新歌单标签
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | tags: query.tags,
7 | }
8 | return request(
9 | 'POST',
10 | `https://interface3.music.163.com/eapi/playlist/tags/update`,
11 | data,
12 | {
13 | crypto: 'eapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | url: '/api/playlist/tags/update',
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/playlist_track_add.js:
--------------------------------------------------------------------------------
1 | module.exports = async (query, request) => {
2 | query.cookie.os = 'pc'
3 | query.ids = query.ids || ''
4 | const data = {
5 | id: query.pid,
6 | tracks: JSON.stringify(
7 | query.ids.split(',').map((item) => {
8 | return { type: 3, id: item }
9 | }),
10 | ),
11 | }
12 | console.log(data)
13 |
14 | return request('POST', `https://music.163.com/api/playlist/track/add`, data, {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | })
20 | }
21 |
--------------------------------------------------------------------------------
/module/playlist_track_all.js:
--------------------------------------------------------------------------------
1 | // 通过传过来的歌单id拿到所有歌曲数据
2 | // 支持传递参数limit来限制获取歌曲的数据数量 例如: /playlist/track/all?id=7044354223&limit=10
3 |
4 | module.exports = (query, request) => {
5 | const data = {
6 | id: query.id,
7 | n: 100000,
8 | s: query.s || 8,
9 | }
10 | //不放在data里面避免请求带上无用的数据
11 | let limit = parseInt(query.limit) || Infinity
12 | let offset = parseInt(query.offset) || 0
13 |
14 | return request('POST', `https://music.163.com/api/v6/playlist/detail`, data, {
15 | crypto: 'api',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | }).then((res) => {
20 | let trackIds = res.body.playlist.trackIds
21 | let idsData = {
22 | c:
23 | '[' +
24 | trackIds
25 | .slice(offset, offset + limit)
26 | .map((item) => '{"id":' + item.id + '}')
27 | .join(',') +
28 | ']',
29 | }
30 |
31 | return request(
32 | 'POST',
33 | `https://music.163.com/api/v3/song/detail`,
34 | idsData,
35 | {
36 | crypto: 'weapi',
37 | cookie: query.cookie,
38 | proxy: query.proxy,
39 | realIP: query.realIP,
40 | },
41 | )
42 | })
43 | }
44 |
--------------------------------------------------------------------------------
/module/playlist_track_delete.js:
--------------------------------------------------------------------------------
1 | // 收藏单曲到歌单 从歌单删除歌曲
2 |
3 | module.exports = async (query, request) => {
4 | query.cookie.os = 'pc'
5 | query.ids = query.ids || ''
6 | const data = {
7 | id: query.id,
8 | tracks: JSON.stringify(
9 | query.ids.split(',').map((item) => {
10 | return { type: 3, id: item }
11 | }),
12 | ),
13 | }
14 |
15 | return request(
16 | 'POST',
17 | `https://music.163.com/api/playlist/track/delete`,
18 | data,
19 | {
20 | crypto: 'weapi',
21 | cookie: query.cookie,
22 | proxy: query.proxy,
23 | realIP: query.realIP,
24 | },
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/module/playlist_tracks.js:
--------------------------------------------------------------------------------
1 | // 收藏单曲到歌单 从歌单删除歌曲
2 |
3 | module.exports = async (query, request) => {
4 | query.cookie.os = 'pc'
5 | const tracks = query.tracks.split(',')
6 | const data = {
7 | op: query.op, // del,add
8 | pid: query.pid, // 歌单id
9 | trackIds: JSON.stringify(tracks), // 歌曲id
10 | imme: 'true',
11 | }
12 |
13 | try {
14 | const res = await request(
15 | 'POST',
16 | `https://music.163.com/api/playlist/manipulate/tracks`,
17 | data,
18 | {
19 | crypto: 'weapi',
20 | cookie: query.cookie,
21 | proxy: query.proxy,
22 | realIP: query.realIP,
23 | },
24 | )
25 | return {
26 | status: 200,
27 | body: {
28 | ...res,
29 | },
30 | }
31 | } catch (error) {
32 | if (error.body.code === 512) {
33 | return request(
34 | 'POST',
35 | `https://music.163.com/api/playlist/manipulate/tracks`,
36 | {
37 | op: query.op, // del,add
38 | pid: query.pid, // 歌单id
39 | trackIds: JSON.stringify([...tracks, ...tracks]),
40 | imme: 'true',
41 | },
42 | {
43 | crypto: 'weapi',
44 | cookie: query.cookie,
45 | proxy: query.proxy,
46 | realIP: query.realIP,
47 | },
48 | )
49 | } else if (error.body.code === 521) {
50 | return {
51 | status: 200,
52 | body: error.body,
53 | }
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/module/playlist_update.js:
--------------------------------------------------------------------------------
1 | // 编辑歌单
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'pc'
5 | query.desc = query.desc || ''
6 | query.tags = query.tags || ''
7 | const data = {
8 | '/api/playlist/desc/update': `{"id":${query.id},"desc":"${query.desc}"}`,
9 | '/api/playlist/tags/update': `{"id":${query.id},"tags":"${query.tags}"}`,
10 | '/api/playlist/update/name': `{"id":${query.id},"name":"${query.name}"}`,
11 | }
12 | return request('POST', `https://music.163.com/weapi/batch`, data, {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/module/playlist_update_playcount.js:
--------------------------------------------------------------------------------
1 | // 歌单打卡
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | }
7 | return request(
8 | 'POST',
9 | `https://music.163.com/api/playlist/update/playcount`,
10 | data,
11 | {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | },
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/module/playlist_video_recent.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {}
3 | return request(
4 | 'POST',
5 | `https://music.163.com/api/playlist/video/recent`,
6 | data,
7 | {
8 | crypto: 'weapi',
9 | cookie: query.cookie,
10 | proxy: query.proxy,
11 | realIP: query.realIP,
12 | },
13 | )
14 | }
15 |
--------------------------------------------------------------------------------
/module/playmode_intelligence_list.js:
--------------------------------------------------------------------------------
1 | // 智能播放
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | songId: query.id,
6 | type: 'fromPlayOne',
7 | playlistId: query.pid,
8 | startMusicId: query.sid || query.id,
9 | count: query.count || 1,
10 | }
11 | return request(
12 | 'POST',
13 | `https://music.163.com/weapi/playmode/intelligence/list`,
14 | data,
15 | {
16 | crypto: 'weapi',
17 | cookie: query.cookie,
18 | proxy: query.proxy,
19 | realIP: query.realIP,
20 | },
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/module/program_recommend.js:
--------------------------------------------------------------------------------
1 | // 推荐节目
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | cateId: query.type,
6 | limit: query.limit || 10,
7 | offset: query.offset || 0,
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/weapi/program/recommend/v1`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/rebind.js:
--------------------------------------------------------------------------------
1 | // 更换手机
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | captcha: query.captcha,
6 | phone: query.phone,
7 | oldcaptcha: query.oldcaptcha,
8 | ctcode: query.ctcode || '86',
9 | }
10 | return request(
11 | 'POST',
12 | `https://music.163.com/api/user/replaceCellphone`,
13 | data,
14 | {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | },
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/module/recommend_resource.js:
--------------------------------------------------------------------------------
1 | // 每日推荐歌单
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/v1/discovery/recommend/resource`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/recommend_songs.js:
--------------------------------------------------------------------------------
1 | // 每日推荐歌曲
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'ios'
5 | const data = {}
6 | return request(
7 | 'POST',
8 | `https://music.163.com/api/v3/discovery/recommend/songs`,
9 | data,
10 | {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | },
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/module/record_recent_album.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {
3 | limit: query.limit || 100,
4 | }
5 | return request(
6 | 'POST',
7 | `https://music.163.com/api/play-record/album/list`,
8 | data,
9 | {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/record_recent_dj.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {
3 | limit: query.limit || 100,
4 | }
5 | return request(
6 | 'POST',
7 | `https://music.163.com/api/play-record/djradio/list`,
8 | data,
9 | {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/record_recent_playlist.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {
3 | limit: query.limit || 100,
4 | }
5 | return request(
6 | 'POST',
7 | `https://music.163.com/api/play-record/playlist/list`,
8 | data,
9 | {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/record_recent_song.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {
3 | limit: query.limit || 100,
4 | }
5 | return request(
6 | 'POST',
7 | `https://music.163.com/api/play-record/song/list`,
8 | data,
9 | {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/record_recent_video.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {
3 | limit: query.limit || 100,
4 | }
5 | return request(
6 | 'POST',
7 | `https://music.163.com/api/play-record/newvideo/list`,
8 | data,
9 | {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/record_recent_voice.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {
3 | limit: query.limit || 100,
4 | }
5 | return request(
6 | 'POST',
7 | `https://music.163.com/api/play-record/voice/list`,
8 | data,
9 | {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/register_cellphone.js:
--------------------------------------------------------------------------------
1 | // 注册账号
2 | const crypto = require('crypto')
3 |
4 | module.exports = (query, request) => {
5 | query.cookie.os = 'pc'
6 | const data = {
7 | captcha: query.captcha,
8 | phone: query.phone,
9 | password: crypto.createHash('md5').update(query.password).digest('hex'),
10 | nickname: query.nickname,
11 | countrycode: query.countrycode || '86',
12 | }
13 | return request('POST', `https://music.163.com/api/register/cellphone`, data, {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/module/related_allvideo.js:
--------------------------------------------------------------------------------
1 | // 相关视频
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | type: /^\d+$/.test(query.id) ? 0 : 1,
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/weapi/cloudvideo/v1/allvideo/rcmd`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/related_playlist.js:
--------------------------------------------------------------------------------
1 | // 相关歌单
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'GET',
6 | `https://music.163.com/playlist?id=${query.id}`,
7 | {},
8 | {
9 | ua: 'pc',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | ).then((response) => {
15 | try {
16 | const pattern =
17 | /[\s\S]*?

[\s\S]*?
]*>([^<]+?)<\/a>[\s\S]*?]*>([^<]+?)<\/a>/g
18 | let result,
19 | playlists = []
20 | while ((result = pattern.exec(response.body)) != null) {
21 | playlists.push({
22 | creator: {
23 | userId: result[4].slice('/user/home?id='.length),
24 | nickname: result[5],
25 | },
26 | coverImgUrl: result[1].slice(0, -'?param=50y50'.length),
27 | name: result[3],
28 | id: result[2].slice('/playlist?id='.length),
29 | })
30 | }
31 | response.body = { code: 200, playlists: playlists }
32 | return response
33 | } catch (err) {
34 | response.status = 500
35 | response.body = { code: 500, msg: err.stack }
36 | return Promise.reject(response)
37 | }
38 | })
39 | }
40 |
--------------------------------------------------------------------------------
/module/resource_like.js:
--------------------------------------------------------------------------------
1 | // 点赞与取消点赞资源
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'android'
5 | query.t = query.t == 1 ? 'like' : 'unlike'
6 | query.type = {
7 | 1: 'R_MV_5_', // MV
8 | 4: 'A_DJ_1_', // 电台
9 | 5: 'R_VI_62_', // 视频
10 | 6: 'A_EV_2_',
11 | }[query.type]
12 | const data = {
13 | threadId: query.type + query.id,
14 | }
15 | if (query.type === 'A_EV_2_') {
16 | data.threadId = query.threadId
17 | }
18 | return request(
19 | 'POST',
20 | `https://music.163.com/weapi/resource/${query.t}`,
21 | data,
22 | {
23 | crypto: 'weapi',
24 | cookie: query.cookie,
25 | proxy: query.proxy,
26 | realIP: query.realIP,
27 | },
28 | )
29 | }
30 |
--------------------------------------------------------------------------------
/module/scrobble.js:
--------------------------------------------------------------------------------
1 | // 听歌打卡
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | logs: JSON.stringify([
6 | {
7 | action: 'play',
8 | json: {
9 | download: 0,
10 | end: 'playend',
11 | id: query.id,
12 | sourceId: query.sourceid,
13 | time: query.time,
14 | type: 'song',
15 | wifi: 0,
16 | source: 'list',
17 | },
18 | },
19 | ]),
20 | }
21 |
22 | return request('POST', `https://music.163.com/weapi/feedback/weblog`, data, {
23 | crypto: 'weapi',
24 | cookie: query.cookie,
25 | proxy: query.proxy,
26 | realIP: query.realIP,
27 | })
28 | }
29 |
--------------------------------------------------------------------------------
/module/search.js:
--------------------------------------------------------------------------------
1 | // 搜索
2 |
3 | module.exports = (query, request) => {
4 | if (query.type && query.type == '2000') {
5 | const data = {
6 | keyword: query.keywords,
7 | scene: 'normal',
8 | limit: query.limit || 30,
9 | offset: query.offset || 0,
10 | }
11 | return request('POST', `https://music.163.com/api/search/voice/get`, data, {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | })
17 | }
18 | const data = {
19 | s: query.keywords,
20 | type: query.type || 1, // 1: 单曲, 10: 专辑, 100: 歌手, 1000: 歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频
21 | limit: query.limit || 30,
22 | offset: query.offset || 0,
23 | }
24 | return request('POST', `https://music.163.com/weapi/search/get`, data, {
25 | crypto: 'weapi',
26 | cookie: query.cookie,
27 | proxy: query.proxy,
28 | realIP: query.realIP,
29 | })
30 | }
31 |
--------------------------------------------------------------------------------
/module/search_default.js:
--------------------------------------------------------------------------------
1 | // 默认搜索关键词
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://interface3.music.163.com/eapi/search/defaultkeyword/get`,
7 | {},
8 | {
9 | crypto: 'eapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | url: '/api/search/defaultkeyword/get',
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/search_hot.js:
--------------------------------------------------------------------------------
1 | // 热门搜索
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | type: 1111,
6 | }
7 | return request('POST', `https://music.163.com/weapi/search/hot`, data, {
8 | crypto: 'weapi',
9 | ua: 'mobile',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/module/search_hot_detail.js:
--------------------------------------------------------------------------------
1 | // 热搜列表
2 | module.exports = (query, request) => {
3 | const data = {}
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/hotsearchlist/get`,
7 | data,
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/search_multimatch.js:
--------------------------------------------------------------------------------
1 | // 多类型搜索
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | type: query.type || 1,
6 | s: query.keywords || '',
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/weapi/search/suggest/multimatch`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/search_suggest.js:
--------------------------------------------------------------------------------
1 | // 搜索建议
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | s: query.keywords || '',
6 | }
7 | let type = query.type == 'mobile' ? 'keyword' : 'web'
8 | return request(
9 | 'POST',
10 | `https://music.163.com/weapi/search/suggest/` + type,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/send_album.js:
--------------------------------------------------------------------------------
1 | // 私信专辑
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'ios'
5 | query.cookie.appver = '8.7.01'
6 | const data = {
7 | id: query.id,
8 | msg: query.msg || '',
9 | type: 'album',
10 | userIds: '[' + query.user_ids + ']',
11 | }
12 | return request('POST', `https://music.163.com/api/msg/private/send`, data, {
13 | crypto: 'api',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/module/send_playlist.js:
--------------------------------------------------------------------------------
1 | // 私信歌单
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'pc'
5 | const data = {
6 | id: query.playlist,
7 | type: 'playlist',
8 | msg: query.msg,
9 | userIds: '[' + query.user_ids + ']',
10 | }
11 | return request('POST', `https://music.163.com/weapi/msg/private/send`, data, {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | })
17 | }
18 |
--------------------------------------------------------------------------------
/module/send_song.js:
--------------------------------------------------------------------------------
1 | // 私信歌曲
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'ios'
5 | query.cookie.appver = '8.7.01'
6 | const data = {
7 | id: query.id,
8 | msg: query.msg || '',
9 | type: 'song',
10 | userIds: '[' + query.user_ids + ']',
11 | }
12 | return request('POST', `https://music.163.com/api/msg/private/send`, data, {
13 | crypto: 'api',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/module/send_text.js:
--------------------------------------------------------------------------------
1 | // 私信
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'pc'
5 | const data = {
6 | type: 'text',
7 | msg: query.msg,
8 | userIds: '[' + query.user_ids + ']',
9 | }
10 | return request('POST', `https://music.163.com/weapi/msg/private/send`, data, {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | })
16 | }
17 |
--------------------------------------------------------------------------------
/module/setting.js:
--------------------------------------------------------------------------------
1 | // 设置
2 |
3 | module.exports = (query, request) => {
4 | const data = {}
5 | return request('POST', `https://music.163.com/api/user/setting`, data, {
6 | crypto: 'weapi',
7 | cookie: query.cookie,
8 | proxy: query.proxy,
9 | realIP: query.realIP,
10 | })
11 | }
12 |
--------------------------------------------------------------------------------
/module/share_resource.js:
--------------------------------------------------------------------------------
1 | // 分享歌曲到动态
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | type: query.type || 'song', // song,playlist,mv,djprogram,djradio,noresource
6 | msg: query.msg || '',
7 | id: query.id || '',
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/weapi/share/friends/resource`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/sign_happy_info.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {}
3 | return request('POST', `https://music.163.com/api/sign/happy/info`, data, {
4 | crypto: 'weapi',
5 | cookie: query.cookie,
6 | proxy: query.proxy,
7 | realIP: query.realIP,
8 | })
9 | }
10 |
--------------------------------------------------------------------------------
/module/signin_progress.js:
--------------------------------------------------------------------------------
1 | // 签到进度
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | moduleId: query.moduleId || '1207signin-1207signin',
6 | }
7 | return request(
8 | 'POST',
9 | `https://music.163.com/weapi/act/modules/signin/v2/progress`,
10 | data,
11 | {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | },
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/module/simi_artist.js:
--------------------------------------------------------------------------------
1 | // 相似歌手
2 | const config = require('../util/config.json')
3 | module.exports = (query, request) => {
4 | if (!('MUSIC_U' in query.cookie))
5 | query.cookie.MUSIC_A = config.anonymous_token
6 | const data = {
7 | artistid: query.id,
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/weapi/discovery/simiArtist`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/simi_mv.js:
--------------------------------------------------------------------------------
1 | // 相似MV
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | mvid: query.mvid,
6 | }
7 | return request('POST', `https://music.163.com/weapi/discovery/simiMV`, data, {
8 | crypto: 'weapi',
9 | cookie: query.cookie,
10 | proxy: query.proxy,
11 | realIP: query.realIP,
12 | })
13 | }
14 |
--------------------------------------------------------------------------------
/module/simi_playlist.js:
--------------------------------------------------------------------------------
1 | // 相似歌单
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | songid: query.id,
6 | limit: query.limit || 50,
7 | offset: query.offset || 0,
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/weapi/discovery/simiPlaylist`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/simi_song.js:
--------------------------------------------------------------------------------
1 | // 相似歌曲
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | songid: query.id,
6 | limit: query.limit || 50,
7 | offset: query.offset || 0,
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/weapi/v1/discovery/simiSong`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/simi_user.js:
--------------------------------------------------------------------------------
1 | // 相似用户
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | songid: query.id,
6 | limit: query.limit || 50,
7 | offset: query.offset || 0,
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/weapi/discovery/simiUser`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/song_detail.js:
--------------------------------------------------------------------------------
1 | // 歌曲详情
2 |
3 | module.exports = (query, request) => {
4 | query.ids = query.ids.split(/\s*,\s*/)
5 | const data = {
6 | c: '[' + query.ids.map((id) => '{"id":' + id + '}').join(',') + ']',
7 | }
8 | return request('POST', `https://music.163.com/api/v3/song/detail`, data, {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/module/song_download_url.js:
--------------------------------------------------------------------------------
1 | // 获取客户端歌曲下载链接
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | br: parseInt(query.br || 999000),
7 | }
8 | return request(
9 | 'POST',
10 | `https://interface.music.163.com/eapi/song/enhance/download/url`,
11 | data,
12 | {
13 | crypto: 'eapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | url: '/api/song/enhance/download/url',
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/song_order_update.js:
--------------------------------------------------------------------------------
1 | // 更新歌曲顺序
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | pid: query.pid,
6 | trackIds: query.ids,
7 | op: 'update',
8 | }
9 |
10 | return request(
11 | 'POST',
12 | `http://interface.music.163.com/api/playlist/manipulate/tracks`,
13 | data,
14 | {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | url: '/api/playlist/desc/update',
19 | realIP: query.realIP,
20 | },
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/module/song_purchased.js:
--------------------------------------------------------------------------------
1 | // 已购单曲
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 20,
6 | offset: query.offset || 0,
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/weapi/single/mybought/song/list`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/song_url.js:
--------------------------------------------------------------------------------
1 | // 歌曲链接
2 |
3 | const crypto = require('crypto')
4 | module.exports = (query, request) => {
5 | if (!('MUSIC_U' in query.cookie))
6 | query.cookie._ntes_nuid = crypto.randomBytes(16).toString('hex')
7 | query.cookie.os = 'pc'
8 | const data = {
9 | ids: '[' + query.id + ']',
10 | br: parseInt(query.br || 999000),
11 | }
12 | return request(
13 | 'POST',
14 | `https://interface3.music.163.com/eapi/song/enhance/player/url`,
15 | data,
16 | {
17 | crypto: 'eapi',
18 | cookie: query.cookie,
19 | proxy: query.proxy,
20 | realIP: query.realIP,
21 | url: '/api/song/enhance/player/url',
22 | },
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/module/top_album.js:
--------------------------------------------------------------------------------
1 | // 新碟上架
2 |
3 | module.exports = (query, request) => {
4 | const date = new Date()
5 |
6 | const data = {
7 | area: query.area || 'ALL', // //ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本
8 | limit: query.limit || 50,
9 | offset: query.offset || 0,
10 | type: query.type || 'new',
11 | year: query.year || date.getFullYear(),
12 | month: query.month || date.getMonth() + 1,
13 | total: false,
14 | rcmd: true,
15 | }
16 | return request(
17 | 'POST',
18 | `https://music.163.com/api/discovery/new/albums/area`,
19 | data,
20 | {
21 | crypto: 'weapi',
22 | cookie: query.cookie,
23 | proxy: query.proxy,
24 | realIP: query.realIP,
25 | },
26 | )
27 | }
28 |
--------------------------------------------------------------------------------
/module/top_artists.js:
--------------------------------------------------------------------------------
1 | // 热门歌手
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 50,
6 | offset: query.offset || 0,
7 | total: true,
8 | }
9 | return request('POST', `https://music.163.com/weapi/artist/top`, data, {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | })
15 | }
16 |
--------------------------------------------------------------------------------
/module/top_list.js:
--------------------------------------------------------------------------------
1 | // 排行榜
2 | module.exports = (query, request) => {
3 | query.cookie.os = 'pc'
4 | if (query.idx) {
5 | return Promise.resolve({
6 | status: 500,
7 | body: {
8 | code: 500,
9 | msg: '不支持此方式调用,只支持id调用',
10 | },
11 | })
12 | }
13 |
14 | const data = {
15 | id: query.id,
16 | n: '500',
17 | s: '0',
18 | }
19 | return request(
20 | 'POST',
21 | `https://interface3.music.163.com/api/playlist/v4/detail`,
22 | data,
23 | {
24 | crypto: 'weapi',
25 | cookie: query.cookie,
26 | proxy: query.proxy,
27 | realIP: query.realIP,
28 | },
29 | )
30 | }
31 |
--------------------------------------------------------------------------------
/module/top_mv.js:
--------------------------------------------------------------------------------
1 | // MV排行榜
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | area: query.area || '',
6 | limit: query.limit || 30,
7 | offset: query.offset || 0,
8 | total: true,
9 | }
10 | return request('POST', `https://music.163.com/weapi/mv/toplist`, data, {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | })
16 | }
17 |
--------------------------------------------------------------------------------
/module/top_playlist.js:
--------------------------------------------------------------------------------
1 | // 分类歌单
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | cat: query.cat || '全部', // 全部,华语,欧美,日语,韩语,粤语,小语种,流行,摇滚,民谣,电子,舞曲,说唱,轻音乐,爵士,乡村,R&B/Soul,古典,民族,英伦,金属,朋克,蓝调,雷鬼,世界音乐,拉丁,另类/独立,New Age,古风,后摇,Bossa Nova,清晨,夜晚,学习,工作,午休,下午茶,地铁,驾车,运动,旅行,散步,酒吧,怀旧,清新,浪漫,性感,伤感,治愈,放松,孤独,感动,兴奋,快乐,安静,思念,影视原声,ACG,儿童,校园,游戏,70后,80后,90后,网络歌曲,KTV,经典,翻唱,吉他,钢琴,器乐,榜单,00后
6 | order: query.order || 'hot', // hot,new
7 | limit: query.limit || 50,
8 | offset: query.offset || 0,
9 | total: true,
10 | }
11 | return request('POST', `https://music.163.com/weapi/playlist/list`, data, {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | })
17 | }
18 |
--------------------------------------------------------------------------------
/module/top_playlist_highquality.js:
--------------------------------------------------------------------------------
1 | // 精品歌单
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | cat: query.cat || '全部', // 全部,华语,欧美,韩语,日语,粤语,小语种,运动,ACG,影视原声,流行,摇滚,后摇,古风,民谣,轻音乐,电子,器乐,说唱,古典,爵士
6 | limit: query.limit || 50,
7 | lasttime: query.before || 0, // 歌单updateTime
8 | total: true,
9 | }
10 | return request(
11 | 'POST',
12 | `https://music.163.com/api/playlist/highquality/list`,
13 | data,
14 | {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | },
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/module/top_song.js:
--------------------------------------------------------------------------------
1 | // 新歌速递
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | areaId: query.type || 0, // 全部:0 华语:7 欧美:96 日本:8 韩国:16
6 | // limit: query.limit || 100,
7 | // offset: query.offset || 0,
8 | total: true,
9 | }
10 | return request(
11 | 'POST',
12 | `https://music.163.com/weapi/v1/discovery/new/songs`,
13 | data,
14 | {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | },
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/module/topic_detail.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {
3 | actid: query.actid,
4 | }
5 | return request('POST', `https://music.163.com/api/act/detail`, data, {
6 | crypto: 'weapi',
7 | cookie: query.cookie,
8 | proxy: query.proxy,
9 | realIP: query.realIP,
10 | })
11 | }
12 |
--------------------------------------------------------------------------------
/module/topic_detail_event_hot.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {
3 | actid: query.actid,
4 | }
5 | return request('POST', `https://music.163.com/api/act/event/hot`, data, {
6 | crypto: 'weapi',
7 | cookie: query.cookie,
8 | proxy: query.proxy,
9 | realIP: query.realIP,
10 | })
11 | }
12 |
--------------------------------------------------------------------------------
/module/topic_sublist.js:
--------------------------------------------------------------------------------
1 | // 收藏的专栏
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 50,
6 | offset: query.offset || 0,
7 | total: true,
8 | }
9 | return request('POST', `https://music.163.com/api/topic/sublist`, data, {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | })
15 | }
16 |
--------------------------------------------------------------------------------
/module/toplist.js:
--------------------------------------------------------------------------------
1 | // 所有榜单介绍
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/api/toplist`,
7 | {},
8 | {
9 | crypto: 'api',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/toplist_artist.js:
--------------------------------------------------------------------------------
1 | // 歌手榜
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | type: query.type || 1,
6 | limit: 100,
7 | offset: 0,
8 | total: true,
9 | }
10 | return request('POST', `https://music.163.com/weapi/toplist/artist`, data, {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | })
16 | }
17 |
--------------------------------------------------------------------------------
/module/toplist_detail.js:
--------------------------------------------------------------------------------
1 | // 所有榜单内容摘要
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/toplist/detail`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/user_account.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {}
3 | return request('POST', `https://music.163.com/api/nuser/account/get`, data, {
4 | crypto: 'weapi',
5 | cookie: query.cookie,
6 | proxy: query.proxy,
7 | realIP: query.realIP,
8 | })
9 | }
10 |
--------------------------------------------------------------------------------
/module/user_audio.js:
--------------------------------------------------------------------------------
1 | // 用户创建的电台
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | userId: query.uid,
6 | }
7 | return request(
8 | 'POST',
9 | `https://music.163.com/weapi/djradio/get/byuser`,
10 | data,
11 | {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | },
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/module/user_binding.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {}
3 | return request(
4 | 'POST',
5 | `https://music.163.com/api/v1/user/bindings/${query.uid}`,
6 | data,
7 | {
8 | crypto: 'weapi',
9 | cookie: query.cookie,
10 | proxy: query.proxy,
11 | realIP: query.realIP,
12 | },
13 | )
14 | }
15 |
--------------------------------------------------------------------------------
/module/user_bindingcellphone.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {
3 | phone: query.phone,
4 | countrycode: query.countrycode || '86',
5 | captcha: query.captcha,
6 | password: query.password
7 | ? crypto.createHash('md5').update(query.password).digest('hex')
8 | : '',
9 | }
10 | return request(
11 | 'POST',
12 | `https://music.163.com/api/user/bindingCellphone`,
13 | data,
14 | {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | },
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/module/user_cloud.js:
--------------------------------------------------------------------------------
1 | // 云盘数据
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 30,
6 | offset: query.offset || 0,
7 | }
8 | return request('POST', `https://music.163.com/api/v1/cloud/get`, data, {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/module/user_cloud_del.js:
--------------------------------------------------------------------------------
1 | // 云盘歌曲删除
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | songIds: [query.id],
6 | }
7 | return request('POST', `https://music.163.com/weapi/cloud/del`, data, {
8 | crypto: 'weapi',
9 | cookie: query.cookie,
10 | proxy: query.proxy,
11 | realIP: query.realIP,
12 | })
13 | }
14 |
--------------------------------------------------------------------------------
/module/user_cloud_detail.js:
--------------------------------------------------------------------------------
1 | // 云盘数据详情
2 |
3 | module.exports = (query, request) => {
4 | const id = query.id.replace(/\s/g, '').split(',')
5 | const data = {
6 | songIds: id,
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/weapi/v1/cloud/get/byids`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/user_comment_history.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | query.cookie.os = 'ios'
3 | query.cookie.appver = '8.7.01'
4 | const data = {
5 | compose_reminder: 'true',
6 | compose_hot_comment: 'true',
7 | limit: query.limit || 10,
8 | user_id: query.uid,
9 | time: query.time || 0,
10 | }
11 | return request(
12 | 'POST',
13 | `https://music.163.com/api/comment/user/comment/history`,
14 | data,
15 | {
16 | crypto: 'weapi',
17 | cookie: query.cookie,
18 | proxy: query.proxy,
19 | realIP: query.realIP,
20 | },
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/module/user_detail.js:
--------------------------------------------------------------------------------
1 | // 用户详情
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/v1/user/detail/${query.uid}`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/user_dj.js:
--------------------------------------------------------------------------------
1 | // 用户电台节目
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 30,
6 | offset: query.offset || 0,
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/weapi/dj/program/${query.uid}`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/user_event.js:
--------------------------------------------------------------------------------
1 | // 用户动态
2 |
3 | module.exports = (query, request) => {
4 | query.cookie.os = 'ios'
5 | query.cookie.appver = '8.7.01'
6 | const data = {
7 | getcounts: true,
8 | time: query.lasttime || -1,
9 | limit: query.limit || 30,
10 | total: false,
11 | }
12 | return request(
13 | 'POST',
14 | `https://music.163.com/api/event/get/${query.uid}`,
15 | data,
16 | {
17 | crypto: 'api',
18 | cookie: query.cookie,
19 | proxy: query.proxy,
20 | realIP: query.realIP,
21 | },
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/module/user_followeds.js:
--------------------------------------------------------------------------------
1 | // 关注TA的人(粉丝)
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | userId: query.uid,
6 | time: '0',
7 | limit: query.limit || 30,
8 | offset: query.offset || 0,
9 | getcounts: 'true',
10 | }
11 | return request(
12 | 'POST',
13 | `https://music.163.com/eapi/user/getfolloweds/${query.uid}`,
14 | data,
15 | {
16 | crypto: 'eapi',
17 | cookie: query.cookie,
18 | proxy: query.proxy,
19 | url: '/api/user/getfolloweds',
20 | realIP: query.realIP,
21 | },
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/module/user_follows.js:
--------------------------------------------------------------------------------
1 | // TA关注的人(关注)
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | offset: query.offset || 0,
6 | limit: query.limit || 30,
7 | order: true,
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/weapi/user/getfollows/${query.uid}`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/user_level.js:
--------------------------------------------------------------------------------
1 | // 类别热门电台
2 |
3 | module.exports = (query, request) => {
4 | const data = {}
5 | return request('POST', `https://music.163.com/weapi/user/level`, data, {
6 | crypto: 'weapi',
7 | cookie: query.cookie,
8 | proxy: query.proxy,
9 | realIP: query.realIP,
10 | })
11 | }
12 |
--------------------------------------------------------------------------------
/module/user_playlist.js:
--------------------------------------------------------------------------------
1 | // 用户歌单
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | uid: query.uid,
6 | limit: query.limit || 30,
7 | offset: query.offset || 0,
8 | includeVideo: true,
9 | }
10 | return request('POST', `https://music.163.com/api/user/playlist`, data, {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | })
16 | }
17 |
--------------------------------------------------------------------------------
/module/user_record.js:
--------------------------------------------------------------------------------
1 | // 听歌排行
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | uid: query.uid,
6 | type: query.type || 0, // 1: 最近一周, 0: 所有时间
7 | }
8 | return request('POST', `https://music.163.com/weapi/v1/play/record`, data, {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/module/user_replacephone.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {
3 | phone: query.phone,
4 | captcha: query.captcha,
5 | oldcaptcha: query.oldcaptcha,
6 | countrycode: query.countrycode || '86',
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/api/user/replaceCellphone`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/user_subcount.js:
--------------------------------------------------------------------------------
1 | // 收藏计数
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/subcount`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/user_update.js:
--------------------------------------------------------------------------------
1 | // 编辑用户信息
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | avatarImgId: '0',
6 | birthday: query.birthday,
7 | city: query.city,
8 | gender: query.gender,
9 | nickname: query.nickname,
10 | province: query.province,
11 | signature: query.signature,
12 | }
13 | return request(
14 | 'POST',
15 | `https://music.163.com/weapi/user/profile/update`,
16 | data,
17 | {
18 | crypto: 'weapi',
19 | cookie: query.cookie,
20 | proxy: query.proxy,
21 | realIP: query.realIP,
22 | },
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/module/video_category_list.js:
--------------------------------------------------------------------------------
1 | // 视频分类列表
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | offset: query.offset || 0,
6 | total: 'true',
7 | limit: query.limit || 99,
8 | }
9 | return request(
10 | 'POST',
11 | `https://music.163.com/api/cloudvideo/category/list`,
12 | data,
13 | {
14 | crypto: 'weapi',
15 | cookie: query.cookie,
16 | proxy: query.proxy,
17 | realIP: query.realIP,
18 | },
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/module/video_detail.js:
--------------------------------------------------------------------------------
1 | // 视频详情
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | id: query.id,
6 | }
7 | return request(
8 | 'POST',
9 | `https://music.163.com/weapi/cloudvideo/v1/video/detail`,
10 | data,
11 | {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | },
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/module/video_detail_info.js:
--------------------------------------------------------------------------------
1 | // 视频点赞转发评论数数据
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | threadid: `R_VI_62_${query.vid}`,
6 | composeliked: true,
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/api/comment/commentthread/info`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/video_group.js:
--------------------------------------------------------------------------------
1 | // 视频标签/分类下的视频
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | groupId: query.id,
6 | offset: query.offset || 0,
7 | need_preview_url: 'true',
8 | total: true,
9 | }
10 | return request(
11 | 'POST',
12 | `https://music.163.com/api/videotimeline/videogroup/otherclient/get`,
13 | data,
14 | {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | },
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/module/video_group_list.js:
--------------------------------------------------------------------------------
1 | // 视频标签列表
2 |
3 | module.exports = (query, request) => {
4 | const data = {}
5 | return request(
6 | 'POST',
7 | `https://music.163.com/api/cloudvideo/group/list`,
8 | data,
9 | {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/video_sub.js:
--------------------------------------------------------------------------------
1 | // 收藏与取消收藏视频
2 |
3 | module.exports = (query, request) => {
4 | query.t = query.t == 1 ? 'sub' : 'unsub'
5 | const data = {
6 | id: query.id,
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/weapi/cloudvideo/video/${query.t}`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/video_timeline_all.js:
--------------------------------------------------------------------------------
1 | // 全部视频列表
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | groupId: 0,
6 | offset: query.offset || 0,
7 | need_preview_url: 'true',
8 | total: true,
9 | }
10 | // /api/videotimeline/otherclient/get
11 | return request(
12 | 'POST',
13 | `https://music.163.com/api/videotimeline/otherclient/get`,
14 | data,
15 | {
16 | crypto: 'weapi',
17 | cookie: query.cookie,
18 | proxy: query.proxy,
19 | realIP: query.realIP,
20 | },
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/module/video_timeline_recommend.js:
--------------------------------------------------------------------------------
1 | // 推荐视频
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | offset: query.offset || 0,
6 | filterLives: '[]',
7 | withProgramInfo: 'true',
8 | needUrl: '1',
9 | resolution: '480',
10 | }
11 | return request('POST', `https://music.163.com/api/videotimeline/get`, data, {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | })
17 | }
18 |
--------------------------------------------------------------------------------
/module/video_url.js:
--------------------------------------------------------------------------------
1 | // 视频链接
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | ids: '["' + query.id + '"]',
6 | resolution: query.res || 1080,
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/weapi/cloudvideo/playurl`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/vip_growthpoint.js:
--------------------------------------------------------------------------------
1 | // 会员成长值
2 |
3 | module.exports = (query, request) => {
4 | const data = {}
5 | return request(
6 | 'POST',
7 | `https://music.163.com/weapi/vipnewcenter/app/level/growhpoint/basic`,
8 | data,
9 | {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/vip_growthpoint_details.js:
--------------------------------------------------------------------------------
1 | // 会员成长值领取记录
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | limit: query.limit || 20,
6 | offset: query.offset || 0,
7 | }
8 | return request(
9 | 'POST',
10 | `https://music.163.com/weapi/vipnewcenter/app/level/growth/details`,
11 | data,
12 | {
13 | crypto: 'weapi',
14 | cookie: query.cookie,
15 | proxy: query.proxy,
16 | realIP: query.realIP,
17 | },
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/module/vip_growthpoint_get.js:
--------------------------------------------------------------------------------
1 | // 领取会员成长值
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | taskIds: query.ids,
6 | }
7 | return request(
8 | 'POST',
9 | `https://music.163.com/weapi/vipnewcenter/app/level/task/reward/get`,
10 | data,
11 | {
12 | crypto: 'weapi',
13 | cookie: query.cookie,
14 | proxy: query.proxy,
15 | realIP: query.realIP,
16 | },
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/module/vip_info.js:
--------------------------------------------------------------------------------
1 | // 获取 VIP 信息
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/music-vip-membership/front/vip/info`,
7 | {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/vip_tasks.js:
--------------------------------------------------------------------------------
1 | // 会员任务
2 |
3 | module.exports = (query, request) => {
4 | const data = {}
5 | return request(
6 | 'POST',
7 | `https://music.163.com/weapi/vipnewcenter/app/level/task/list`,
8 | data,
9 | {
10 | crypto: 'weapi',
11 | cookie: query.cookie,
12 | proxy: query.proxy,
13 | realIP: query.realIP,
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/module/vip_timemachine.js:
--------------------------------------------------------------------------------
1 | // 黑胶时光机
2 |
3 | module.exports = (query, request) => {
4 | const data = {}
5 | if (query.startTime && query.endTime) {
6 | data.startTime = query.startTime
7 | data.endTime = query.endTime
8 | data.type = 1
9 | data.limit = query.limit || 60
10 | }
11 | return request(
12 | 'POST',
13 | `https://music.163.com/weapi/vipmusic/newrecord/weekflow`,
14 | data,
15 | {
16 | crypto: 'weapi',
17 | cookie: query.cookie,
18 | proxy: query.proxy,
19 | realIP: query.realIP,
20 | },
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/module/weblog.js:
--------------------------------------------------------------------------------
1 | // 操作记录
2 |
3 | module.exports = (query, request) => {
4 | return request(
5 | 'POST',
6 | `https://music.163.com/weapi/feedback/weblog`,
7 | query.data || {},
8 | {
9 | crypto: 'weapi',
10 | cookie: query.cookie,
11 | proxy: query.proxy,
12 | realIP: query.realIP,
13 | },
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/module/yunbei.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {}
3 | // /api/point/today/get
4 | return request('POST', `https://music.163.com/api/point/signed/get`, data, {
5 | crypto: 'weapi',
6 | cookie: query.cookie,
7 | proxy: query.proxy,
8 | realIP: query.realIP,
9 | })
10 | }
11 |
--------------------------------------------------------------------------------
/module/yunbei_expense.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {
3 | limit: query.limit || 10,
4 | offset: query.offset || 0,
5 | }
6 | return request(
7 | 'POST',
8 | `https://music.163.com/store/api/point/expense`,
9 | data,
10 | {
11 | crypto: 'api',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | },
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/module/yunbei_info.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {}
3 | return request('POST', `https://music.163.com/api/v1/user/info`, data, {
4 | crypto: 'weapi',
5 | cookie: query.cookie,
6 | proxy: query.proxy,
7 | realIP: query.realIP,
8 | })
9 | }
10 |
--------------------------------------------------------------------------------
/module/yunbei_rcmd_song.js:
--------------------------------------------------------------------------------
1 | // 云贝推歌
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | songId: query.id,
6 | reason: query.reason || '好歌献给你',
7 | scene: '',
8 | fromUserId: -1,
9 | }
10 | return request(
11 | 'POST',
12 | `https://music.163.com/weapi/yunbei/rcmd/song/submit`,
13 | data,
14 | {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | },
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/module/yunbei_rcmd_song_history.js:
--------------------------------------------------------------------------------
1 | // 云贝推歌历史记录
2 |
3 | module.exports = (query, request) => {
4 | const data = {
5 | page: JSON.stringify({
6 | size: query.size || 20,
7 | cursor: query.cursor || '',
8 | }),
9 | }
10 | return request(
11 | 'POST',
12 | `https://music.163.com/weapi/yunbei/rcmd/song/history/list`,
13 | data,
14 | {
15 | crypto: 'weapi',
16 | cookie: query.cookie,
17 | proxy: query.proxy,
18 | realIP: query.realIP,
19 | },
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/module/yunbei_receipt.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {
3 | limit: query.limit || 10,
4 | offset: query.offset || 0,
5 | }
6 | return request(
7 | 'POST',
8 | `https://music.163.com/store/api/point/receipt`,
9 | data,
10 | {
11 | crypto: 'api',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | },
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/module/yunbei_sign.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {
3 | type: '0',
4 | }
5 | return request('POST', `https://music.163.com/api/point/dailyTask`, data, {
6 | crypto: 'weapi',
7 | cookie: query.cookie,
8 | proxy: query.proxy,
9 | realIP: query.realIP,
10 | })
11 | }
12 |
--------------------------------------------------------------------------------
/module/yunbei_task_finish.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {
3 | userTaskId: query.userTaskId,
4 | depositCode: query.depositCode || '0',
5 | }
6 | return request(
7 | 'POST',
8 | `https://music.163.com/api/usertool/task/point/receive`,
9 | data,
10 | {
11 | crypto: 'weapi',
12 | cookie: query.cookie,
13 | proxy: query.proxy,
14 | realIP: query.realIP,
15 | },
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/module/yunbei_tasks.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {}
3 | return request(
4 | 'POST',
5 | `https://music.163.com/api/usertool/task/list/all`,
6 | data,
7 | {
8 | crypto: 'weapi',
9 | cookie: query.cookie,
10 | proxy: query.proxy,
11 | realIP: query.realIP,
12 | },
13 | )
14 | }
15 |
--------------------------------------------------------------------------------
/module/yunbei_tasks_todo.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {}
3 | return request(
4 | 'POST',
5 | `https://music.163.com/api/usertool/task/todo/query`,
6 | data,
7 | {
8 | crypto: 'weapi',
9 | cookie: query.cookie,
10 | proxy: query.proxy,
11 | realIP: query.realIP,
12 | },
13 | )
14 | }
15 |
--------------------------------------------------------------------------------
/module/yunbei_today.js:
--------------------------------------------------------------------------------
1 | module.exports = (query, request) => {
2 | const data = {}
3 | return request('POST', `https://music.163.com/api/point/today/get`, data, {
4 | crypto: 'weapi',
5 | cookie: query.cookie,
6 | proxy: query.proxy,
7 | realIP: query.realIP,
8 | })
9 | }
10 |
--------------------------------------------------------------------------------
/module_example/avatar_upload.js:
--------------------------------------------------------------------------------
1 | const { avatar_upload, login_cellphone } = require('../main')
2 | const fs = require('fs')
3 | const path = require('path')
4 |
5 | async function main() {
6 | const result = await login_cellphone({
7 | phone: '手机号',
8 | password: '密码',
9 | })
10 | const filePath = './test.jpg'
11 | await avatar_upload({
12 | imgFile: {
13 | name: path.basename(filePath),
14 | data: fs.readFileSync(filePath),
15 | },
16 | imgSize: 1012, //图片尺寸,需要正方形图片
17 | cookie: result.body.cookie,
18 | })
19 | }
20 | main()
21 |
--------------------------------------------------------------------------------
/module_example/multi_song_upload.js:
--------------------------------------------------------------------------------
1 | const { cloud, login_cellphone } = require('../main')
2 | const fs = require('fs')
3 | const path = require('path')
4 | const yargs = require('yargs')
5 |
6 | const MUSIC_FILE_EXTENSIONS = new Set(['.mp3', '.flac'])
7 |
8 | function getAllMusicFiles(dir, arrayOfFiles) {
9 | arrayOfFiles = arrayOfFiles || []
10 |
11 | fs.readdirSync(dir).forEach((file) => {
12 | let fullPath = path.join(dir, file)
13 | if (fs.lstatSync(fullPath).isDirectory()) {
14 | getAllMusicFiles(fullPath, arrayOfFiles)
15 | } else {
16 | if (MUSIC_FILE_EXTENSIONS.has(path.extname(fullPath))) {
17 | arrayOfFiles.push(fullPath)
18 | }
19 | }
20 | })
21 |
22 | return arrayOfFiles
23 | }
24 |
25 | function getParsedArgs() {
26 | return yargs(process.argv.slice(2))
27 | .option('country_code', {
28 | default: '86',
29 | describe: 'The country code of your phone number',
30 | type: 'string',
31 | })
32 | .option('phone_number', {
33 | demandOption: true,
34 | describe: 'Your phone number',
35 | type: 'string',
36 | })
37 | .option('password', {
38 | demandOption: true,
39 | describe: 'Your password',
40 | type: 'string',
41 | })
42 | .option('file', {
43 | describe: 'The absolute path to the single music file to be uploaded',
44 | type: 'string',
45 | })
46 | .option('dir', {
47 | describe: 'The absolute to the directory of music files to be uploaded',
48 | type: 'string',
49 | })
50 | .conflicts('file', 'dir')
51 | .help()
52 | .alias('help', 'h').argv
53 | }
54 |
55 | async function main() {
56 | const args = getParsedArgs()
57 | const result = await login_cellphone({
58 | countrycode: args.country_code,
59 | phone: args.phone_number,
60 | password: args.password,
61 | })
62 | const files = args.file
63 | ? getAllMusicFiles(args.file)
64 | : getAllMusicFiles(args.dir)
65 | let processed = 0
66 | let failed = 0
67 | for (let k in files) {
68 | const file = files[k]
69 | try {
70 | await cloud({
71 | songFile: {
72 | name: path.basename(file),
73 | data: fs.readFileSync(file),
74 | },
75 | cookie: result.body.cookie,
76 | })
77 | } catch (error) {
78 | console.log(error)
79 | failed += 1
80 | }
81 | processed += 1
82 | console.log(`Processed ${processed}/${files.length} songs...`)
83 | if (failed) {
84 | console.log(`Failed to upload ${failed} songs...`)
85 | }
86 | }
87 | console.log('Finished!')
88 | }
89 | main()
90 |
--------------------------------------------------------------------------------
/module_example/song_upload.js:
--------------------------------------------------------------------------------
1 | const { cloud, login_cellphone } = require('../main')
2 | const fs = require('fs')
3 | const path = require('path')
4 |
5 | async function main() {
6 | const result = await login_cellphone({
7 | phone: '手机号',
8 | password: '密码',
9 | })
10 | const filePath = './test.mp3'
11 | try {
12 | await cloud({
13 | songFile: {
14 | name: path.basename(filePath),
15 | data: fs.readFileSync(filePath),
16 | },
17 | cookie: result.body.cookie,
18 | })
19 | } catch (error) {
20 | console.log(error, 'error')
21 | }
22 | }
23 | main()
24 |
--------------------------------------------------------------------------------
/module_example/test.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/module_example/test.jpg
--------------------------------------------------------------------------------
/module_example/test.js:
--------------------------------------------------------------------------------
1 | const {
2 | login_cellphone,
3 | user_cloud,
4 | album_sublist,
5 | song_url,
6 | } = require('../main')
7 | async function test() {
8 | try {
9 | const result = await login_cellphone({
10 | phone: '手机号',
11 | password: '密码',
12 | })
13 | console.log(result)
14 | const result2 = await user_cloud({
15 | cookie: result.body.cookie,
16 | })
17 | console.log(result2.body)
18 | const result3 = await album_sublist({
19 | cookie: result.body.cookie,
20 | })
21 | console.log(result3.body)
22 | const result4 = await song_url({
23 | cookie: result.body.cookie,
24 | id: 33894312,
25 | })
26 | console.log(result4.body)
27 | } catch (error) {
28 | console.log(error)
29 | }
30 | }
31 | test()
32 |
--------------------------------------------------------------------------------
/module_example/test.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/module_example/test.mp3
--------------------------------------------------------------------------------
/module_example/test.ts:
--------------------------------------------------------------------------------
1 | import { banner, lyric } from 'NeteaseCloudMusicApi'
2 | banner({ type: 0 }).then((res) => {
3 | console.log(res)
4 | })
5 | lyric({
6 | id: '33894312',
7 | }).then((res) => {
8 | console.log(res)
9 | })
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "NeteaseCloudMusicApi",
3 | "version": "4.5.14",
4 | "description": "网易云音乐 NodeJS 版 API",
5 | "scripts": {
6 | "start": "node app.js",
7 | "test": "mocha -r intelli-espower-loader -t 20000 server.test.js main.test.js --exit",
8 | "lint": "eslint \"**/*.{js,ts}\"",
9 | "lint-fix": "eslint --fix \"**/*.{js,ts}\"",
10 | "prepare": "husky install",
11 | "pkgwin": "pkg . -t node14-win-x64 -o app",
12 | "pkglinux": "pkg . -t node14-linux-x64 -o app",
13 | "pkgmacos": "pkg . -t node14-macos-x64 -o app"
14 | },
15 | "bin": "./app.js",
16 | "pkg": {
17 | "scripts": "module/*.js",
18 | "assets": [
19 | "/node_modules/vm2/lib/contextify.js",
20 | "/public"
21 | ]
22 | },
23 | "keywords": [
24 | "网易云音乐",
25 | "网易云",
26 | "音乐",
27 | "网易云音乐nodejs"
28 | ],
29 | "main": "main.js",
30 | "types": "./interface.d.ts",
31 | "engines": {
32 | "node": ">=12"
33 | },
34 | "lint-staged": {
35 | "*.js": [
36 | "eslint --fix",
37 | "git add"
38 | ]
39 | },
40 | "author": "binaryify",
41 | "license": "MIT",
42 | "files": [
43 | "module",
44 | "util",
45 | "plugins",
46 | "main.d.ts",
47 | "interface.d.ts",
48 | "module_types",
49 | "server.js"
50 | ],
51 | "dependencies": {
52 | "axios": "^0.24.0",
53 | "express": "^4.17.1",
54 | "express-fileupload": "^1.1.9",
55 | "md5": "^2.3.0",
56 | "music-metadata": "^7.5.3",
57 | "pac-proxy-agent": "^5.0.0",
58 | "qrcode": "^1.4.4",
59 | "safe-decode-uri-component": "^1.2.1",
60 | "tunnel": "^0.0.6",
61 | "yargs": "^17.1.1"
62 | },
63 | "devDependencies": {
64 | "@types/express": "^4.17.13",
65 | "@types/express-fileupload": "^1.2.2",
66 | "@types/mocha": "^9.1.0",
67 | "@types/node": "16.11.19",
68 | "@typescript-eslint/eslint-plugin": "5.0.0",
69 | "@typescript-eslint/parser": "5.0.0",
70 | "eslint": "8.7.0",
71 | "eslint-config-prettier": "8.3.0",
72 | "eslint-plugin-html": "6.2.0",
73 | "eslint-plugin-prettier": "4.0.0",
74 | "husky": "7.0.4",
75 | "intelli-espower-loader": "1.1.0",
76 | "lint-staged": "12.1.7",
77 | "mocha": "8.4.0",
78 | "power-assert": "1.6.1",
79 | "prettier": "2.5.1",
80 | "typescript": "4.5.2"
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/plugins/songUpload.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios')
2 | module.exports = async (query, request) => {
3 | let ext = 'mp3'
4 | if (query.songFile.name.indexOf('flac') > -1) {
5 | ext = 'flac'
6 | }
7 | const filename = query.songFile.name
8 | .replace('.' + ext, '')
9 | .replace(/\s/g, '')
10 | .replace(/\./g, '_')
11 | // 获取key和token
12 | const tokenRes = await request(
13 | 'POST',
14 | `https://music.163.com/weapi/nos/token/alloc`,
15 | {
16 | bucket: 'jd-musicrep-privatecloud-audio-public',
17 | ext: ext,
18 | filename: filename,
19 | local: false,
20 | nos_product: 3,
21 | type: 'audio',
22 | md5: query.songFile.md5,
23 | },
24 | { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy },
25 | )
26 |
27 | // 上传
28 | const objectKey = tokenRes.body.result.objectKey.replace('/', '%2F')
29 | try {
30 | await axios({
31 | method: 'post',
32 | url: `http://45.127.129.8/jd-musicrep-privatecloud-audio-public/${objectKey}?offset=0&complete=true&version=1.0`,
33 | headers: {
34 | 'x-nos-token': tokenRes.body.result.token,
35 | 'Content-MD5': query.songFile.md5,
36 | 'Content-Type': 'audio/mpeg',
37 | 'Content-Length': String(query.songFile.size),
38 | },
39 | data: query.songFile.data,
40 | maxContentLength: Infinity,
41 | maxBodyLength: Infinity,
42 | })
43 | } catch (error) {
44 | console.log('error', error.response)
45 | throw error.response
46 | }
47 | return {
48 | ...tokenRes,
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/plugins/upload.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios')
2 | module.exports = async (query, request) => {
3 | const data = {
4 | bucket: 'yyimgs',
5 | ext: 'jpg',
6 | filename: query.imgFile.name,
7 | local: false,
8 | nos_product: 0,
9 | return_body: `{"code":200,"size":"$(ObjectSize)"}`,
10 | type: 'other',
11 | }
12 | // 获取key和token
13 | const res = await request(
14 | 'POST',
15 | `https://music.163.com/weapi/nos/token/alloc`,
16 | data,
17 | { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy },
18 | )
19 | // 上传图片
20 | const res2 = await axios({
21 | method: 'post',
22 | url: `https://nosup-hz1.127.net/yyimgs/${res.body.result.objectKey}?offset=0&complete=true&version=1.0`,
23 | headers: {
24 | 'x-nos-token': res.body.result.token,
25 | 'Content-Type': 'image/jpeg',
26 | },
27 | data: query.imgFile.data,
28 | })
29 | // 获取裁剪后图片的id
30 | const imgSize = query.imgSize || 300
31 | const imgX = query.imgX || 0
32 | const imgY = query.imgY || 0
33 | const res3 = await request(
34 | 'POST',
35 | `https://music.163.com/upload/img/op?id=${res.body.result.docId}&op=${imgX}y${imgY}y${imgSize}y${imgSize}`,
36 | {},
37 | { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy },
38 | )
39 |
40 | return {
41 | // ...res.body.result,
42 | // ...res2.data,
43 | // ...res3.body,
44 | url_pre: 'https://p1.music.126.net/' + res.body.result.objectKey,
45 | url: res3.body.url,
46 | imgId: res3.body.id,
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/public/avatar_update.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 更新头像
7 |
8 |
9 |
10 |
11 |
12 |
14 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/public/cloud.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 云盘上传
8 |
9 |
10 |
11 |
12 |
13 |
14 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/public/home.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | home
8 |
9 |
10 |
11 |
12 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 网易云音乐 API
9 |
10 |
11 |
12 | 网易云音乐 API
13 | 当你看到这个页面时,这个服务已经成功跑起来了~
14 | 查看文档
15 |
例子:
16 |
21 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/public/login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
登录
8 |
9 |
10 |
11 |
12 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/public/qrlogin.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
二维码登录
8 |
9 |
10 |
11 |
![]()
12 |
13 |
15 |
63 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/public/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
test
9 |
10 |
11 |
12 |
请在控制台看结果
13 |
14 |
15 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "config:base"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/server.test.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const path = require('path')
3 | const serverMod = require('./server')
4 |
5 | /** @type {import("express").Express & serverMod.ExpressExtension} */
6 | let app
7 |
8 | before(async () => {
9 | app = await serverMod.serveNcmApi({})
10 |
11 | if (app.server && app.server.address) {
12 | const addr = app.server.address()
13 | if (addr && typeof addr === 'object' && 'port' in addr) {
14 | global.host = `http://localhost:${addr.port}`
15 | return
16 | }
17 | }
18 |
19 | throw new Error('failed to set up host')
20 | })
21 |
22 | after((done) => {
23 | if (app.server) {
24 | app.server.close(done)
25 | return
26 | }
27 |
28 | throw new Error('failed to set up server')
29 | })
30 |
31 | fs.readdirSync(path.join(__dirname, 'test')).forEach((file) => {
32 | require(path.join(__dirname, 'test', file))
33 | })
34 |
--------------------------------------------------------------------------------
/static/artist_album.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/artist_album.png
--------------------------------------------------------------------------------
/static/artists.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/artists.png
--------------------------------------------------------------------------------
/static/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/banner.png
--------------------------------------------------------------------------------
/static/comment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/comment.png
--------------------------------------------------------------------------------
/static/docs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/docs.png
--------------------------------------------------------------------------------
/static/fm_trash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/fm_trash.png
--------------------------------------------------------------------------------
/static/like.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/like.png
--------------------------------------------------------------------------------
/static/likeSuccess.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/likeSuccess.png
--------------------------------------------------------------------------------
/static/mv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/mv.png
--------------------------------------------------------------------------------
/static/new_albums.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/new_albums.png
--------------------------------------------------------------------------------
/static/personal_fm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/personal_fm.png
--------------------------------------------------------------------------------
/static/play_mv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/play_mv.png
--------------------------------------------------------------------------------
/static/screenshot1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/screenshot1.png
--------------------------------------------------------------------------------
/static/screenshot2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/screenshot2.png
--------------------------------------------------------------------------------
/static/signinError.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/signinError.png
--------------------------------------------------------------------------------
/static/signinSuccess.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/signinSuccess.png
--------------------------------------------------------------------------------
/static/songDetail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/songDetail.png
--------------------------------------------------------------------------------
/static/top_artists.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/top_artists.png
--------------------------------------------------------------------------------
/static/top_list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/top_list.png
--------------------------------------------------------------------------------
/static/top_playlist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/top_playlist.png
--------------------------------------------------------------------------------
/static/专辑.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/专辑.png
--------------------------------------------------------------------------------
/static/推荐歌单.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/推荐歌单.png
--------------------------------------------------------------------------------
/static/推荐歌曲.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/推荐歌曲.png
--------------------------------------------------------------------------------
/static/搜索.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/搜索.png
--------------------------------------------------------------------------------
/static/歌单详情.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/歌单详情.png
--------------------------------------------------------------------------------
/static/歌词.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/歌词.png
--------------------------------------------------------------------------------
/static/用户歌单.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/用户歌单.png
--------------------------------------------------------------------------------
/static/登录.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/登录.png
--------------------------------------------------------------------------------
/static/音乐 url.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coderwhy/NeteaseCloudMusicApi/338ba1ea497d2049b62d9a9a54c00e266783c201/static/音乐 url.png
--------------------------------------------------------------------------------
/test/album.test.js:
--------------------------------------------------------------------------------
1 | const assert = require('assert')
2 | const axios = require('axios')
3 | const host = global.host || 'http://localhost:3000'
4 |
5 | describe('测试获取歌手专辑列表是否正常', () => {
6 | it('数据的 code 应该为200', (done) => {
7 | const qs = {
8 | id: 32311,
9 | }
10 |
11 | axios
12 | .get(`${host}/album`, {
13 | params: qs,
14 | })
15 | .then(({ status, data }) => {
16 | if (status == 200) {
17 | assert(data.code === 200)
18 | }
19 | done()
20 | })
21 | .catch((err) => {
22 | done(err)
23 | })
24 | })
25 | })
26 |
--------------------------------------------------------------------------------
/test/comment.test.js:
--------------------------------------------------------------------------------
1 | const assert = require('assert')
2 | const axios = require('axios')
3 | const host = global.host || 'http://localhost:3000'
4 |
5 | describe('测试获取评论是否正常', () => {
6 | it('数据的 code 应该为200', (done) => {
7 | const qs = {
8 | id: 32311,
9 | }
10 |
11 | axios
12 | .get(`${host}/comment/album`, {
13 | params: qs,
14 | })
15 | .then(({ status, data }) => {
16 | if (status == 200) {
17 | assert(data.code === 200)
18 | }
19 | done()
20 | })
21 | .catch((err) => {
22 | done(err)
23 | })
24 | })
25 | })
26 |
--------------------------------------------------------------------------------
/test/login.test.js:
--------------------------------------------------------------------------------
1 | const assert = require('assert')
2 | const axios = require('axios')
3 | const host = global.host || 'http://localhost:3000'
4 |
5 | console.log('注意: 测试登录需在 test/login.test.js 中填写账号密码!!!')
6 | const country_code = '1'
7 | const phone = '3156678705'
8 | const password = '1q2w3e4R'
9 | describe('测试登录是否正常', () => {
10 | it('手机登录 code 应该等于200', (done) => {
11 | const qs = {
12 | countrycode:
13 | process.env.NCM_API_TEST_LOGIN_COUNTRY_CODE || country_code || '',
14 | phone: process.env.NCM_API_TEST_LOGIN_PHONE || phone || '',
15 | password: process.env.NCM_API_TEST_LOGIN_PASSWORD || password || '',
16 | }
17 |
18 | axios
19 | .get(`${host}/login/cellphone`, {
20 | params: qs,
21 | })
22 | .then(({ status, data }) => {
23 | if (status == 200) {
24 | console.log('昵称:' + data.profile.nickname)
25 | assert(data.code === 200)
26 | done()
27 | } else {
28 | done('登录错误')
29 | }
30 | })
31 | .catch((err) => {
32 | done(err)
33 | })
34 | })
35 | })
36 |
--------------------------------------------------------------------------------
/test/lyric.test.js:
--------------------------------------------------------------------------------
1 | const assert = require('assert')
2 | const axios = require('axios')
3 | const host = global.host || 'http://localhost:3000'
4 |
5 | describe('测试获取歌词是否正常', () => {
6 | it('数据应该有 lrc 字段', (done) => {
7 | const qs = {
8 | id: 347230,
9 | }
10 |
11 | axios
12 | .get(`${host}/lyric`, {
13 | params: qs,
14 | })
15 | .then(({ status, data }) => {
16 | if (status == 200) {
17 | assert(typeof data.lrc !== 'undefined')
18 | }
19 | done()
20 | })
21 | .catch((err) => {
22 | done(err)
23 | })
24 | })
25 | })
26 |
--------------------------------------------------------------------------------
/test/music_url.test.js:
--------------------------------------------------------------------------------
1 | const assert = require('assert')
2 | const axios = require('axios')
3 | const host = global.host || 'http://localhost:3000'
4 |
5 | describe('测试获取歌曲是否正常', () => {
6 | it('歌曲的 url 不应该为空', (done) => {
7 | const qs = {
8 | id: 462791935,
9 | br: 999000,
10 | realIP: '116.25.146.177',
11 | }
12 |
13 | axios
14 | .get(`${host}/song/url`, {
15 | params: qs,
16 | })
17 | .then(({ status, data }) => {
18 | if (status == 200) {
19 | assert(!!data.data[0].url)
20 | }
21 | done()
22 | })
23 | .catch((err) => {
24 | done(err)
25 | })
26 | })
27 | })
28 |
--------------------------------------------------------------------------------
/test/search.test.js:
--------------------------------------------------------------------------------
1 | const assert = require('assert')
2 | const axios = require('axios')
3 | const host = global.host || 'http://localhost:3000'
4 |
5 | describe('测试搜索是否正常', () => {
6 | it('获取到的数据的 name 应该和搜索关键词一致', (done) => {
7 | const qs = {
8 | keywords: '海阔天空',
9 | type: 1,
10 | }
11 | axios
12 | .get(`${host}/search`, {
13 | params: qs,
14 | })
15 | .then(({ status, data }) => {
16 | if (status == 200) {
17 | assert(data.result.songs[0].name === '海阔天空')
18 | }
19 | done()
20 | })
21 | .catch((err) => {
22 | done(err)
23 | })
24 | })
25 | })
26 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2015",
4 | "module": "commonjs",
5 | "experimentalDecorators": true,
6 | "moduleResolution": "node",
7 | "lib": [
8 | "esnext",
9 | "esnext.asynciterable",
10 | "dom"
11 | ],
12 | "esModuleInterop": true,
13 | "allowJs": true,
14 | "sourceMap": true,
15 | "strict": true,
16 | "noEmit": true,
17 | "baseUrl": ".",
18 | "paths": {
19 | "~/*": [
20 | "./*"
21 | ],
22 | "@/*": [
23 | "./*"
24 | ]
25 | },
26 | },
27 | "exclude": [
28 | "node_modules"
29 | ]
30 | }
--------------------------------------------------------------------------------
/util/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "anonymous_token": "8aae43f148f990410b9a2af38324af24e87ab9227c9265627ddd10145db744295fcd8701dc45b1ab8985e142f491516295dd965bae848761274a577a62b0fdc54a50284d1e434dcc04ca6d1a52333c9a",
3 | "resourceTypeMap": {
4 | "0": "R_SO_4_",
5 | "1": "R_MV_5_",
6 | "2": "A_PL_0_",
7 | "3": "R_AL_3_",
8 | "4": "A_DJ_1_",
9 | "5": "R_VI_62_",
10 | "6": "A_EV_2_"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/util/crypto.js:
--------------------------------------------------------------------------------
1 | const crypto = require('crypto')
2 | const iv = Buffer.from('0102030405060708')
3 | const presetKey = Buffer.from('0CoJUm6Qyw8W8jud')
4 | const linuxapiKey = Buffer.from('rFgB&h#%2?^eDg:Q')
5 | const base62 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
6 | const publicKey =
7 | '-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgtQn2JZ34ZC28NWYpAUd98iZ37BUrX/aKzmFbt7clFSs6sXqHauqKWqdtLkF2KexO40H1YTX8z2lSgBBOAxLsvaklV8k4cBFK9snQXE9/DDaFt6Rr7iVZMldczhC0JNgTz+SHXT6CBHuX3e9SdB1Ua44oncaTWz7OBGLbCiK45wIDAQAB\n-----END PUBLIC KEY-----'
8 | const eapiKey = 'e82ckenh8dichen8'
9 |
10 | const aesEncrypt = (buffer, mode, key, iv) => {
11 | const cipher = crypto.createCipheriv('aes-128-' + mode, key, iv)
12 | return Buffer.concat([cipher.update(buffer), cipher.final()])
13 | }
14 |
15 | const rsaEncrypt = (buffer, key) => {
16 | buffer = Buffer.concat([Buffer.alloc(128 - buffer.length), buffer])
17 | return crypto.publicEncrypt(
18 | { key: key, padding: crypto.constants.RSA_NO_PADDING },
19 | buffer,
20 | )
21 | }
22 |
23 | const weapi = (object) => {
24 | const text = JSON.stringify(object)
25 | const secretKey = crypto
26 | .randomBytes(16)
27 | .map((n) => base62.charAt(n % 62).charCodeAt())
28 | return {
29 | params: aesEncrypt(
30 | Buffer.from(
31 | aesEncrypt(Buffer.from(text), 'cbc', presetKey, iv).toString('base64'),
32 | ),
33 | 'cbc',
34 | secretKey,
35 | iv,
36 | ).toString('base64'),
37 | encSecKey: rsaEncrypt(secretKey.reverse(), publicKey).toString('hex'),
38 | }
39 | }
40 |
41 | const linuxapi = (object) => {
42 | const text = JSON.stringify(object)
43 | return {
44 | eparams: aesEncrypt(Buffer.from(text), 'ecb', linuxapiKey, '')
45 | .toString('hex')
46 | .toUpperCase(),
47 | }
48 | }
49 |
50 | const eapi = (url, object) => {
51 | const text = typeof object === 'object' ? JSON.stringify(object) : object
52 | const message = `nobody${url}use${text}md5forencrypt`
53 | const digest = crypto.createHash('md5').update(message).digest('hex')
54 | const data = `${url}-36cd479b6b5-${text}-36cd479b6b5-${digest}`
55 | return {
56 | params: aesEncrypt(Buffer.from(data), 'ecb', eapiKey, '')
57 | .toString('hex')
58 | .toUpperCase(),
59 | }
60 | }
61 |
62 | const decrypt = (cipherBuffer) => {
63 | const decipher = crypto.createDecipheriv('aes-128-ecb', eapiKey, '')
64 | return Buffer.concat([decipher.update(cipherBuffer), decipher.final()])
65 | }
66 |
67 | module.exports = { weapi, linuxapi, eapi, decrypt }
68 |
--------------------------------------------------------------------------------
/util/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | toBoolean(val) {
3 | if (typeof val === 'boolean') return val
4 | if (val === '') return val
5 | return val === 'true' || val == '1'
6 | },
7 | cookieToJson(cookie) {
8 | if (!cookie) return {}
9 | let cookieArr = cookie.split(';')
10 | let obj = {}
11 | cookieArr.forEach((i) => {
12 | let arr = i.split('=')
13 | obj[arr[0]] = arr[1]
14 | })
15 | return obj
16 | },
17 | }
18 |
--------------------------------------------------------------------------------
/util/memory-cache.js:
--------------------------------------------------------------------------------
1 | function MemoryCache() {
2 | this.cache = {}
3 | this.size = 0
4 | }
5 |
6 | MemoryCache.prototype.add = function (key, value, time, timeoutCallback) {
7 | var old = this.cache[key]
8 | var instance = this
9 |
10 | var entry = {
11 | value: value,
12 | expire: time + Date.now(),
13 | timeout: setTimeout(function () {
14 | instance.delete(key)
15 | return (
16 | timeoutCallback &&
17 | typeof timeoutCallback === 'function' &&
18 | timeoutCallback(value, key)
19 | )
20 | }, time),
21 | }
22 |
23 | this.cache[key] = entry
24 | this.size = Object.keys(this.cache).length
25 |
26 | return entry
27 | }
28 |
29 | MemoryCache.prototype.delete = function (key) {
30 | var entry = this.cache[key]
31 |
32 | if (entry) {
33 | clearTimeout(entry.timeout)
34 | }
35 |
36 | delete this.cache[key]
37 |
38 | this.size = Object.keys(this.cache).length
39 |
40 | return null
41 | }
42 |
43 | MemoryCache.prototype.get = function (key) {
44 | var entry = this.cache[key]
45 |
46 | return entry
47 | }
48 |
49 | MemoryCache.prototype.getValue = function (key) {
50 | var entry = this.get(key)
51 |
52 | return entry && entry.value
53 | }
54 |
55 | MemoryCache.prototype.clear = function () {
56 | Object.keys(this.cache).forEach(function (key) {
57 | this.delete(key)
58 | }, this)
59 |
60 | return true
61 | }
62 |
63 | module.exports = MemoryCache
64 |
--------------------------------------------------------------------------------
/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "builds": [
4 | {
5 | "src": "./index.js",
6 | "use": "@vercel/node"
7 | }
8 | ],
9 | "routes": [
10 | {
11 | "src": "/(.*)",
12 | "dest": "/"
13 | }
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------