From d5a244ce7f381ce043e3f19dfd3a33257245c8bb Mon Sep 17 00:00:00 2001 From: My-Responsitories <107370289+My-Responsitories@users.noreply.github.com> Date: Mon, 3 Mar 2025 09:23:19 +0000 Subject: [PATCH] update msg api (#375) --- lib/http/api.dart | 9 ++--- lib/http/constants.dart | 33 --------------- lib/http/msg.dart | 38 ++++++------------ lib/models/msg/msgfeed_sys_msg.dart | 24 ----------- .../msg_feed_top/sys_msg/controller.dart | 38 ++++++++---------- lib/utils/app_scheme.dart | 40 ++++++++++--------- lib/utils/utils.dart | 8 ++-- 7 files changed, 57 insertions(+), 133 deletions(-) diff --git a/lib/http/api.dart b/lib/http/api.dart index 9d86d9f0..cddd08b0 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -468,12 +468,9 @@ class Api { static const String msgFeedAt = '/x/msgfeed/at'; //https://api.bilibili.com/x/msgfeed/like?platform=web&build=0&mobi_app=web static const String msgFeedLike = '/x/msgfeed/like'; - //https://message.bilibili.com/x/sys-msg/query_user_notify?csrf=xxxx&csrf=xxxx&page_size=20&build=0&mobi_app=web - static const String msgSysUserNotify = - '${HttpString.messageBaseUrl}/x/sys-msg/query_user_notify'; - //https://message.bilibili.com/x/sys-msg/query_unified_notify?csrf=xxxx&csrf=xxxx&page_size=10&build=0&mobi_app=web - static const String msgSysUnifiedNotify = - '${HttpString.messageBaseUrl}/x/sys-msg/query_unified_notify'; + //https://message.bilibili.com/x/sys-msg/query_notify_list?page_size=20&cursor=xxx + static const String msgSysNotify = + '${HttpString.messageBaseUrl}/x/sys-msg/query_notify_list'; // 系统信息光标更新(已读标记) //https://message.bilibili.com/x/sys-msg/update_cursor?csrf=xxxx&csrf=xxxx&cursor=1705288500000000000&has_up=0&build=0&mobi_app=web diff --git a/lib/http/constants.dart b/lib/http/constants.dart index 03059ee2..325dd530 100644 --- a/lib/http/constants.dart +++ b/lib/http/constants.dart @@ -9,37 +9,4 @@ class HttpString { static const String dynamicShareBaseUrl = 'https://t.bilibili.com'; static const String spaceBaseUrl = 'https://space.bilibili.com'; static const String sponsorBlockBaseUrl = 'https://www.bsbsb.top'; - static const List validateStatusCodes = [ - 302, - 304, - 307, - 400, - 401, - 403, - 404, - 405, - 409, - 412, - 500, - 503, - 504, - 509, - 616, - 617, - 625, - 626, - 628, - 629, - 632, - 643, - 650, - 652, - 658, - 662, - 688, - 689, - 701, - 799, - 8888 - ]; } diff --git a/lib/http/msg.dart b/lib/http/msg.dart index 448d724f..818da833 100644 --- a/lib/http/msg.dart +++ b/lib/http/msg.dart @@ -16,6 +16,9 @@ class MsgHttp { var res = await Request().get(Api.msgFeedReply, queryParameters: { 'id': cursor == -1 ? null : cursor, 'reply_time': cursorTime == -1 ? null : cursorTime, + 'platform': 'android', + 'mobi_app': 'android', + 'build': '8350200', }); if (res.data['code'] == 0) { return { @@ -35,6 +38,9 @@ class MsgHttp { var res = await Request().get(Api.msgFeedAt, queryParameters: { 'id': cursor == -1 ? null : cursor, 'at_time': cursorTime == -1 ? null : cursorTime, + 'platform': 'android', + 'mobi_app': 'android', + 'build': '8350200', }); if (res.data['code'] == 0) { return { @@ -54,6 +60,9 @@ class MsgHttp { var res = await Request().get(Api.msgFeedLike, queryParameters: { 'id': cursor == -1 ? null : cursor, 'like_time': cursorTime == -1 ? null : cursorTime, + 'platform': 'android', + 'mobi_app': 'android', + 'build': '8350200', }); if (res.data['code'] == 0) { return { @@ -69,31 +78,10 @@ class MsgHttp { } } - static Future msgFeedSysUserNotify() async { - String csrf = await Request.getCsrf(); - var res = await Request().get(Api.msgSysUserNotify, queryParameters: { - 'csrf': csrf, - 'page_size': 20, - }); - if (res.data['code'] == 0) { - return { - 'status': true, - 'data': res.data['data'], - }; - } else { - return { - 'status': false, - 'date': [], - 'msg': res.data['message'], - }; - } - } - - static Future msgFeedSysUnifiedNotify() async { - String csrf = await Request.getCsrf(); - var res = await Request().get(Api.msgSysUnifiedNotify, queryParameters: { - 'csrf': csrf, - 'page_size': 10, + static Future msgFeedNotify({int cursor = -1, int pageSize = 20}) async { + var res = await Request().get(Api.msgSysNotify, queryParameters: { + 'cursor': cursor == -1 ? null : cursor, + 'page_size': pageSize, }); if (res.data['code'] == 0) { return { diff --git a/lib/models/msg/msgfeed_sys_msg.dart b/lib/models/msg/msgfeed_sys_msg.dart index 3af72e78..a8921542 100644 --- a/lib/models/msg/msgfeed_sys_msg.dart +++ b/lib/models/msg/msgfeed_sys_msg.dart @@ -1,27 +1,3 @@ -class MsgFeedSysMsg { - List? systemNotifyList; - - MsgFeedSysMsg({this.systemNotifyList}); - - MsgFeedSysMsg.fromJson(Map json) { - if (json['system_notify_list'] != null) { - systemNotifyList = []; - json['system_notify_list'].forEach((v) { - systemNotifyList!.add(SystemNotifyList.fromJson(v)); - }); - } - } - - Map toJson() { - final Map data = {}; - if (systemNotifyList != null) { - data['system_notify_list'] = - systemNotifyList!.map((v) => v.toJson()).toList(); - } - return data; - } -} - class SystemNotifyList { int? id; int? cursor; diff --git a/lib/pages/msg_feed_top/sys_msg/controller.dart b/lib/pages/msg_feed_top/sys_msg/controller.dart index c5b9f8cd..c06fe2b0 100644 --- a/lib/pages/msg_feed_top/sys_msg/controller.dart +++ b/lib/pages/msg_feed_top/sys_msg/controller.dart @@ -5,38 +5,33 @@ import 'package:PiliPlus/http/msg.dart'; import '../../../models/msg/msgfeed_sys_msg.dart'; class SysMsgController extends GetxController { + static const pageSize = 20; RxList msgFeedSysMsgList = [].obs; bool isLoading = false; int cursor = -1; - int cursorTime = -1; bool isEnd = false; Future queryMsgFeedSysMsg() async { if (isLoading) return; isLoading = true; - var resUserNotify = await MsgHttp.msgFeedSysUserNotify(); - var resUnifiedNotify = await MsgHttp.msgFeedSysUnifiedNotify(); + final res = await MsgHttp.msgFeedNotify(cursor: cursor, pageSize: pageSize); isLoading = false; - List systemNotifyList = []; - if (resUserNotify['status']) { - MsgFeedSysMsg data = MsgFeedSysMsg.fromJson(resUserNotify['data']); - if (data.systemNotifyList != null) { - systemNotifyList.addAll(data.systemNotifyList!); + if (res['status']) { + final data = (res['data'] as List) + .map((i) => SystemNotifyList.fromJson(i)) + .toList(); + isEnd = data.length + 1 < pageSize; // data.length会比pageSize小1 + if (data.isNotEmpty) { + if (cursor == -1) { + msgFeedSysMsgList.assignAll(data); + } else { + msgFeedSysMsgList.addAll(data); + } + cursor = data.last.cursor ?? -1; + msgSysUpdateCursor(msgFeedSysMsgList.first.cursor!); } - } - if (resUnifiedNotify['status']) { - MsgFeedSysMsg data = MsgFeedSysMsg.fromJson(resUnifiedNotify['data']); - if (data.systemNotifyList != null) { - systemNotifyList.addAll(data.systemNotifyList!); - } - } - if (systemNotifyList.isNotEmpty) { - systemNotifyList.sort((a, b) => b.cursor!.compareTo(a.cursor!)); - msgFeedSysMsgList.assignAll(systemNotifyList); - msgSysUpdateCursor(msgFeedSysMsgList.first.cursor!); } else { - SmartDialog.showToast( - "UserNotify: ${resUserNotify['msg']} UnifiedNotify: ${resUnifiedNotify['msg']}"); + SmartDialog.showToast(res['msg']); } } @@ -58,7 +53,6 @@ class SysMsgController extends GetxController { Future onRefresh() async { cursor = -1; - cursorTime = -1; queryMsgFeedSysMsg(); } diff --git a/lib/utils/app_scheme.dart b/lib/utils/app_scheme.dart index a8093851..e20791c6 100644 --- a/lib/utils/app_scheme.dart +++ b/lib/utils/app_scheme.dart @@ -16,6 +16,7 @@ import 'utils.dart'; class PiliScheme { static late AppLinks appLinks; static StreamSubscription? listener; + static final uriDigitRegExp = RegExp(r'/(\d+)'); static Future init() async { // Register our protocol only on Windows platform @@ -67,19 +68,19 @@ class PiliScheme { return true; case 'pgc': // bilibili://pgc/season/ep/123456?h5_awaken_params=random - String? id = RegExp(r'/(\d+)').firstMatch(path)?.group(1); + String? id = uriDigitRegExp.firstMatch(path)?.group(1); if (id != null) { bool isEp = path.contains('/ep/'); Utils.viewBangumi( - seasonId: isEp ? null : id, - epId: isEp ? id : null, - ); + seasonId: isEp ? null : id, + epId: isEp ? id : null, + progress: uri.queryParameters['start_progress']); return true; } return false; case 'space': // bilibili://space/12345678?frommodule=XX&h5awaken=random - String? mid = RegExp(r'/(\d+)').firstMatch(path)?.group(1); + String? mid = uriDigitRegExp.firstMatch(path)?.group(1); if (mid != null) { Utils.toDupNamed('/member?mid=$mid', off: off); return true; @@ -92,7 +93,7 @@ class PiliScheme { if (queryParameters['comment_root_id'] != null) { // to check // to video reply - String? oid = RegExp(r'/(\d+)').firstMatch(path)?.group(1); + String? oid = uriDigitRegExp.firstMatch(path)?.group(1); int? rpid = int.tryParse(queryParameters['comment_root_id']!); if (oid != null && rpid != null) { Get.to( @@ -132,7 +133,7 @@ class PiliScheme { // to video // bilibili://video/12345678?page=0&h5awaken=random - String? aid = RegExp(r'/(\d+)').firstMatch(path)?.group(1); + String? aid = uriDigitRegExp.firstMatch(path)?.group(1); String? bvid = RegExp(r'/(BV[a-z\d]{10})', caseSensitive: false) .firstMatch(path) ?.group(1); @@ -163,7 +164,7 @@ class PiliScheme { return false; case 'live': // bilibili://live/12345678?extra_jump_from=1&from=1&is_room_feed=1&h5awaken=random - String? roomId = RegExp(r'/(\d+)').firstMatch(path)?.group(1); + String? roomId = uriDigitRegExp.firstMatch(path)?.group(1); if (roomId != null) { Utils.toDupNamed('/liveRoom?roomid=$roomId', off: off); return true; @@ -172,7 +173,7 @@ class PiliScheme { case 'bangumi': // bilibili://bangumi/season/12345678?h5_awaken_params=random if (path.startsWith('/season')) { - String? seasonId = RegExp(r'/(\d+)').firstMatch(path)?.group(1); + String? seasonId = uriDigitRegExp.firstMatch(path)?.group(1); if (seasonId != null) { Utils.viewBangumi(seasonId: seasonId, epId: null); return true; @@ -195,7 +196,7 @@ class PiliScheme { return true; case 'article': // bilibili://article/40679479?jump_opus=1&jump_opus_type=1&opus_type=article&h5awaken=random - String? id = RegExp(r'/(\d+)').firstMatch(path)?.group(1); + String? id = uriDigitRegExp.firstMatch(path)?.group(1); if (id != null) { Utils.toDupNamed( '/htmlRender', @@ -256,7 +257,7 @@ class PiliScheme { final queryParameters = uri.queryParameters; final commentRootId = queryParameters['comment_root_id']; if (commentRootId != null) { - String? oid = RegExp(r'/(\d+)').firstMatch(path)?.group(1); + String? oid = uriDigitRegExp.firstMatch(path)?.group(1); int? rpid = int.tryParse(commentRootId); if (oid != null && rpid != null) { Get.to( @@ -296,7 +297,7 @@ class PiliScheme { } return false; case 'album': - String? rid = RegExp(r'/(\d+)').firstMatch(path)?.group(1); + String? rid = uriDigitRegExp.firstMatch(path)?.group(1); if (rid != null) { SmartDialog.showLoading(); dynamic res = await DynamicsHttp.dynamicDetail(rid: rid, type: 2); @@ -402,7 +403,7 @@ class PiliScheme { } if (host.contains('live.bilibili.com')) { - String? roomId = RegExp(r'/(\d+)').firstMatch(path)?.group(1); + String? roomId = uriDigitRegExp.firstMatch(path)?.group(1); if (roomId != null) { Utils.toDupNamed('/liveRoom?roomid=$roomId', off: off); return true; @@ -412,7 +413,7 @@ class PiliScheme { } if (host.contains('space.bilibili.com')) { - String? mid = RegExp(r'/(\d+)').firstMatch(path)?.group(1); + String? mid = uriDigitRegExp.firstMatch(path)?.group(1); if (mid != null) { Utils.toDupNamed('/member?mid=$mid', off: off); return true; @@ -448,15 +449,16 @@ class PiliScheme { launchURL(); return false; case 'bangumi': + // www.bilibili.com/bangumi/play/ep{eid}?start_progress={offset}&thumb_up_dm_id={dmid} debugPrint('番剧'); String? id = RegExp(r'(ss|ep)\d+').firstMatch(path)?.group(0); if (id != null) { bool isSeason = id.startsWith('ss'); id = id.substring(2); Utils.viewBangumi( - seasonId: isSeason ? id : null, - epId: isSeason ? null : id, - ); + seasonId: isSeason ? id : null, + epId: isSeason ? null : id, + progress: uri.queryParameters['start_progress']); return true; } launchURL(); @@ -498,7 +500,7 @@ class PiliScheme { return false; case 'space': debugPrint('个人空间'); - String? mid = RegExp(r'/(\d+)').firstMatch(path)?.group(1); + String? mid = uriDigitRegExp.firstMatch(path)?.group(1); if (mid != null) { Utils.toDupNamed( '/member?mid=$mid', @@ -524,7 +526,7 @@ class PiliScheme { } static Future _onPushDynDetail(path, off) async { - String? id = RegExp(r'/(\d+)').firstMatch(path)?.group(1); + String? id = uriDigitRegExp.firstMatch(path)?.group(1); if (id != null) { SmartDialog.showLoading(); dynamic res = await DynamicsHttp.dynamicDetail(id: id); diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 9bf4df0c..4ce3d63e 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -899,10 +899,8 @@ class Utils { return '${randomTraceId.toString()}:${randomTraceId.toString().substring(16, 32)}:0:0'; } - static void viewBangumi({ - dynamic seasonId, - dynamic epId, - }) async { + static void viewBangumi( + {dynamic seasonId, dynamic epId, dynamic progress}) async { try { SmartDialog.showLoading(msg: '资源获取中'); var result = await SearchHttp.bangumiInfo(seasonId: seasonId, epId: epId); @@ -934,6 +932,7 @@ class Utils { 'pic': item.cover, 'heroTag': Utils.makeHeroTag(item.cid), 'videoType': SearchType.video, + if (progress != null) 'progress': int.tryParse(progress) }, preventDuplicates: false, ); @@ -963,6 +962,7 @@ class Utils { 'heroTag': Utils.makeHeroTag(episode.cid), 'videoType': SearchType.media_bangumi, 'bangumiItem': data, + if (progress != null) 'progress': int.tryParse(progress) }, preventDuplicates: false, );