feat: integrate api in electron app

master
kunkka 4 years ago
parent bd29570e31
commit 74bf714c28

1
.gitignore vendored

@ -28,5 +28,4 @@ pnpm-debug.log*
#Electron-builder output
/dist_electron
NeteaseCloudMusicApi-master
NeteaseCloudMusicApi-master.zip

@ -1,3 +1,4 @@
# 如果发现 npm / yarn 安装太慢,可以解除注释
# registry=https://registry.npm.taobao.org/
# ELECTRON_MIRROR=https://npm.taobao.org/mirrors/electron
registry=https://registry.npm.taobao.org/
ELECTRON_MIRROR=https://npm.taobao.org/mirrors/electron
phantomjs_cdnurl=https://npm.taobao.org/dist/phantomjs

@ -0,0 +1,34 @@
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
# Matches multiple files with brace expansion notation
# Set default charset
[*.{js,py}]
charset = utf-8
# 4 space indentation
[*.py]
indent_style = space
indent_size = 4
# Tab indentation (no size specified)
[Makefile]
indent_style = tab
# Indentation override for all JS under lib directory
[*.{js,ts}]
indent_style = space
indent_size = 2
# Matches the exact files either package.json or .travis.yml
[{package.json,.travis.yml}]
indent_style = space
indent_size = 2

@ -0,0 +1,49 @@
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint',
ecmaVersion: 2018,
sourceType: 'module',
},
plugins: ['html'],
extends: ['plugin:prettier/recommended'],
env: {
browser: true,
node: true,
},
rules: {
indent: ['error', 2, { SwitchCase: 1 }],
'space-infix-ops': ['error', { int32Hint: false }],
'key-spacing': [
2,
{
beforeColon: false,
afterColon: true,
},
],
'no-octal': 2,
'no-redeclare': 2,
'comma-spacing': 2,
'no-new-object': 2,
'arrow-spacing': 2,
quotes: [
2,
'single',
{
avoidEscape: true,
allowTemplateLiterals: true,
},
],
},
overrides: [
{
files: ['**/*.ts'],
parser: '@typescript-eslint/parser',
extends: [
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
'prettier/@typescript-eslint',
],
},
],
};

5
napi/.gitignore vendored

@ -0,0 +1,5 @@
.DS_Store
node_modules
*.log
.idea
.vscode

@ -0,0 +1,3 @@
static
docs
node_modules

@ -0,0 +1,5 @@
{
"semi": true,
"trailingComma": "all",
"singleQuote": true
}

@ -0,0 +1,312 @@
# 网易云音乐 API
网易云音乐 Node.js API service
<p>
<a href="https://www.npmjs.com/package/NeteaseCloudMusicApi"><img src="https://img.shields.io/npm/v/NeteaseCloudMusicApi.svg" alt="Version"></a>
<a href="https://www.npmjs.com/package/NeteaseCloudMusicApi"><img src="https://img.shields.io/npm/l/NeteaseCloudMusicApi.svg" alt="License"></a>
<a href="https://www.npmjs.com/package/NeteaseCloudMusicApi"><img src="https://img.shields.io/david/dev/binaryify/NeteaseCloudMusicApi.svg" alt="devDependencies" ></a>
<a href="https://www.npmjs.com/package/NeteaseCloudMusicApi"><img src="https://img.shields.io/david/binaryify/NeteaseCloudMusicApi.svg" alt="devDependencies" ></a>
<a href="https://codeclimate.com/github/Binaryify/NeteaseCloudMusicApi"><img src="https://codeclimate.com/github/Binaryify/NeteaseCloudMusicApi/badges/gpa.svg" /></a>
</p>
## 灵感来自
[disoul/electron-cloud-music](https://github.com/disoul/electron-cloud-music)
[darknessomi/musicbox](https://github.com/darknessomi/musicbox)
[sqaiyan/netmusic-node](https://github.com/sqaiyan/netmusic-node)
## 环境要求
需要 NodeJS 8.12+ 环境
## 安装
```shell
$ git clone git@github.com:Binaryify/NeteaseCloudMusicApi.git
$ npm install
```
或者
```shell
$ git clone https://github.com/Binaryify/NeteaseCloudMusicApi.git
$ npm install
```
## 运行
```shell
$ node app.js
```
服务器启动默认端口为 3000,若不想使用 3000 端口,可使用以下命令: Mac/Linux
```shell
$ PORT=4000 node app.js
```
windows 下使用 git-bash 或者 cmder 等终端执行以下命令:
```shell
$ set PORT=4000 && node app.js
```
## 可以在Node.js调用
v3.31.0后支持Node.js调用,导入的方法为`module`内的文件名,返回内容包含`status`和`body`,`status`为状态码,`body`为请求返回内容,参考`module_example` 文件夹下的 `test.js`
```js
const { login_cellphone, user_cloud } = require('NeteaseCloudMusicApi')
async function main() {
try {
const result = await login_cellphone({
phone: '手机号',
password: '密码'
})
console.log(result)
const result2 = await user_cloud({
cookie: result.body.cookie // 凭证
})
console.log(result2.body)
} catch (error) {
console.log(error)
}
}
main()
```
## 支持 TypeScript
```ts
// test.ts
import { banner } from 'NeteaseCloudMusicApi'
banner({ type:0 }).then(res=>{
console.log(res)
})
```
## 使用文档
[文档地址](https://binaryify.github.io/NeteaseCloudMusicApi)
[文档地址2](https://neteasecloudmusicapi.vercel.app)
![文档](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/docs.png)
## 功能特性
1. 登录
2. 刷新登录
3. 发送验证码
4. 校验验证码
5. 注册(修改密码)
6. 获取用户信息 , 歌单收藏mv, dj 数量
7. 获取用户歌单
8. 获取用户电台
9. 获取用户关注列表
10. 获取用户粉丝列表
11. 获取用户动态
12. 获取用户播放记录
13. 获取精品歌单
14. 获取歌单详情
15. 搜索
16. 搜索建议
17. 获取歌词
18. 歌曲评论
19. 收藏单曲到歌单
20. 专辑评论
21. 歌单评论
22. mv 评论
23. 电台节目评论
24. banner
25. 获取歌曲详情
26. 获取专辑内容
27. 获取歌手单曲
28. 获取歌手 mv
29. 获取歌手专辑
30. 获取歌手描述
31. 获取相似歌手
32. 获取相似歌单
33. 相似 mv
34. 获取相似音乐
35. 获取最近 5 个听了这首歌的用户
36. 获取每日推荐歌单
37. 获取每日推荐歌曲
38. 私人 FM
39. 签到
40. 喜欢音乐
41. 垃圾桶
42. 歌单 ( 网友精选碟 )
43. 新碟上架
44. 热门歌手
45. 最新 mv
46. 推荐 mv
47. 推荐歌单
48. 推荐新音乐
49. 推荐电台
50. 推荐节目
51. 独家放送
52. mv 排行
53. 获取 mv 数据
54. 播放 mv/视频
55. 排行榜
56. 歌手榜
57. 云盘
58. 电台 - 推荐
59. 电台 - 分类
60. 电台 - 分类推荐
61. 电台 - 订阅
62. 电台 - 详情
63. 电台 - 节目
64. 给评论点赞
65. 获取动态
66. 热搜列表(简略)
67. 发送私信
68. 发送私信歌单
69. 新建歌单
70. 收藏/取消收藏歌单
71. 歌单分类
72. 收藏的歌手列表
73. 订阅的电台列表
74. 相关歌单推荐
75. 付费精选接口
76. 音乐是否可用检查接口
77. 登录状态
78. 获取视频播放地址
79. 发送/删除评论
80. 热门评论
81. 视频评论
82. 退出登录
83. 所有榜单
84. 所有榜单内容摘要
85. 收藏视频
86. 收藏 MV
87. 视频详情
88. 相关视频
89. 关注用户
90. 新歌速递
91. 喜欢音乐列表(无序)
92. 收藏的 MV 列表
93. 获取最新专辑
94. 听歌打卡
95. 获取视频标签/分类下的视频
96. 已收藏专辑列表
97. 获取动态评论
98. 歌单收藏者列表
99. 云盘歌曲删除
100. 热门话题
101. 电台 - 推荐类型
102. 电台 - 非热门类型
103. 电台 - 今日优选
104. 心动模式/智能播放
105. 转发动态
106. 删除动态
107. 分享歌曲、歌单、mv、电台、电台节目到动态
108. 通知-私信
109. 通知-评论
110. 通知-@我
111. 通知-通知
112. 设置
113. 云盘数据详情
114. 私信内容
115. 我的数字专辑
116. batch批量请求接口
117. 获取视频标签列表
118. 全部mv
119. 网易出品mv
120. 收藏/取消收藏专辑
121. 专辑动态信息
122. 热搜列表(详细)
123. 更换绑定手机
124. 检测手机号码是否已注册
125. 初始化昵称
126. 更新歌单描述
127. 更新歌单名
128. 更新歌单标签
129. 默认搜索关键词
130. 删除歌单
131. 电台banner
132. 用户电台
133. 热门电台
134. 电台 - 节目详情
135. 电台 - 节目榜
136. 电台 - 新晋电台榜/热门电台榜
137. 类别热门电台
138. 云村热评
139. 电台24小时节目榜
140. 电台24小时主播榜
141. 电台最热主播榜
142. 电台主播新人榜
143. 电台付费精品榜
144. 歌手热门50首歌曲
145. 购买数字专辑
146. 获取 mv 点赞转发评论数数据
147. 获取视频点赞转发评论数数据
148. 调整歌单顺序
149. 调整歌曲顺序
150. 独家放送列表
151. 获取推荐视频
152. 获取视频分类列表
153. 获取全部视频列表接口
154. 获取历史日推可用日期列表
155. 获取历史日推详细数据
156. 国家编码列表
157. 首页-发现
158. 首页-发现-圆形图标入口列表
159. 数字专辑-全部新碟
160. 数字专辑-热门新碟
161. 数字专辑&数字单曲-榜单
162. 数字专辑-语种风格馆
163. 数字专辑详情
164. 更新头像
165. 歌单封面上传
166. 楼层评论
167. 歌手全部歌曲
168. 精品歌单标签列表
169. 用户等级信息
170. 电台个性推荐
171. 用户绑定信息
172. 用户绑定手机
173. 新版评论
174. 点赞过的视频
175. 收藏视频到视频歌单
176. 删除视频歌单里的视频
177. 最近播放的视频
178. 音乐日历
179. 电台订阅者列表
180. 云贝签到信息
181. 云贝签到
182. 云贝所有任务
183. 云贝todo任务
184. 云贝今日签到信息
185. 云贝完成任务
186. 云贝收入
187. 云贝支出
188. 云贝账户信息
189. 账号信息
## 更新日志
[changelog](https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/CHANGELOG.MD)
## 单元测试
```shell
$ npm test
```
![单元测试](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/screenshot1.png)
![单元测试](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/screenshot2.png)
## 贡献者
![](https://opencollective.com/NeteaseCloudMusicApi/contributors.svg?width=890)
## License
[The MIT License (MIT)](https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/LICENSE)

@ -0,0 +1,117 @@
const fs = require('fs');
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const request = require('./util/request');
const packageJSON = require('./package.json');
const exec = require('child_process').exec;
const cache = require('./util/apicache').middleware;
const { cookieToJson } = require('./util/index');
const fileUpload = require('express-fileupload');
// version check
exec('npm info NeteaseCloudMusicApi version', (err, stdout, stderr) => {
if (!err) {
let version = stdout.trim();
if (packageJSON.version < version) {
console.log(
`最新版本: ${version}, 当前版本: ${packageJSON.version}, 请及时更新`,
);
}
}
});
const app = express();
// CORS & Preflight request
app.use((req, res, next) => {
if (req.path !== '/' && !req.path.includes('.')) {
res.set({
'Access-Control-Allow-Credentials': true,
'Access-Control-Allow-Origin': req.headers.origin || '*',
'Access-Control-Allow-Headers': 'X-Requested-With,Content-Type',
'Access-Control-Allow-Methods': 'PUT,POST,GET,DELETE,OPTIONS',
'Content-Type': 'application/json; charset=utf-8',
});
}
req.method === 'OPTIONS' ? res.status(204).end() : next();
});
// cookie parser
app.use((req, res, next) => {
req.cookies = {};
(req.headers.cookie || '').split(/\s*;\s*/).forEach((pair) => {
let crack = pair.indexOf('=');
if (crack < 1 || crack == pair.length - 1) return;
req.cookies[
decodeURIComponent(pair.slice(0, crack)).trim()
] = decodeURIComponent(pair.slice(crack + 1)).trim();
});
next();
});
// body parser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(fileUpload());
// static
app.use(express.static(path.join(__dirname, 'public')));
// cache
app.use(cache('2 minutes', (req, res) => res.statusCode === 200));
// router
const special = {
'daily_signin.js': '/daily_signin',
'fm_trash.js': '/fm_trash',
'personal_fm.js': '/personal_fm',
};
fs.readdirSync(path.join(__dirname, 'module'))
.reverse()
.forEach((file) => {
if (!file.endsWith('.js')) return;
let route =
file in special
? special[file]
: '/' + file.replace(/\.js$/i, '').replace(/_/g, '/');
let question = require(path.join(__dirname, 'module', file));
app.use(route, (req, res) => {
if (typeof req.query.cookie === 'string') {
req.query.cookie = cookieToJson(req.query.cookie);
}
let query = Object.assign(
{},
{ cookie: req.cookies },
req.query,
req.body,
req.files,
);
question(query, request)
.then((answer) => {
console.log('[OK]', decodeURIComponent(req.originalUrl));
res.append('Set-Cookie', answer.cookie);
res.status(answer.status).send(answer.body);
})
.catch((answer) => {
console.log('[ERR]', decodeURIComponent(req.originalUrl), {
status: answer.status,
body: answer.body,
});
if (answer.body.code == '301') answer.body.msg = '需要登录';
res.append('Set-Cookie', answer.cookie);
res.status(answer.status).send(answer.body);
});
});
});
const port = process.env.PORT || 3000;
const host = process.env.HOST || '';
app.server = app.listen(port, host, () => {
console.log(`server running @ http://${host ? host : 'localhost'}:${port}`);
});
module.exports = app;

@ -0,0 +1,60 @@
const fs = require('fs');
const path = require('path');
const express = require('express');
const request = require('./util/request');
const strip = require('strip-comments');
var router = express.Router();
const special = {
'daily_signin.js': '/daily_signin',
'fm_trash.js': '/fm_trash',
'personal_fm.js': '/personal_fm',
};
const app = express();
const temp = {};
fs.readdirSync(path.join(__dirname, 'module'))
.reverse()
.forEach((file) => {
if (!file.endsWith('.js')) return;
let route =
file in special
? special[file]
: '/' + file.replace(/\.js$/i, '').replace(/_/g, '/');
let question = require(path.join(__dirname, 'module', file));
// console.log(question.toString())
const func = `(req, res) => {
if (typeof req.query.cookie === 'string') {
req.query.cookie = cookieToJson(req.query.cookie);
}
let query = Object.assign(
{},
{ cookie: req.cookies },
req.query,
req.body,
req.files,
);
const ${file.replace(/\.js$/i, '')} = ${strip(question.toString())};
${file.replace(/\.js$/i, '')}(query, request)
.then((answer) => {
console.log('[OK]', decodeURIComponent(req.originalUrl));
res.append('Set-Cookie', answer.cookie);
res.status(answer.status).send(answer.body);
})
.catch((answer) => {
console.log('[ERR]', decodeURIComponent(req.originalUrl), {
status: answer.status,
body: answer.body,
});
if (answer.body.code == '301') answer.body.msg = '需要登录';
res.append('Set-Cookie', answer.cookie);
res.status(answer.status).send(answer.body);
})
}`;
temp[route] = func;
});
fs.writeFileSync(
path.resolve(__dirname, './test_result.json'),
JSON.stringify(temp),
);

1311
napi/interface.d.ts vendored

File diff suppressed because it is too large Load Diff

@ -0,0 +1,26 @@
const fs = require('fs');
const path = require('path');
const request = require('./util/request');
const { cookieToJson } = require('./util/index');
let obj = {};
fs.readdirSync(path.join(__dirname, 'module'))
.reverse()
.forEach((file) => {
if (!file.endsWith('.js')) return;
let fileModule = require(path.join(__dirname, 'module', file));
obj[file.split('.').shift()] = function (data) {
if (typeof data.cookie === 'string') {
data.cookie = cookieToJson(data.cookie);
}
return fileModule(
{
...data,
cookie: data.cookie ? data.cookie : {},
},
request,
);
};
});
module.exports = obj;

@ -0,0 +1,19 @@
// 初始化名字
module.exports = (query, request) => {
const data = {
nickname: query.nickname,
};
return request(
'POST',
`https://music.163.com/eapi/activate/initProfile`,
data,
{
crypto: 'eapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
url: '/api/activate/initProfile',
},
);
};

@ -0,0 +1,15 @@
// 专辑内容
module.exports = (query, request) => {
return request(
'POST',
`https://music.163.com/weapi/v1/album/${query.id}`,
{},
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,17 @@
// 数字专辑详情
module.exports = (query, request) => {
const data = {
id: query.id,
};
return request(
'POST',
`https://music.163.com/weapi/vipmall/albumproduct/detail`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,17 @@
// 专辑动态信息
module.exports = (query, request) => {
const data = {
id: query.id,
};
return request(
'POST',
`https://music.163.com/api/album/detail/dynamic`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,21 @@
// 数字专辑-新碟上架
module.exports = (query, request) => {
const data = {
limit: query.limit || 30,
offset: query.offset || 0,
total: true,
area: query.area || 'ALL', //ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本
type: query.type,
};
return request(
'POST',
`https://music.163.com/weapi/vipmall/albumproduct/list`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,20 @@
// 数字专辑-语种风格馆
module.exports = (query, request) => {
const data = {
limit: query.limit || 10,
offset: query.offset || 0,
total: true,
area: query.area || 'Z_H', //Z_H:华语,E_A:欧美,KR:韩国,JP:日本
};
return request(
'POST',
`https://music.163.com/weapi/vipmall/appalbum/album/style`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,15 @@
// 全部新碟
module.exports = (query, request) => {
const data = {
limit: query.limit || 30,
offset: query.offset || 0,
total: true,
area: query.area || 'ALL', //ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本
};
return request('POST', `https://music.163.com/weapi/album/new`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,15 @@
// 最新专辑
module.exports = (query, request) => {
return request(
'POST',
`https://music.163.com/api/discovery/newAlbum`,
{},
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,24 @@
// 数字专辑&数字单曲-榜单
module.exports = (query, request) => {
let data = {
albumType: query.albumType || 0, //0为数字专辑,1为数字单曲
};
const type = query.type || 'daily'; // daily,week,year,total
if (type === 'year') {
data = {
...data,
year: query.year,
};
}
return request(
'POST',
`https://music.163.com/api/feealbum/songsaleboard/${type}/type`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,14 @@
// 收藏/取消收藏专辑
module.exports = (query, request) => {
query.t = query.t == 1 ? 'sub' : 'unsub';
const data = {
id: query.id,
};
return request('POST', `https://music.163.com/api/album/${query.t}`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,15 @@
// 已收藏专辑列表
module.exports = (query, request) => {
const data = {
limit: query.limit || 25,
offset: query.offset || 0,
total: true,
};
return request('POST', `https://music.163.com/weapi/album/sublist`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,20 @@
// 歌手专辑列表
module.exports = (query, request) => {
const data = {
limit: query.limit || 30,
offset: query.offset || 0,
total: true,
};
return request(
'POST',
`https://music.163.com/weapi/artist/albums/${query.id}`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,18 @@
// 歌手介绍
module.exports = (query, request) => {
const data = {
id: query.id,
};
return request(
'POST',
`https://music.163.com/weapi/artist/introduction`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,37 @@
// 歌手分类
/*
type 取值
1:男歌手
2:女歌手
3:乐队
area 取值
-1:全部
7华语
96欧美
8:日本
16韩国
0:其他
initial 取值 a-z/A-Z
*/
module.exports = (query, request) => {
const data = {
initial: isNaN(query.initial)
? (query.initial || '').toUpperCase().charCodeAt() || undefined
: query.initial,
offset: query.offset || 0,
limit: query.limit || 30,
total: true,
type: query.type || '1',
area: query.area,
};
return request('POST', `https://music.163.com/api/v1/artist/list`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,16 @@
// 歌手相关MV
module.exports = (query, request) => {
const data = {
artistId: query.id,
limit: query.limit,
offset: query.offset,
total: true,
};
return request('POST', `https://music.163.com/weapi/artist/mvs`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,17 @@
module.exports = (query, request) => {
query.cookie.os = 'pc';
const data = {
id: query.id,
private_cloud: 'true',
work_type: 1,
order: query.order || 'hot', //hot,time
offset: query.offset || 0,
limit: query.limit || 100,
};
return request('POST', `https://music.163.com/api/v1/artist/songs`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,20 @@
// 收藏与取消收藏歌手
module.exports = (query, request) => {
query.t = query.t == 1 ? 'sub' : 'unsub';
const data = {
artistId: query.id,
artistIds: '[' + query.id + ']',
};
return request(
'POST',
`https://music.163.com/weapi/artist/${query.t}`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,15 @@
// 关注歌手列表
module.exports = (query, request) => {
const data = {
limit: query.limit || 25,
offset: query.offset || 0,
total: true,
};
return request('POST', `https://music.163.com/weapi/artist/sublist`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,12 @@
// 歌手热门 50 首歌曲
module.exports = (query, request) => {
const data = {
id: query.id,
};
return request('POST', `https://music.163.com/api/artist/top/song`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,15 @@
// 歌手单曲
module.exports = (query, request) => {
return request(
'POST',
`https://music.163.com/weapi/v1/artist/${query.id}`,
{},
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,19 @@
const realData =
'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=';
module.exports = (query, request) => {
query.cookie.os = 'pc';
const data = {
algorithmCode: 'shazam_v2',
times: 1,
sessionId: 'C999431ACDC84EDBB984763654E6F8D7',
duration: 3.3066249999999995,
from: 'recognize-song',
rawdata: realData,
};
return request('POST', `https://music.163.com/api/music/audio/match`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,27 @@
const uploadPlugin = require('../plugins/upload');
module.exports = async (query, request) => {
const uploadInfo = await uploadPlugin(query, request);
const res = await request(
'POST',
`https://music.163.com/weapi/user/avatar/upload/v1`,
{
imgid: uploadInfo.imgId,
},
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
return {
status: 200,
body: {
code: 200,
data: {
...uploadInfo,
...res.body,
},
},
};
};

@ -0,0 +1,17 @@
// 首页轮播图
module.exports = (query, request) => {
const type =
{
0: 'pc',
1: 'android',
2: 'iphone',
3: 'ipad',
}[query.type || 0] || 'pc';
return request(
'POST',
`https://music.163.com/api/v2/banner/get`,
{ clientType: type },
{ crypto: 'linuxapi', proxy: query.proxy, realIP: query.realIP },
);
};

@ -0,0 +1,19 @@
// 批量请求接口
module.exports = (query, request) => {
const data = {
e_r: true,
};
Object.keys(query).forEach((i) => {
if (/^\/api\//.test(i)) {
data[i] = query[i];
}
});
return request('POST', `https://music.163.com/eapi/batch`, data, {
crypto: 'eapi',
proxy: query.proxy,
url: '/api/batch',
cookie: query.cookie,
realIP: query.realIP,
});
};

@ -0,0 +1,12 @@
module.exports = (query, request) => {
const data = {
startTime: query.startTime || Date.now(),
endTime: query.endTime || Date.now(),
};
return request('POST', `https://music.163.com/api/mcalendar/detail`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,14 @@
// 发送验证码
module.exports = (query, request) => {
const data = {
ctcode: query.ctcode || '86',
cellphone: query.phone,
};
return request('POST', `https://music.163.com/weapi/sms/captcha/sent`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,20 @@
// 校验验证码
module.exports = (query, request) => {
const data = {
ctcode: query.ctcode || '86',
cellphone: query.phone,
captcha: query.captcha,
};
return request(
'POST',
`https://music.163.com/weapi/sms/captcha/verify`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,20 @@
// 检测手机号码是否已注册
module.exports = (query, request) => {
const data = {
cellphone: query.phone,
countrycode: query.countrycode,
};
return request(
'POST',
`https://music.163.com/eapi/cellphone/existence/check`,
data,
{
crypto: 'eapi',
cookie: query.cookie,
proxy: query.proxy,
url: '/api/cellphone/existence/check',
realIP: query.realIP,
},
);
};

@ -0,0 +1,34 @@
// 歌曲可用性
module.exports = (query, request) => {
const data = {
ids: '[' + parseInt(query.id) + ']',
br: parseInt(query.br || 999000),
};
return request(
'POST',
`https://music.163.com/weapi/song/enhance/player/url`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
).then((response) => {
let playable = false;
if (response.body.code == 200) {
if (response.body.data[0].code == 200) {
playable = true;
}
}
if (playable) {
response.body = { success: true, message: 'ok' };
return response;
} else {
response.status = 404;
response.body = { success: false, message: '亲爱的,暂无版权' };
return Promise.reject(response);
}
});
};

@ -0,0 +1,21 @@
// 搜索
module.exports = (query, request) => {
const data = {
s: query.keywords,
type: query.type || 1, // 1: 单曲, 10: 专辑, 100: 歌手, 1000: 歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频
limit: query.limit || 30,
offset: query.offset || 0,
};
return request(
'POST',
`https://music.163.com/weapi/cloudsearch/get/web`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,43 @@
// 发送与删除评论
module.exports = (query, request) => {
query.cookie.os = 'pc';
query.t = {
1: 'add',
0: 'delete',
2: 'reply',
}[query.t];
query.type = {
0: 'R_SO_4_', // 歌曲
1: 'R_MV_5_', // MV
2: 'A_PL_0_', // 歌单
3: 'R_AL_3_', // 专辑
4: 'A_DJ_1_', // 电台,
5: 'R_VI_62_', // 视频
6: 'A_EV_2_', // 动态
}[query.type];
const data = {
threadId: query.type + query.id,
};
if (query.type == 'A_EV_2_') {
data.threadId = query.threadId;
}
if (query.t == 'add') data.content = query.content;
else if (query.t == 'delete') data.commentId = query.commentId;
else if (query.t == 'reply') {
data.commentId = query.commentId;
data.content = query.content;
}
return request(
'POST',
`https://music.163.com/weapi/resource/comments/${query.t}`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,22 @@
// 专辑评论
module.exports = (query, request) => {
query.cookie.os = 'pc';
const data = {
rid: query.id,
limit: query.limit || 20,
offset: query.offset || 0,
beforeTime: query.before || 0,
};
return request(
'POST',
`https://music.163.com/weapi/v1/resource/comments/R_AL_3_${query.id}`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,22 @@
// 电台评论
module.exports = (query, request) => {
query.cookie.os = 'pc';
const data = {
rid: query.id,
limit: query.limit || 20,
offset: query.offset || 0,
beforeTime: query.before || 0,
};
return request(
'POST',
`https://music.163.com/weapi/v1/resource/comments/A_DJ_1_${query.id}`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,20 @@
// 获取动态评论
module.exports = (query, request) => {
const data = {
limit: query.limit || 20,
offset: query.offset || 0,
beforeTime: query.before || 0,
};
return request(
'POST',
`https://music.163.com/weapi/v1/resource/comments/${query.threadId}`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,27 @@
module.exports = (query, request) => {
query.type = {
0: 'R_SO_4_', // 歌曲
1: 'R_MV_5_', // MV
2: 'A_PL_0_', // 歌单
3: 'R_AL_3_', // 专辑
4: 'A_DJ_1_', // 电台,
5: 'R_VI_62_', // 视频
}[query.type];
const data = {
parentCommentId: query.parentCommentId,
threadId: query.type + query.id,
time: query.time || -1,
limit: query.limit || 20,
};
return request(
'POST',
`https://music.163.com/api/resource/comment/floor/get`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,30 @@
// 热门评论
module.exports = (query, request) => {
query.cookie.os = 'pc';
query.type = {
0: 'R_SO_4_', // 歌曲
1: 'R_MV_5_', // MV
2: 'A_PL_0_', // 歌单
3: 'R_AL_3_', // 专辑
4: 'A_DJ_1_', // 电台,
5: 'R_VI_62_', // 视频
}[query.type];
const data = {
rid: query.id,
limit: query.limit || 20,
offset: query.offset || 0,
beforeTime: query.before || 0,
};
return request(
'POST',
`https://music.163.com/weapi/v1/resource/hotcomments/${query.type}${query.id}`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,16 @@
// 云村热评
module.exports = (query, request) => {
const data = {};
return request(
'POST',
`https://music.163.com/api/comment/hotwall/list/get`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,33 @@
// 点赞与取消点赞评论
module.exports = (query, request) => {
query.cookie.os = 'pc';
query.t = query.t == 1 ? 'like' : 'unlike';
query.type = {
0: 'R_SO_4_', // 歌曲
1: 'R_MV_5_', // MV
2: 'A_PL_0_', // 歌单
3: 'R_AL_3_', // 专辑
4: 'A_DJ_1_', // 电台,
5: 'R_VI_62_', // 视频
6: 'A_EV_2_', // 动态
}[query.type];
const data = {
threadId: query.type + query.id,
commentId: query.cid,
};
if (query.type == 'A_EV_2_') {
data.threadId = query.threadId;
}
return request(
'POST',
`https://music.163.com/weapi/v1/comment/${query.t}`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,22 @@
// 歌曲评论
module.exports = (query, request) => {
query.cookie.os = 'pc';
const data = {
rid: query.id,
limit: query.limit || 20,
offset: query.offset || 0,
beforeTime: query.before || 0,
};
return request(
'POST',
`https://music.163.com/api/v1/resource/comments/R_SO_4_${query.id}`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,22 @@
// MV评论
module.exports = (query, request) => {
query.cookie.os = 'pc';
const data = {
rid: query.id,
limit: query.limit || 20,
offset: query.offset || 0,
beforeTime: query.before || 0,
};
return request(
'POST',
`https://music.163.com/weapi/v1/resource/comments/R_MV_5_${query.id}`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,38 @@
// 评论
module.exports = (query, request) => {
query.cookie.os = 'pc';
query.type = {
0: 'R_SO_4_', // 歌曲
1: 'R_MV_5_', // MV
2: 'A_PL_0_', // 歌单
3: 'R_AL_3_', // 专辑
4: 'A_DJ_1_', // 电台,
5: 'R_VI_62_', // 视频
6: 'A_EV_2_', // 动态
}[query.type];
const threadId = query.type + query.id;
const pageSize = query.pageSize || 20;
const pageNo = query.pageNo || 1;
const data = {
threadId: threadId, //'R_SO_4_863481066',
pageNo,
showInner: query.showInner || true,
pageSize,
cursor:
+query.sortType === 3 ? query.cursor || '0' : (pageNo - 1) * pageSize,
sortType: query.sortType || 1, //1:按推荐排序,2:按热度排序,3:按时间排序
};
return request(
'POST',
`https://music.163.com/api/v2/resource/comments`,
data,
{
crypto: 'eapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
url: '/api/v2/resource/comments',
},
);
};

@ -0,0 +1,22 @@
// 歌单评论
module.exports = (query, request) => {
query.cookie.os = 'pc';
const data = {
rid: query.id,
limit: query.limit || 20,
offset: query.offset || 0,
beforeTime: query.before || 0,
};
return request(
'POST',
`https://music.163.com/weapi/v1/resource/comments/A_PL_0_${query.id}`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,22 @@
// 视频评论
module.exports = (query, request) => {
query.cookie.os = 'pc';
const data = {
rid: query.id,
limit: query.limit || 20,
offset: query.offset || 0,
beforeTime: query.before || 0,
};
return request(
'POST',
`https://music.163.com/weapi/v1/resource/comments/R_VI_62_${query.id}`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,16 @@
// 国家编码列表
module.exports = (query, request) => {
const data = {};
return request(
'POST',
`https://interface3.music.163.com/eapi/lbs/countries/v1`,
data,
{
crypto: 'eapi',
cookie: query.cookie,
proxy: query.proxy,
url: '/api/lbs/countries/v1',
realIP: query.realIP,
},
);
};

@ -0,0 +1,20 @@
// 签到
/*
0为安卓端签到 3点经验, 1为网页签到,2点经验
签到成功 {'android': {'point': 3, 'code': 200}, 'web': {'point': 2, 'code': 200}}
重复签到 {'android': {'code': -2, 'msg': '重复签到'}, 'web': {'code': -2, 'msg': '重复签到'}}
未登录 {'android': {'code': 301}, 'web': {'code': 301}}
*/
module.exports = (query, request) => {
const data = {
type: query.type || 0,
};
return request('POST', `https://music.163.com/weapi/point/dailyTask`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,27 @@
// 购买数字专辑
module.exports = (query, request) => {
const data = {
business: 'Album',
paymentMethod: query.payment,
digitalResources: JSON.stringify([
{
business: 'Album',
resourceID: query.id,
quantity: query.quantity,
},
]),
from: 'web',
};
return request(
'POST',
`https://music.163.com/api/ordering/web/digital`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,20 @@
// 我的数字专辑
module.exports = (query, request) => {
const data = {
limit: query.limit || 30,
offset: query.offset || 0,
total: true,
};
return request(
'POST',
`https://music.163.com/api/digitalAlbum/purchased`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,17 @@
// 电台banner
module.exports = (query, request) => {
const data = {};
query.cookie.os = 'pc';
return request(
'POST',
`https://music.163.com/weapi/djradio/banner/get`,
{},
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,15 @@
// 电台非热门类型
module.exports = (query, request) => {
return request(
'POST',
`https://music.163.com/weapi/djradio/category/excludehot`,
{},
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,15 @@
// 电台推荐类型
module.exports = (query, request) => {
return request(
'POST',
`https://music.163.com/weapi/djradio/home/category/recommend`,
{},
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,15 @@
// 电台分类列表
module.exports = (query, request) => {
return request(
'POST',
`https://music.163.com/weapi/djradio/category/get`,
{},
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,13 @@
// 电台详情
module.exports = (query, request) => {
const data = {
id: query.rid,
};
return request('POST', `https://music.163.com/api/djradio/v2/get`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,14 @@
// 热门电台
module.exports = (query, request) => {
const data = {
limit: query.limit || 30,
offset: query.offset || 0,
};
return request('POST', `https://music.163.com/weapi/djradio/hot/v1`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,19 @@
// 付费电台
module.exports = (query, request) => {
const data = {
limit: query.limit || 30,
offset: query.offset || 0,
};
return request(
'POST',
`https://music.163.com/weapi/djradio/home/paygift/list?_nmclfl=1`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,17 @@
// 电台个性推荐
module.exports = (query, request) => {
return request(
'POST',
`https://music.163.com/api/djradio/personalize/rcmd`,
{
limit: query.limit || 6,
},
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,21 @@
// 电台节目列表
const { toBoolean } = require('../util');
module.exports = (query, request) => {
const data = {
radioId: query.rid,
limit: query.limit || 30,
offset: query.offset || 0,
asc: toBoolean(query.asc),
};
return request(
'POST',
`https://music.163.com/weapi/dj/program/byradio`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,13 @@
// 电台节目详情
module.exports = (query, request) => {
const data = {
id: query.id,
};
return request('POST', `https://music.163.com/api/dj/program/detail`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,14 @@
// 电台节目榜
module.exports = (query, request) => {
const data = {
limit: query.limit || 100,
offset: query.offset || 0,
};
return request('POST', `https://music.163.com/api/program/toplist/v1`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,18 @@
// 电台24小时节目榜
module.exports = (query, request) => {
const data = {
limit: query.limit || 100,
// 不支持 offset
};
return request(
'POST',
`https://music.163.com/api/djprogram/toplist/hours`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,15 @@
// 类别热门电台
module.exports = (query, request) => {
const data = {
cateId: query.cateId,
limit: query.limit || 30,
offset: query.offset || 0,
};
return request('POST', `https://music.163.com/api/djradio/hot`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,15 @@
// 精选电台
module.exports = (query, request) => {
return request(
'POST',
`https://music.163.com/weapi/djradio/recommend/v1`,
{},
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,41 @@
// 精选电台分类
/*
有声书 10001
知识技能 453050
商业财经 453051
人文历史 11
外语世界 13
亲子宝贝 14
创作|翻唱 2001
音乐故事 2
3D|电子 10002
相声曲艺 8
情感调频 3
美文读物 6
脱口秀 5
广播剧 7
二次元 3001
明星做主播 1
娱乐|影视 4
科技科学 453052
校园|教育 4001
旅途|城市 12
*/
module.exports = (query, request) => {
const data = {
cateId: query.type,
};
return request(
'POST',
`https://music.163.com/weapi/djradio/recommend`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,19 @@
// 订阅与取消电台
module.exports = (query, request) => {
query.t = query.t == 1 ? 'sub' : 'unsub';
const data = {
id: query.rid,
};
return request(
'POST',
`https://music.163.com/weapi/djradio/${query.t}`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,20 @@
// 订阅电台列表
module.exports = (query, request) => {
const data = {
limit: query.limit || 30,
offset: query.offset || 0,
total: true,
};
return request(
'POST',
`https://music.163.com/weapi/djradio/get/subed`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,16 @@
// 电台详情
module.exports = (query, request) => {
const data = {
time: query.time || '-1',
id: query.id,
limit: query.limit || '20',
total: 'true',
};
return request('POST', `https://music.163.com/api/djradio/subscriber`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,18 @@
// 电台今日优选
module.exports = (query, request) => {
const data = {
page: query.page || 0,
};
return request(
'POST',
`https://music.163.com/weapi/djradio/home/today/perfered`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,18 @@
// 新晋电台榜/热门电台榜
const typeMap = {
new: 0,
hot: 1,
};
module.exports = (query, request) => {
const data = {
limit: query.limit || 100,
offset: query.offset || 0,
type: typeMap[query.type || 'new'] || '0', //0为新晋,1为热门
};
return request('POST', `https://music.163.com/api/djradio/toplist`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,14 @@
// 电台24小时主播榜
module.exports = (query, request) => {
const data = {
limit: query.limit || 100,
// 不支持 offset
};
return request('POST', `https://music.163.com/api/dj/toplist/hours`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,18 @@
// 电台新人榜
module.exports = (query, request) => {
const data = {
limit: query.limit || 100,
offset: query.offset || 0,
};
return request(
'POST',
`https://music.163.com/api/dj/toplist/newcomer`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,18 @@
// 付费精品
module.exports = (query, request) => {
const data = {
limit: query.limit || 100,
// 不支持 offset
};
return request(
'POST',
`https://music.163.com/api/djradio/toplist/pay`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,14 @@
// 电台最热主播榜
module.exports = (query, request) => {
const data = {
limit: query.limit || 100,
// 不支持 offset
};
return request('POST', `https://music.163.com/api/dj/toplist/popular`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,14 @@
// 动态
module.exports = (query, request) => {
const data = {
pagesize: query.pagesize || 20,
lasttime: query.lasttime || -1,
};
return request('POST', `https://music.163.com/weapi/v1/event/get`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,13 @@
// 删除动态
module.exports = (query, request) => {
const data = {
id: query.evId,
};
return request('POST', `https://music.163.com/eapi/event/delete`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,16 @@
// 转发动态
module.exports = (query, request) => {
query.cookie.os = 'pc';
const data = {
forwards: query.forwards,
id: query.evId,
eventUserId: query.uid,
};
return request('POST', `https://music.163.com/weapi/event/forward`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,20 @@
// 垃圾桶
module.exports = (query, request) => {
const data = {
songId: query.id,
};
return request(
'POST',
`https://music.163.com/weapi/radio/trash/add?alg=RT&songId=${
query.id
}&time=${query.time || 25}`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,17 @@
// 关注与取消关注用户
module.exports = (query, request) => {
query.cookie.os = 'pc';
query.t = query.t == 1 ? 'follow' : 'delfollow';
return request(
'POST',
`https://music.163.com/weapi/user/${query.t}/${query.id}`,
{},
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,17 @@
// 历史每日推荐歌曲
module.exports = (query, request) => {
query.cookie.os = 'ios';
const data = {};
return request(
'POST',
`https://music.163.com/api/discovery/recommend/songs/history/recent`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,19 @@
// 历史每日推荐歌曲详情
module.exports = (query, request) => {
query.cookie.os = 'ios';
const data = {
date: query.date || '',
};
return request(
'POST',
`https://music.163.com/api/discovery/recommend/songs/history/detail`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,17 @@
// 首页-发现 block page
// 这个接口为移动端接口,首页-发现页,数据结构可以参考 https://github.com/hcanyz/flutter-netease-music-api/blob/master/lib/src/api/uncategorized/bean.dart#L259 HomeBlockPageWrap
// query.refresh 是否刷新数据
module.exports = (query, request) => {
const data = { refresh: query.refresh || true };
return request(
'POST',
`https://music.163.com/api/homepage/block/page`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,19 @@
// 首页-发现 dragon ball
// 这个接口为移动端接口,首页-发现页(每日推荐、歌单、排行榜 那些入口)
// 数据结构可以参考 https://github.com/hcanyz/flutter-netease-music-api/blob/master/lib/src/api/uncategorized/bean.dart#L290 HomeDragonBallWrap
// !需要登录或者匿名登录,非登录返回 []
module.exports = (query, request) => {
const data = {};
return request(
'POST',
`https://music.163.com/eapi/homepage/dragon/ball/static`,
data,
{
crypto: 'eapi',
cookie: query.cookie,
proxy: query.proxy,
url: '/api/homepage/dragon/ball/static',
realIP: query.realIP,
},
);
};

@ -0,0 +1,14 @@
//热门话题
module.exports = (query, request) => {
const data = {
limit: query.limit || 20,
offset: query.offset || 0,
};
return request('POST', `https://music.163.com/weapi/act/hot`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,23 @@
// 红心与取消红心歌曲
const { toBoolean } = require('../util');
module.exports = (query, request) => {
query.like = query.like == 'false' ? false : true;
const data = {
trackId: query.id,
like: query.like,
};
return request(
'POST',
`https://music.163.com/weapi/radio/like?alg=${
query.alg || 'itembased'
}&trackId=${query.id}&time=${query.time || 25}`,
data,
{
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,13 @@
// 喜欢的歌曲(无序)
module.exports = (query, request) => {
const data = {
uid: query.uid,
};
return request('POST', `https://music.163.com/weapi/song/like/get`, data, {
crypto: 'weapi',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
});
};

@ -0,0 +1,47 @@
// 邮箱登录
const crypto = require('crypto');
module.exports = async (query, request) => {
query.cookie.os = 'pc';
const data = {
username: query.email,
password:
query.md5_password ||
crypto.createHash('md5').update(query.password).digest('hex'),
rememberLogin: 'true',
};
let result = await request(
'POST',
`https://music.163.com/weapi/login`,
data,
{
crypto: 'weapi',
ua: 'pc',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
if (result.body.code === 502) {
return {
status: 200,
body: {
msg: '账号或密码错误',
code: 502,
message: '账号或密码错误',
},
};
}
if (result.body.code === 200) {
result = {
status: 200,
body: {
...result.body,
cookie: result.cookie.join(';'),
},
cookie: result.cookie,
};
}
return result;
};

@ -0,0 +1,39 @@
// 手机登录
const crypto = require('crypto');
module.exports = async (query, request) => {
query.cookie.os = 'pc';
const data = {
phone: query.phone,
countrycode: query.countrycode || '86',
password:
query.md5_password ||
crypto.createHash('md5').update(query.password).digest('hex'),
rememberLogin: 'true',
};
let result = await request(
'POST',
`https://music.163.com/weapi/login/cellphone`,
data,
{
crypto: 'weapi',
ua: 'pc',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
if (result.body.code === 200) {
result = {
status: 200,
body: {
...result.body,
cookie: result.cookie.join(';'),
},
cookie: result.cookie,
};
}
return result;
};

@ -0,0 +1,16 @@
// 登录刷新
module.exports = (query, request) => {
return request(
'POST',
`https://music.163.com/weapi/login/token/refresh`,
{},
{
crypto: 'weapi',
ua: 'pc',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

@ -0,0 +1,23 @@
// 登录状态
module.exports = (query, request) => {
return request(
'GET',
`https://music.163.com`,
{},
{ cookie: query.cookie, proxy: query.proxy, realIP: query.realIP },
).then((response) => {
try {
let profile = eval(`(${/GUser\s*=\s*([^;]+);/.exec(response.body)[1]})`);
let bindings = eval(
`(${/GBinds\s*=\s*([^;]+);/.exec(response.body)[1]})`,
);
response.body = { code: 200, profile: profile, bindings: bindings };
return response;
} catch (err) {
response.status = 301;
response.body = { code: 301 };
return Promise.reject(response);
}
});
};

@ -0,0 +1,16 @@
// 退出登录
module.exports = (query, request) => {
return request(
'POST',
`https://music.163.com/weapi/logout`,
{},
{
crypto: 'weapi',
ua: 'pc',
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
);
};

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

Loading…
Cancel
Save