From 6f85779152362cefa215f9e6dfbd6a46348974fb Mon Sep 17 00:00:00 2001
From: binaryify
Date: Fri, 14 Apr 2017 16:54:20 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=A7=81=E4=BA=BA=20FM,=20?=
=?UTF-8?q?=E5=96=9C=E6=AC=A2=E6=AD=8C=E6=9B=B2,=E5=9E=83=E5=9C=BE?=
=?UTF-8?q?=E6=A1=B6,=E6=AF=8F=E6=97=A5=E7=AD=BE=E5=88=B0=E7=AD=89?=
=?UTF-8?q?=E6=8E=A5=E5=8F=A3,=E6=9B=B4=E6=96=B0=E6=96=87=E6=A1=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
CHANGELOG.MD | 4 +-
README.MD | 21 +++++++++
app.js | 15 +++++++
docs/README.md | 93 ++++++++++++++++++++++++++++++++++++++-
router/daily_signin.js | 29 ++++++++++++
router/fm_trash.js | 26 +++++++++++
router/like.js | 27 ++++++++++++
router/personal_fm.js | 24 ++++++++++
static/fm_trash.png | Bin 0 -> 200911 bytes
static/like.png | Bin 0 -> 201651 bytes
static/likeSuccess.png | Bin 0 -> 27518 bytes
static/personal_fm.png | Bin 0 -> 406884 bytes
static/signinError.png | Bin 0 -> 161052 bytes
static/signinSuccess.png | Bin 0 -> 173012 bytes
14 files changed, 236 insertions(+), 3 deletions(-)
create mode 100644 router/daily_signin.js
create mode 100644 router/fm_trash.js
create mode 100644 router/like.js
create mode 100644 router/personal_fm.js
create mode 100644 static/fm_trash.png
create mode 100644 static/like.png
create mode 100644 static/likeSuccess.png
create mode 100644 static/personal_fm.png
create mode 100644 static/signinError.png
create mode 100644 static/signinSuccess.png
diff --git a/CHANGELOG.MD b/CHANGELOG.MD
index ad4963f..aea5ef4 100644
--- a/CHANGELOG.MD
+++ b/CHANGELOG.MD
@@ -1,8 +1,10 @@
# 更新日志
+### 2.2.0 |2017.4.14
+增加私人 FM, 喜欢歌曲,垃圾桶,每日签到等接口,更新文档
+
## 2.1.3 | 2017.4.6
改善文档
-
## 2.1.0 | 2017.4.6
增加获取评论接口以及对应单元测试,增加更新日志
diff --git a/README.MD b/README.MD
index 8e46c5d..f071f27 100644
--- a/README.MD
+++ b/README.MD
@@ -8,14 +8,35 @@
+## 灵感来自
+[disoul/electron-cloud-music](https://github.com/disoul/electron-cloud-music)
+
+[darknessomi/musicbox](https://github.com/darknessomi/musicbox)
## 版本新特性
+### 2.2.0 |2017.4.14
+增加私人 FM, 喜欢歌曲,垃圾桶,每日签到等接口,更新文档
+
### 2.1.0 | 2017.4.6
增加获取评论接口以及对应单元测试,增加更新日志
### 2.0.0 | 2017.4.1
版本升级到 2.0.增加使用文档,完成项目重构,增加更完善的单元测试,升级 api 到 v2+,支持登录并获取用户信息和创建的歌单,可通过获取音乐 url 接口获取用户歌单里的的音乐,获取每日推荐歌单和每日推荐音乐
+## 功能特性
+1. 登录
+2. 获取用户歌单
+3. 获取歌曲详情
+4. 获取音乐 url
+5. 搜索音乐
+6. 获取歌词
+7. 获取评论
+8. 获取歌手专辑
+9. 获取每日推荐歌单
+10. 获取每日推荐歌曲
+11. 喜欢歌曲
+12. 私人FM
+13. 把私人 FM 的歌曲移动至垃圾桶
## 环境要求
需要 NodeJS 6.0+ 环境
diff --git a/app.js b/app.js
index 4f13593..697d89a 100644
--- a/app.js
+++ b/app.js
@@ -27,14 +27,29 @@ app.use('/user/playlist', require('./router/userPlaylist'))
// 获取歌单内列表
app.use('/playlist/detail', require('./router/playlistDetail'))
+//不明 api
app.use('/playlist/tracks', require('./router/playlistTracks'))
+
// 获取音乐 url
app.use('/music/url', require('./router/musicUrl'))
+
// 搜歌
app.use('/search', require('.//router/search'))
app.use('/log/web', require('./router/logWeb'))
+// 私人 FM
+app.use("/personal_fm",require("./router/personal_fm"))
+
+// 喜欢歌曲
+app.use("/like",require("./router/like"))
+
+//签到
+app.use("/daily_signin",require("./router/daily_signin"))
+
+//垃圾桶
+app.use("/fm_trash",require("./router/fm_trash"))
+
process.on('SIGHUP', () => {
console.log('server: bye bye')
process.exit()
diff --git a/docs/README.md b/docs/README.md
index 6d5da89..efb4443 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -4,7 +4,24 @@
## 版本新特性
-版本升级到 2.0 .增加使用文档,完成项目重构,增加更完善的单元测试,升级 api 到 v2+,支持登录并获取用户信息和创建的歌单,可通过获取音乐 url 接口获取用户歌单里的的音乐,获取每日推荐歌单和每日推荐音乐
+Version 2.2.0
+新增喜欢歌曲,私人 FM, 垃圾桶,签到等接口
+
+## 功能特性
+1. 登录
+2. 获取用户歌单
+3. 获取歌曲详情
+4. 获取音乐 url
+5. 搜索音乐
+6. 获取歌词
+7. 获取评论
+8. 获取歌手专辑
+9. 获取每日推荐歌单
+10. 获取每日推荐歌曲
+11. 喜欢歌曲
+12. 私人FM
+13. 把私人 FM 的歌曲移动至垃圾桶
+14. 签到
## 安装
``` shell
@@ -51,7 +68,7 @@ $ node app.js
![登录](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/%E7%99%BB%E5%BD%95.png)
-完成登录后,会在浏览器保存一个 cookie 用作登录凭证, 除了搜索的音乐和歌词,以及获取音乐 url 都需要用到这个 cookie
+完成登录后,会在浏览器保存一个 Cookies 用作登录凭证,大部分 API 都需要用到这个 Cookies
#### 注意
调用登录接口的速度比调用其他接口慢,因为登录过程调用了加密算法
@@ -204,6 +221,78 @@ $ node app.js
返回数据如下图:
![搜索音乐](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/%E6%8E%A8%E8%8D%90%E6%AD%8C%E6%9B%B2.png)
+
+### 私人 FM
+说明:私人 FM( 需要登录)
+
+**接口地址:**
+`/personal_fm`
+
+**调用例子:**
+`/personal_fm`
+
+返回数据如下图:
+
+![私人 FM](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/personal_fm.png)
+
+### 签到
+说明:调用此接口,传入签到类型(可不传,默认安卓端签到),可签到(需要登录),其中安卓端签到可获得3点经验, web/PC 端签到可获得2点经验
+**可选参数:**
+`type`: 签到类型,默认 0, 其中 0 为安卓端签到,1为 web/PC 签到
+
+**接口地址:**
+`/daily_signin`
+
+**调用例子:**
+`/daily_signin`
+
+返回数据如下图:
+
+![签到成功](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/signinSuccess)
+
+![签到失败](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/signinError.png)
+
+
+### 喜欢音乐
+说明:调用此接口,传入音乐 id, 可喜欢该音乐
+**必选参数:**
+` id`: 歌曲 id
+
+**可选参数:**
+` like`: 布尔值,默认为 true 即喜欢,若传 false, 则取消喜欢
+
+**接口地址:**
+`/like`
+
+**调用例子:**
+`/like?id=347230`
+
+返回数据如下图:
+
+![喜欢成功](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/like.png)
+
+![喜欢成功截图](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/likeSuccess.png)
+
+喜欢成功则返回数据的 code 为200,其余为失败
+
+### 垃圾桶
+说明:调用此接口,传入音乐 id, 可把该音乐从私人 FM中移除至垃圾桶
+
+**必选参数:**
+` id`: 歌曲 id
+
+**接口地址:**
+`/fm_trash`
+
+**调用例子:**
+`/fm_trash?id=347230`
+
+返回数据如下图:
+
+![移除成功](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/fm_trash.png)
+
+
+
## 离线访问此文档
此文档同时也是 Progressive Web Apps(PWA), 加入了serviceWorker,可离线访问
diff --git a/router/daily_signin.js b/router/daily_signin.js
new file mode 100644
index 0000000..1027b04
--- /dev/null
+++ b/router/daily_signin.js
@@ -0,0 +1,29 @@
+const express = require("express")
+const router = express()
+const { createWebAPIRequest } = require("../util/util")
+
+router.get("/", (req, res) => {
+ const cookie = req.get('Cookie') ? req.get('Cookie') : ''
+ const data = {
+ "csrf_token": ""
+ }
+ // {'android': {'point': 3, 'code': 200}, 'web': {'point': 2, 'code': 200}}
+ // {'android': {'code': -2, 'msg': '重复签到'}, 'web': {'code': -2, 'msg': '重复签到'}}
+ // 'android': {'code': 301}, 'web': {'code': 301}}
+
+ let type = req.query.type || 0 //0为安卓端签到 3点经验,1为网页签到,2点经验
+ const action = `http://music.163.com/weapi/point/dailyTask?type=${type}`
+ createWebAPIRequest(
+ 'music.163.com',
+ action,
+ 'POST',
+ data,
+ cookie,
+ music_req => res.send(music_req),
+ err => res.status(502).send('fetch error')
+ )
+})
+
+
+
+module.exports = router
\ No newline at end of file
diff --git a/router/fm_trash.js b/router/fm_trash.js
new file mode 100644
index 0000000..602fe14
--- /dev/null
+++ b/router/fm_trash.js
@@ -0,0 +1,26 @@
+const express = require("express")
+const router = express()
+const { createWebAPIRequest } = require("../util/util")
+
+router.get("/", (req, res) => {
+ const cookie = req.get('Cookie') ? req.get('Cookie') : ''
+ const data = {
+ "csrf_token": ""
+ }
+ const songid = req.query.id
+ const alg = "RT"
+ const time = req.query.time || 25
+ createWebAPIRequest(
+ 'music.163.com',
+ `http://music.163.com/api/radio/trash/add?alg=${alg}&songId=${songid}&time=${time}`,
+ 'POST',
+ data,
+ cookie,
+ music_req => res.send(music_req),
+ err => res.status(502).send('fetch error')
+ )
+})
+
+
+
+module.exports = router
\ No newline at end of file
diff --git a/router/like.js b/router/like.js
new file mode 100644
index 0000000..cc5cd9b
--- /dev/null
+++ b/router/like.js
@@ -0,0 +1,27 @@
+const express = require("express")
+const router = express()
+const { createWebAPIRequest } = require("../util/util")
+
+router.get("/", (req, res) => {
+ const cookie = req.get('Cookie') ? req.get('Cookie') : ''
+ const data = {
+ "csrf_token": ""
+ }
+ const trackId = req.query.id
+ const like = req.query.like || true
+ const alg = "itembased"
+ const time = req.query.time || 25
+ createWebAPIRequest(
+ 'music.163.com',
+ `http://music.163.com/api/radio/like?alg=${alg}&trackId=${trackId}&like=${like}&time=${time}`,
+ 'POST',
+ data,
+ cookie,
+ music_req => res.send(music_req),
+ err => res.status(502).send('fetch error')
+ )
+})
+
+
+
+module.exports = router
\ No newline at end of file
diff --git a/router/personal_fm.js b/router/personal_fm.js
new file mode 100644
index 0000000..4439e2f
--- /dev/null
+++ b/router/personal_fm.js
@@ -0,0 +1,24 @@
+const express = require("express")
+const router = express()
+const { createWebAPIRequest } = require("../util/util")
+
+router.get("/", (req, res) => {
+ const cookie = req.get('Cookie') ? req.get('Cookie') : ''
+ const data = {
+ "csrf_token": ""
+ }
+
+ createWebAPIRequest(
+ 'music.163.com',
+ 'http://music.163.com/api/radio/get',
+ 'POST',
+ data,
+ cookie,
+ music_req => res.send(music_req),
+ err => res.status(502).send('fetch error')
+ )
+})
+
+
+
+module.exports = router
\ No newline at end of file
diff --git a/static/fm_trash.png b/static/fm_trash.png
new file mode 100644
index 0000000000000000000000000000000000000000..64dff51b70daa1285bb2f34d5198ef25a9ea71dd
GIT binary patch
literal 200911
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