├── .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 | ![color](#ffffff) 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 | --------------------------------------------------------------------------------