feat: read, remove and clear listening history and switch recording over HTTP
This commit is contained in:
1 parent
112527db83
commit
17e486209e
14 files changed
+722
-18
No files matched your search
@@ -19,6 +19,7 @@ import (
|
||||
"github.com/dihemoe/alisten/internal/app/admin"
|
||||
"github.com/dihemoe/alisten/internal/app/catalog"
|
||||
"github.com/dihemoe/alisten/internal/app/identity"
|
||||
"github.com/dihemoe/alisten/internal/app/listen"
|
||||
"github.com/dihemoe/alisten/internal/app/lobby"
|
||||
"github.com/dihemoe/alisten/internal/app/media"
|
||||
"github.com/dihemoe/alisten/internal/app/playlist"
|
||||
@@ -52,6 +53,7 @@ type Services struct {
|
||||
Media *media.Library
|
||||
Playback *media.Playback
|
||||
Site *site.Service
|
||||
Listens *listen.Service
|
||||
|
||||
// 浏览器访问对象存储时使用的地址前缀,结尾没有 /。
|
||||
StorageURL string
|
||||
@@ -158,6 +160,11 @@ func New(s Services, metrics prometheus.Registerer, tracer trace.TracerProvider,
|
||||
srv.handle(mux, protocol.RouteAdminCloseRegistration, srv.adminCloseRegistration)
|
||||
srv.handle(mux, protocol.RouteAdminGetAccount, srv.adminGetAccount)
|
||||
srv.handle(mux, protocol.RouteAdminResetAccountPassword, srv.adminResetAccountPassword)
|
||||
srv.handle(mux, protocol.RouteListMyListens, srv.listMyListens)
|
||||
srv.handle(mux, protocol.RouteRemoveMyListen, srv.removeMyListen)
|
||||
srv.handle(mux, protocol.RouteClearMyListens, srv.clearMyListens)
|
||||
srv.handle(mux, protocol.RouteEnableListenRecording, srv.enableListenRecording)
|
||||
srv.handle(mux, protocol.RouteDisableListenRecording, srv.disableListenRecording)
|
||||
mux.HandleFunc("GET /ws", srv.websocket)
|
||||
mux.HandleFunc("GET /api/room/events", srv.roomEvents)
|
||||
mux.HandleFunc("GET /media/{source}/{id}", srv.redirectMedia)
|
||||
|
||||
@@ -42,6 +42,9 @@ func (s *server) getMe(ctx context.Context, c call) (any, error) {
|
||||
dto := accountDTO(account)
|
||||
resp.Account = &dto
|
||||
}
|
||||
if resp.RecordListens, err = s.Listens.Recording(ctx, c.member.ID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/dihemoe/alisten/protocol"
|
||||
)
|
||||
|
||||
func (s *server) listMyListens(ctx context.Context, c call) (any, error) {
|
||||
listens, err := s.Listens.List(ctx, c.member.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items := make([]protocol.MyListen, len(listens))
|
||||
for i, l := range listens {
|
||||
items[i] = protocol.MyListen{Track: trackDTO(l.Track), Meta: s.trackMeta(l.Meta), HeardAtMs: l.HeardAt.UnixMilli()}
|
||||
}
|
||||
return protocol.ListMyListensResponse{Items: items}, nil
|
||||
}
|
||||
|
||||
func (s *server) removeMyListen(ctx context.Context, c call) (any, error) {
|
||||
req, err := protocol.DecodeRemoveMyListenRequest(c.body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, s.Listens.Remove(ctx, c.member.ID, trackOf(req.Track))
|
||||
}
|
||||
|
||||
func (s *server) clearMyListens(ctx context.Context, c call) (any, error) {
|
||||
return nil, s.Listens.Clear(ctx, c.member.ID)
|
||||
}
|
||||
|
||||
func (s *server) enableListenRecording(ctx context.Context, c call) (any, error) {
|
||||
if _, err := protocol.DecodeEnableListenRecordingRequest(c.body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, s.Listens.SetRecording(ctx, c.member.ID, true)
|
||||
}
|
||||
|
||||
func (s *server) disableListenRecording(ctx context.Context, c call) (any, error) {
|
||||
return nil, s.Listens.SetRecording(ctx, c.member.ID, false)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package listen
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/dihemoe/alisten/internal/app/port"
|
||||
"github.com/dihemoe/alisten/internal/domain/track"
|
||||
)
|
||||
|
||||
// 游客和已注册成员都有播放历史,不像歌单要求注册。
|
||||
type Service struct {
|
||||
listens port.Listens
|
||||
}
|
||||
|
||||
func New(listens port.Listens) *Service {
|
||||
return &Service{listens: listens}
|
||||
}
|
||||
|
||||
func (s *Service) List(ctx context.Context, memberID string) ([]port.Listen, error) {
|
||||
return s.listens.MemberListens(ctx, memberID)
|
||||
}
|
||||
|
||||
// 链接曲目的 t.ID 必须已经按 track.LinkID 规范化。
|
||||
func (s *Service) Remove(ctx context.Context, memberID string, t track.Track) error {
|
||||
return s.listens.DeleteListen(ctx, memberID, t)
|
||||
}
|
||||
|
||||
func (s *Service) Clear(ctx context.Context, memberID string) error {
|
||||
return s.listens.ClearListens(ctx, memberID)
|
||||
}
|
||||
|
||||
func (s *Service) Recording(ctx context.Context, memberID string) (bool, error) {
|
||||
return s.listens.ListenRecording(ctx, memberID)
|
||||
}
|
||||
|
||||
func (s *Service) SetRecording(ctx context.Context, memberID string, on bool) error {
|
||||
return s.listens.SetListenRecording(ctx, memberID, on)
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"github.com/dihemoe/alisten/internal/app/admin"
|
||||
"github.com/dihemoe/alisten/internal/app/catalog"
|
||||
"github.com/dihemoe/alisten/internal/app/identity"
|
||||
"github.com/dihemoe/alisten/internal/app/listen"
|
||||
"github.com/dihemoe/alisten/internal/app/lobby"
|
||||
"github.com/dihemoe/alisten/internal/app/media"
|
||||
"github.com/dihemoe/alisten/internal/app/playlist"
|
||||
@@ -90,6 +91,7 @@ func newPublic(cfg serveConfig, pool *pgxpool.Pool, rdb *goredis.Client, instanc
|
||||
Media: media.NewLibrary(store, store, objects),
|
||||
Playback: media.NewPlayback(src.playback, store),
|
||||
Site: site.New(store),
|
||||
Listens: listen.New(store),
|
||||
|
||||
StorageURL: cfg.storageURL,
|
||||
}
|
||||
|
||||
+6
-6
@@ -22,7 +22,7 @@ GET /api/me
|
||||
Authorization: Bearer $alice
|
||||
-- response --
|
||||
200
|
||||
{"member": {"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}, "account": {"username": "alice"}}
|
||||
{"member": {"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}, "account": {"username": "alice"}, "recordListens": true}
|
||||
|
||||
-- request --
|
||||
PATCH /api/me
|
||||
@@ -38,7 +38,7 @@ GET /api/me
|
||||
Authorization: Bearer $alice
|
||||
-- response --
|
||||
200
|
||||
{"member": {"id": "$aliceId", "name": "$aliceName", "avatarHash": "c160f8cc69a4f0bf2b0362752353d060"}, "account": {"username": "alice", "email": "Alice@Example.COM"}}
|
||||
{"member": {"id": "$aliceId", "name": "$aliceName", "avatarHash": "c160f8cc69a4f0bf2b0362752353d060"}, "account": {"username": "alice", "email": "Alice@Example.COM"}, "recordListens": true}
|
||||
|
||||
-- request --
|
||||
POST /api/account
|
||||
@@ -62,7 +62,7 @@ GET /api/me
|
||||
Authorization: Bearer $bob
|
||||
-- response --
|
||||
200
|
||||
{"member": {"id": "$bobId", "name": "$bobName", "avatarHash": ""}}
|
||||
{"member": {"id": "$bobId", "name": "$bobName", "avatarHash": ""}, "recordListens": true}
|
||||
|
||||
-- request --
|
||||
PATCH /api/me
|
||||
@@ -78,7 +78,7 @@ GET /api/me
|
||||
Authorization: Bearer $bob
|
||||
-- response --
|
||||
200
|
||||
{"member": {"id": "$bobId", "name": "$bobName", "avatarHash": "c160f8cc69a4f0bf2b0362752353d060"}}
|
||||
{"member": {"id": "$bobId", "name": "$bobName", "avatarHash": "c160f8cc69a4f0bf2b0362752353d060"}, "recordListens": true}
|
||||
|
||||
-- request --
|
||||
PATCH /api/me
|
||||
@@ -139,7 +139,7 @@ GET /api/me
|
||||
Authorization: Bearer $alice2
|
||||
-- response --
|
||||
200
|
||||
{"member": {"id": "$aliceId", "name": "$aliceName", "avatarHash": "c160f8cc69a4f0bf2b0362752353d060"}, "account": {"username": "alice", "email": "Alice@Example.COM"}}
|
||||
{"member": {"id": "$aliceId", "name": "$aliceName", "avatarHash": "c160f8cc69a4f0bf2b0362752353d060"}, "account": {"username": "alice", "email": "Alice@Example.COM"}, "recordListens": true}
|
||||
|
||||
-- request --
|
||||
PATCH /api/me
|
||||
@@ -155,7 +155,7 @@ GET /api/me
|
||||
Authorization: Bearer $alice
|
||||
-- response --
|
||||
200
|
||||
{"member": {"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}, "account": {"username": "alice"}}
|
||||
{"member": {"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}, "account": {"username": "alice"}, "recordListens": true}
|
||||
|
||||
-- request --
|
||||
GET /api/me
|
||||
|
||||
+3
-3
@@ -21,7 +21,7 @@ GET /api/me
|
||||
Authorization: Bearer $alice
|
||||
-- response --
|
||||
200
|
||||
{"member": {"id": "$aliceId", "name": "$guestName", "avatarHash": ""}}
|
||||
{"member": {"id": "$aliceId", "name": "$guestName", "avatarHash": ""}, "recordListens": true}
|
||||
|
||||
-- request --
|
||||
PATCH /api/me
|
||||
@@ -73,11 +73,11 @@ GET /api/me
|
||||
Authorization: Bearer $alice
|
||||
-- response --
|
||||
200
|
||||
{"member": {"id": "$aliceId", "name": "甲", "avatarHash": ""}}
|
||||
{"member": {"id": "$aliceId", "name": "甲", "avatarHash": ""}, "recordListens": true}
|
||||
|
||||
-- request --
|
||||
GET /api/me
|
||||
Authorization: Bearer $bob
|
||||
-- response --
|
||||
200
|
||||
{"member": {"id": "$bobId", "name": "乙", "avatarHash": ""}}
|
||||
{"member": {"id": "$bobId", "name": "乙", "avatarHash": ""}, "recordListens": true}
|
||||
+249
@@ -0,0 +1,249 @@
|
||||
播放历史:开播时记给房间里的成员,开播之后进来的成员也记上正在播放的歌,关闭了记录的成员不记,已有的历史保留;
|
||||
可以删除一首、清空;游客登录账号时,游客的历史并入账号。读取历史要有成员 token。
|
||||
|
||||
-- request --
|
||||
POST /api/members
|
||||
|
||||
{}
|
||||
-- response --
|
||||
201
|
||||
{"memberToken": "$alice", "member": {"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}}
|
||||
|
||||
-- request --
|
||||
POST /api/account
|
||||
Authorization: Bearer $alice
|
||||
|
||||
{"username": "alice", "password": "correct horse"}
|
||||
-- response --
|
||||
201
|
||||
{"account": {"username": "alice"}}
|
||||
|
||||
-- request --
|
||||
GET /api/me/listens
|
||||
Authorization: Bearer $alice
|
||||
-- response --
|
||||
200
|
||||
{"items": []}
|
||||
|
||||
-- request --
|
||||
POST /api/members
|
||||
|
||||
{}
|
||||
-- response --
|
||||
201
|
||||
{"memberToken": "$bob", "member": {"id": "$bobId", "name": "$bobName", "avatarHash": ""}}
|
||||
|
||||
-- request --
|
||||
DELETE /api/me/listen-recording
|
||||
Authorization: Bearer $bob
|
||||
-- response --
|
||||
204
|
||||
|
||||
-- request --
|
||||
GET /api/me
|
||||
Authorization: Bearer $bob
|
||||
-- response --
|
||||
200
|
||||
{"member": {"id": "$bobId", "name": "$bobName", "avatarHash": ""}, "recordListens": false}
|
||||
|
||||
-- request --
|
||||
POST /api/admin/rooms
|
||||
Authorization: Bearer admin-secret
|
||||
|
||||
{"name": "大厅", "description": ""}
|
||||
-- response --
|
||||
201
|
||||
Location: /api/rooms/$room
|
||||
{"id": "$room"}
|
||||
|
||||
-- request --
|
||||
POST /api/rooms/$room/tickets
|
||||
Authorization: Bearer $alice
|
||||
|
||||
{}
|
||||
-- response --
|
||||
201
|
||||
{"ticket": "$ticketA"}
|
||||
|
||||
-- connect alice --
|
||||
-- send alice --
|
||||
{"kind": "request", "type": "hello", "id": "h1", "data": {"roomId": "$room", "ticket": "$ticketA", "protocolVersion": "$protocolVersion"}}
|
||||
-- receive alice --
|
||||
{"kind": "response", "type": "hello", "id": "h1", "data": {
|
||||
"member": {"id": "$aliceId", "name": "$aliceName", "avatarHash": ""},
|
||||
"serverTimeMs": 1,
|
||||
"room": {"term": 1, "seq": 1, "room": {"id": "$room", "name": "大厅", "description": "", "kind": "persistent"},
|
||||
"playMode": "sequential", "nowPlaying": null, "pending": null, "items": [],
|
||||
"members": {"sessions": [{"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}], "onlineCount": 1}}}}
|
||||
|
||||
-- send alice --
|
||||
{"kind": "request", "type": "queue.add", "id": "a1", "data": {"track": {"source": "netease", "id": "186016"}}}
|
||||
-- receive alice --
|
||||
{"kind": "event", "type": "room.activity", "term": 1, "seq": 2, "data": {"kind": "added", "member": {"id": "$aliceId", "name": "$aliceName", "avatarHash": ""},
|
||||
"entry": {"id": "1", "track": {"source": "netease", "id": "186016"}, "meta": {"title": "晴天", "artist": "周杰伦", "album": "叶惠美", "coverUrl": "https://p1.music.126.net/example.jpg", "pageUrl": "https://music.163.com/#/song?id=186016", "durationMs": 269000},
|
||||
"by": {"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}, "auto": false, "likes": 0, "status": "preparing"},
|
||||
"message": "点了《晴天》"}}
|
||||
-- receive alice --
|
||||
{"kind": "event", "type": "queue.updated", "term": 1, "seq": 3, "data": {"items": [],
|
||||
"pending": {"id": "1", "track": {"source": "netease", "id": "186016"}, "meta": {"title": "晴天", "artist": "周杰伦", "album": "叶惠美", "coverUrl": "https://p1.music.126.net/example.jpg", "pageUrl": "https://music.163.com/#/song?id=186016", "durationMs": 269000},
|
||||
"by": {"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}, "auto": false, "likes": 0, "status": "preparing"}}}
|
||||
-- receive alice --
|
||||
{"kind": "response", "type": "queue.add", "id": "a1", "data": {"entry": {"id": "1", "track": {"source": "netease", "id": "186016"},
|
||||
"meta": {"title": "晴天", "artist": "周杰伦", "album": "叶惠美", "coverUrl": "https://p1.music.126.net/example.jpg", "pageUrl": "https://music.163.com/#/song?id=186016", "durationMs": 269000},
|
||||
"by": {"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}, "auto": false, "likes": 0, "status": "preparing"}}}
|
||||
-- receive alice --
|
||||
{"kind": "event", "type": "queue.updated", "term": 1, "seq": 4, "data": {"pending": null, "items": []}}
|
||||
-- receive alice --
|
||||
{"kind": "event", "type": "playback.updated", "term": 1, "seq": 5, "data": {"nowPlaying": {
|
||||
"entry": {"id": "1", "track": {"source": "netease", "id": "186016"}, "meta": {"title": "晴天", "artist": "周杰伦", "album": "叶惠美", "coverUrl": "https://p1.music.126.net/example.jpg", "pageUrl": "https://music.163.com/#/song?id=186016", "durationMs": 269500},
|
||||
"by": {"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}, "auto": false, "likes": 0, "status": "ready"},
|
||||
"mediaUrl": "/media/netease/186016", "startedAtMs": 1, "durationMs": 269500, "gain": 1, "lyric": "[00:01.00]故事的小黄花"}}}
|
||||
|
||||
-- request --
|
||||
GET /api/me/listens
|
||||
Authorization: Bearer $alice
|
||||
-- response --
|
||||
200
|
||||
{"items": [{"track": {"source": "netease", "id": "186016"}, "meta": {"title": "晴天", "artist": "周杰伦", "album": "叶惠美", "coverUrl": "https://p1.music.126.net/example.jpg", "pageUrl": "https://music.163.com/#/song?id=186016", "durationMs": 269500}, "heardAtMs": 1}]}
|
||||
|
||||
-- request --
|
||||
POST /api/rooms/$room/tickets
|
||||
Authorization: Bearer $bob
|
||||
|
||||
{}
|
||||
-- response --
|
||||
201
|
||||
{"ticket": "$ticketB"}
|
||||
|
||||
-- connect bob --
|
||||
-- send bob --
|
||||
{"kind": "request", "type": "hello", "id": "h1", "data": {"roomId": "$room", "ticket": "$ticketB", "protocolVersion": "$protocolVersion"}}
|
||||
-- receive bob --
|
||||
{"kind": "response", "type": "hello", "id": "h1", "data": {
|
||||
"member": {"id": "$bobId", "name": "$bobName", "avatarHash": ""},
|
||||
"serverTimeMs": 1,
|
||||
"room": {"term": 1, "seq": 6, "room": {"id": "$room", "name": "大厅", "description": "", "kind": "persistent"},
|
||||
"playMode": "sequential", "pending": null, "items": [],
|
||||
"nowPlaying": {
|
||||
"entry": {"id": "1", "track": {"source": "netease", "id": "186016"}, "meta": {"title": "晴天", "artist": "周杰伦", "album": "叶惠美", "coverUrl": "https://p1.music.126.net/example.jpg", "pageUrl": "https://music.163.com/#/song?id=186016", "durationMs": 269500},
|
||||
"by": {"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}, "auto": false, "likes": 0, "status": "ready"},
|
||||
"mediaUrl": "/media/netease/186016", "startedAtMs": 1, "durationMs": 269500, "gain": 1, "lyric": "[00:01.00]故事的小黄花"},
|
||||
"members": {"sessions": [{"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}, {"id": "$bobId", "name": "$bobName", "avatarHash": ""}], "onlineCount": 2}}}}
|
||||
-- receive alice --
|
||||
{"kind": "event", "type": "members.updated", "term": 1, "seq": 6, "data": {
|
||||
"sessions": [{"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}, {"id": "$bobId", "name": "$bobName", "avatarHash": ""}], "onlineCount": 2}}
|
||||
|
||||
-- request --
|
||||
GET /api/me/listens
|
||||
Authorization: Bearer $bob
|
||||
-- response --
|
||||
200
|
||||
{"items": []}
|
||||
|
||||
-- request --
|
||||
PUT /api/me/listen-recording
|
||||
Authorization: Bearer $bob
|
||||
|
||||
{}
|
||||
-- response --
|
||||
204
|
||||
|
||||
-- request --
|
||||
GET /api/me
|
||||
Authorization: Bearer $bob
|
||||
-- response --
|
||||
200
|
||||
{"member": {"id": "$bobId", "name": "$bobName", "avatarHash": ""}, "recordListens": true}
|
||||
|
||||
-- disconnect bob --
|
||||
-- receive alice --
|
||||
{"kind": "event", "type": "members.updated", "term": 1, "seq": 7, "data": {
|
||||
"sessions": [{"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}], "onlineCount": 1}}
|
||||
|
||||
-- connect again --
|
||||
-- send again --
|
||||
{"kind": "request", "type": "hello", "id": "h1", "data": {"roomId": "$room", "ticket": "$ticketB", "protocolVersion": "$protocolVersion"}}
|
||||
-- receive again --
|
||||
{"kind": "response", "type": "hello", "id": "h1", "data": {
|
||||
"member": {"id": "$bobId", "name": "$bobName", "avatarHash": ""},
|
||||
"serverTimeMs": 1,
|
||||
"room": {"term": 1, "seq": 8, "room": {"id": "$room", "name": "大厅", "description": "", "kind": "persistent"},
|
||||
"playMode": "sequential", "pending": null, "items": [],
|
||||
"nowPlaying": {
|
||||
"entry": {"id": "1", "track": {"source": "netease", "id": "186016"}, "meta": {"title": "晴天", "artist": "周杰伦", "album": "叶惠美", "coverUrl": "https://p1.music.126.net/example.jpg", "pageUrl": "https://music.163.com/#/song?id=186016", "durationMs": 269500},
|
||||
"by": {"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}, "auto": false, "likes": 0, "status": "ready"},
|
||||
"mediaUrl": "/media/netease/186016", "startedAtMs": 1, "durationMs": 269500, "gain": 1, "lyric": "[00:01.00]故事的小黄花"},
|
||||
"members": {"sessions": [{"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}, {"id": "$bobId", "name": "$bobName", "avatarHash": ""}], "onlineCount": 2}}}}
|
||||
-- receive alice --
|
||||
{"kind": "event", "type": "members.updated", "term": 1, "seq": 8, "data": {
|
||||
"sessions": [{"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}, {"id": "$bobId", "name": "$bobName", "avatarHash": ""}], "onlineCount": 2}}
|
||||
|
||||
-- request --
|
||||
GET /api/me/listens
|
||||
Authorization: Bearer $bob
|
||||
-- response --
|
||||
200
|
||||
{"items": [{"track": {"source": "netease", "id": "186016"}, "meta": {"title": "晴天", "artist": "周杰伦", "album": "叶惠美", "coverUrl": "https://p1.music.126.net/example.jpg", "pageUrl": "https://music.163.com/#/song?id=186016", "durationMs": 269500}, "heardAtMs": 1}]}
|
||||
|
||||
-- request --
|
||||
POST /api/me/listens/removals
|
||||
Authorization: Bearer $alice
|
||||
|
||||
{"track": {"source": "netease", "id": "186016"}}
|
||||
-- response --
|
||||
204
|
||||
|
||||
-- request --
|
||||
POST /api/me/listens/removals
|
||||
Authorization: Bearer $alice
|
||||
|
||||
{"track": {"source": "qq", "id": "0039MnYb0qxYhV"}}
|
||||
-- response --
|
||||
204
|
||||
|
||||
-- request --
|
||||
GET /api/me/listens
|
||||
Authorization: Bearer $alice
|
||||
-- response --
|
||||
200
|
||||
{"items": []}
|
||||
|
||||
-- request --
|
||||
POST /api/sessions
|
||||
Authorization: Bearer $bob
|
||||
|
||||
{"username": "alice", "password": "correct horse"}
|
||||
-- response --
|
||||
201
|
||||
{"memberToken": "$alice2", "member": {"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}, "account": {"username": "alice"}, "device": "$bobDevice"}
|
||||
-- closed again --
|
||||
4401
|
||||
-- receive alice --
|
||||
{"kind": "event", "type": "members.updated", "term": 1, "seq": 9, "data": {
|
||||
"sessions": [{"id": "$aliceId", "name": "$aliceName", "avatarHash": ""}], "onlineCount": 1}}
|
||||
|
||||
-- request --
|
||||
GET /api/me/listens
|
||||
Authorization: Bearer $alice2
|
||||
-- response --
|
||||
200
|
||||
{"items": [{"track": {"source": "netease", "id": "186016"}, "meta": {"title": "晴天", "artist": "周杰伦", "album": "叶惠美", "coverUrl": "https://p1.music.126.net/example.jpg", "pageUrl": "https://music.163.com/#/song?id=186016", "durationMs": 269500}, "heardAtMs": 1}]}
|
||||
|
||||
-- request --
|
||||
DELETE /api/me/listens
|
||||
Authorization: Bearer $alice2
|
||||
-- response --
|
||||
204
|
||||
|
||||
-- request --
|
||||
GET /api/me/listens
|
||||
Authorization: Bearer $alice
|
||||
-- response --
|
||||
200
|
||||
{"items": []}
|
||||
|
||||
-- request --
|
||||
GET /api/me/listens
|
||||
-- response --
|
||||
401
|
||||
{"error": {"code": "UNAUTHORIZED", "message": "成员 token 无效"}}
|
||||
Reference in new issue
Block a user