refactor: message listeners (#447)

* Refactor API imports and update API endpoints

* Fix variable naming in FavoritesPop and Favorites components

* Fix variable naming inconsistency in getHistoryList function

* Fix API parameter naming conventions

* Refactor API_AUTH afterHandle functions

* Add API documentation links  and add function to be the api item

* Refactor API body and params

* Remove unused getAccessKey function in auth.ts

---------

Co-authored-by: pengyunfei <pengyunfei@360.cn>
Co-authored-by: Hakadao <a578457889743@gmail.com>
This commit is contained in:
cloudflypeng
2024-04-02 00:41:58 +08:00
committed by GitHub
parent 41a463dbaf
commit 433a2ed4cf
22 changed files with 509 additions and 538 deletions

View File

@@ -1,7 +1,8 @@
import type { APIMAP, _FETCH } from '../utils'
import type { APIMAP } from '../utils'
import { AHS } from '../utils'
const API_ANIME: APIMAP = {
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/36e250090800793b41b223b55eefdcbb9391b53e/user/space.md#%E6%9F%A5%E8%AF%A2%E7%94%A8%E6%88%B7%E8%BF%BD%E7%95%AA%E8%BF%BD%E5%89%A7%E6%98%8E%E7%BB%86
getPopularAnimeList: {
url: 'https://api.bilibili.com/pgc/web/rank/list',
_fetch: {

View File

@@ -1,70 +1,59 @@
import browser from 'webextension-polyfill'
// 由于 sendResponse 复杂, 所以使用自定义的函数
import type { APIMAP } from '../utils'
import { AHS } from '../utils'
function handleMessage(message: any, sender: any, sendResponse: any) {
if (message.contentScriptQuery === 'getAccessKey') {
const url = message.confirmUri
fetch(url)
.then(response => sendResponse({ accessKey: `${response.url}`.match(/access_key=([0-9a-z]{32})/)![1] }))
.catch(error => console.error(error))
return true
}
else if (message.contentScriptQuery === 'logout') {
const url = `https://passport.bilibili.com/login/exit/v2?biliCSRF=${message.biliCSRF}`
fetch(url, {
method: 'POST',
body: JSON.stringify({
biliCSRF: message.biliJct,
}),
})
.then(response => response.json())
.then(data => sendResponse(data))
.catch(error => console.error(error))
}
else if (message.contentScriptQuery === 'getLoginQRCode') {
const url = 'https://passport.bilibili.com/x/passport-tv-login/qrcode/auth_code'
fetch(url, {
const API_AUTH: APIMAP = {
// biliJct 似乎没有使用
logout: {
url: 'https://passport.bilibili.com/login/exit/v2',
_fetch: {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
body: new URLSearchParams({
appkey: '4409e2ce8ffd12b8',
local_id: '0',
ts: '0',
sign: 'e134154ed6add881d28fbdf68653cd9c',
}),
})
.then(response => response.json())
.then(data => sendResponse(data))
.catch(error => console.error(error))
}
else if (message.contentScriptQuery === 'qrCodeLogin') {
const url = 'https://passport.bilibili.com/x/passport-tv-login/qrcode/auth_code'
fetch(url, {
method: 'POST',
body: {
biliCSRF: '',
// biliJct: '',
},
},
params: {
biliCSRF: '',
},
afterHandle: AHS.J_S,
},
getLoginQRCode: {
url: 'https://passport.bilibili.com/x/passport-tv-login/qrcode/auth_code',
_fetch: {
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
body: new URLSearchParams({
appkey: '4409e2ce8ffd12b8',
auth_code: message.authCode,
local_id: '0',
ts: '0',
sign: 'e134154ed6add881d28fbdf68653cd9c',
}),
})
.then(response => response.json())
.then(data => sendResponse(data))
.catch(error => console.error(error))
}
},
params: {
appkey: '4409e2ce8ffd12b8',
local_id: '0',
ts: '0',
sign: 'e134154ed6add881d28fbdf68653cd9c',
},
afterHandle: AHS.J_S,
},
qrCodeLogin: {
url: 'https://passport.bilibili.com/x/passport-tv-login/qrcode/auth_code',
_fetch: {
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
},
params: {
appkey: '4409e2ce8ffd12b8',
auth_code: '',
local_id: '0',
ts: '0',
sign: 'e134154ed6add881d28fbdf68653cd9c',
},
afterHandle: AHS.J_S,
},
}
function handleConnect() {
browser.runtime.onMessage.removeListener(handleMessage)
browser.runtime.onMessage.addListener(handleMessage)
}
export function setupAuthMsgLstnr() {
browser.runtime.onConnect.removeListener(handleConnect)
browser.runtime.onConnect.addListener(handleConnect)
}
export default API_AUTH

View File

@@ -1,48 +1,49 @@
import browser from 'webextension-polyfill'
import type { APIMAP } from '../utils'
import { AHS } from '../utils'
function handleMessage(message: any) {
const API_FAVORITE: APIMAP = {
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/fav/info.md#%E8%8E%B7%E5%8F%96%E6%8C%87%E5%AE%9A%E7%94%A8%E6%88%B7%E5%88%9B%E5%BB%BA%E7%9A%84%E6%89%80%E6%9C%89%E6%94%B6%E8%97%8F%E5%A4%B9%E4%BF%A1%E6%81%AF
if (message.contentScriptQuery === 'getFavoriteCategories') {
const url = `https://api.bilibili.com/x/v3/fav/folder/created/list-all?up_mid=${message.mid}&jsonp=jsonp`
return fetch(url)
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error))
}
getFavoriteCategories: {
url: 'https://api.bilibili.com/x/v3/fav/folder/created/list-all',
_fetch: {
method: 'get',
},
params: {
up_mid: '',
},
afterHandle: AHS.J_D,
},
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/fav/list.md#%E8%8E%B7%E5%8F%96%E6%94%B6%E8%97%8F%E5%A4%B9%E5%86%85%E5%AE%B9%E6%98%8E%E7%BB%86%E5%88%97%E8%A1%A8
else if (message.contentScriptQuery === 'getFavoriteResources') {
const url = `https://api.bilibili.com/x/v3/fav/resource/list?media_id=${message.mediaId}&pn=${message.pageNum}&ps=20&keyword=${message.keyword}&order=mtime&type=0&tid=0&platform=web&jsonp=jsonp`
return fetch(url)
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error))
}
getFavoriteResources: {
url: 'https://api.bilibili.com/x/v3/fav/resource/list',
_fetch: {
method: 'get',
},
params: {
media_id: '',
pn: 1,
ps: 20,
keyword: '',
order: 'mtime',
type: 0,
tid: 0,
platform: 'web',
},
afterHandle: AHS.J_D,
},
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/fav/action.md#%E6%89%B9%E9%87%8F%E5%88%A0%E9%99%A4%E5%86%85%E5%AE%B9
else if (message.contentScriptQuery === 'patchDelFavoriteResources') {
const url = 'https://api.bilibili.com/x/v3/fav/resource/batch-del'
return fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
body: new URLSearchParams({
resources: message.resources,
media_id: message.mediaId,
csrf: message.csrf,
}),
})
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error))
}
patchDelFavoriteResources: {
url: 'https://api.bilibili.com/x/v3/fav/resource/batch-del',
_fetch: {
method: 'post',
},
params: {
resources: '',
media_id: '',
csrf: '',
},
afterHandle: AHS.J_D,
},
}
function handleConnect() {
browser.runtime.onMessage.removeListener(handleMessage)
browser.runtime.onMessage.addListener(handleMessage)
}
export function setupFavoriteMsgLstnr() {
browser.runtime.onConnect.removeListener(handleConnect)
browser.runtime.onConnect.addListener(handleConnect)
}
export default API_FAVORITE

View File

@@ -1,4 +1,4 @@
import type { APIMAP, _FETCH } from '../utils'
import type { APIMAP } from '../utils'
import { AHS } from '../utils'
const API_HISTORY: APIMAP = {
@@ -35,10 +35,10 @@ const API_HISTORY: APIMAP = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
},
params: {
kid: '',
csrf: '',
body: {
aid: '',
csrf: '',
},
},
afterHandle: AHS.J_D,
},
@@ -47,9 +47,12 @@ const API_HISTORY: APIMAP = {
url: 'https://api.bilibili.com/x/v2/history/clear',
_fetch: {
method: 'post',
},
params: {
csrf: '',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
body: {
csrf: '',
},
},
afterHandle: AHS.J_D,
},
@@ -67,10 +70,13 @@ const API_HISTORY: APIMAP = {
url: 'https://api.bilibili.com/x/v2/history/shadow/set',
_fetch: {
method: 'post',
},
params: {
switch: '',
csrf: '',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
body: {
switch: '',
csrf: '',
},
},
afterHandle: AHS.J_D,
},

View File

@@ -1,33 +1,22 @@
import browser from 'webextension-polyfill'
import { apiListenerFactory } from '../utils'
import API_AUTH from './auth'
import API_ANIME from './anime'
import { setupAuthMsgLstnr } from './auth'
import { setupVideoMsgLstnr } from './video'
import { setupUserMsgLstnr } from './user'
import { setupSearchMsgLstnr } from './search'
import { setupNotificationMsgLstnr } from './notification'
import { setupMomentMsgLstnr } from './moment'
import API_HISTORY from './history'
import { setupFavoriteMsgLstnr } from './favorite'
import { setupWatchLaterMsgLstnr } from './watchLater'
import { setupRankingMsgLstnr } from './ranking'
import API_FAVORITE from './favorite'
import API_MOMENT from './moment'
import API_NOTIFICATION from './notification'
import API_RANKING from './ranking'
import API_SEARCH from './search'
import API_USER from './user'
import API_VIDEO from './video'
import API_WATCHLATER from './watchLater'
export function setupAllMsgLstnrs() {
setupAuthMsgLstnr()
setupVideoMsgLstnr()
setupUserMsgLstnr()
setupSearchMsgLstnr()
setupNotificationMsgLstnr()
setupMomentMsgLstnr()
setupFavoriteMsgLstnr()
setupWatchLaterMsgLstnr()
setupRankingMsgLstnr()
// 上面的会全部删除, 每个文件只保留定义API 的对象, 在这里进行mixin
// 然后整个开始监听
const FullAPI = Object.assign({}, API_ANIME, API_HISTORY)
// Merge all API objects into one
const FullAPI = Object.assign({}, API_AUTH, API_ANIME, API_HISTORY, API_FAVORITE, API_MOMENT, API_NOTIFICATION, API_RANKING, API_SEARCH, API_USER, API_VIDEO, API_WATCHLATER)
// Create a message listener for each API
const handleMessage = apiListenerFactory(FullAPI)
browser.runtime.onMessage.removeListener(handleMessage)
browser.runtime.onMessage.addListener(handleMessage)

View File

@@ -1,74 +1,62 @@
import browser from 'webextension-polyfill'
import type { APIMAP } from '../utils'
import { AHS } from '../utils'
function handleMessage(message: any) {
if (message.contentScriptQuery === 'getTopBarNewMomentsCount') {
const url = 'https://api.bilibili.com/x/web-interface/dynamic/entrance'
return fetch(url)
.then(response => response.json())
.then(data => (data))
.catch(error => console.error(error))
}
const API_MOMENT: APIMAP = {
getTopBarNewMomentsCount: {
url: 'https://api.bilibili.com/x/web-interface/dynamic/entrance',
_fetch: {
method: 'get',
},
params: {},
afterHandle: AHS.J_D,
},
getTopBarNewMoments: {
url: 'https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new',
_fetch: {
method: 'get',
},
params: {
uid: '',
type_list: '268435455',
},
afterHandle: AHS.J_D,
},
getTopbarHistoryMoments: {
url: 'https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_history',
_fetch: {
method: 'get',
},
params: {
uid: '',
type_list: '268435455',
offset_dynamic_id: '',
},
afterHandle: AHS.J_D,
},
getTopbarLiveMoments: {
url: 'https://api.live.bilibili.com/xlive/web-ucenter/v1/xfetter/FeedList',
_fetch: {
method: 'get',
},
params: {
page: 1,
pagesize: 10,
},
afterHandle: AHS.J_D,
},
getMoments: {
url: 'https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all',
_fetch: {
method: 'get',
},
params: {
type: 268435455,
offset: 0,
update_baseline: 0,
},
afterHandle: AHS.J_D,
},
// v2 get moment list
// else if (message.contentScriptQuery === 'getTopBarNewMoments') {
// // type: video | article
// const url = `https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/nav?type=${message.type}&update_baseline=${message.updateBaseline}`
// return fetch(url)
// .then(response => response.json())
// .then(data => (data))
// .catch(error => console.error(error))
// }
// else if (message.contentScriptQuery === 'getTopbarLiveMoments') {
// const url = `https://api.live.bilibili.com/xlive/web-ucenter/v1/xfetter/FeedList?page=${message.page}&pagesize=10`
// return fetch(url)
// .then(response => response.json())
// .then(data => (data))
// .catch(error => console.error(error))
// }
else if (message.contentScriptQuery === 'getTopBarNewMoments') {
const url = `https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new?uid=${message.uid}
&type_list=${message.typeList}`
return fetch(url)
.then(response => response.json())
.then(data => (data))
.catch(error => console.error(error))
}
else if (message.contentScriptQuery === 'getTopbarHistoryMoments') {
const url = `https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_history?uid=${message.uid}
&type_list=${message.typeList}
&offset_dynamic_id=${message.offsetDynamicID}`
return fetch(url)
.then(response => response.json())
.then(data => (data))
.catch(error => console.error(error))
}
else if (message.contentScriptQuery === 'getTopbarLiveMoments') {
const url = `https://api.live.bilibili.com/xlive/web-ucenter/v1/xfetter/FeedList?page=${message.page}&pagesize=${message.pageSize}`
return fetch(url)
.then(response => response.json())
.then(data => (data))
.catch(error => console.error(error))
}
// https://socialsisteryi.github.io/bilibili-API-collect/docs/dynamic/all.html#%E8%8E%B7%E5%8F%96%E5%8A%A8%E6%80%81%E5%88%97%E8%A1%A8
else if (message.contentScriptQuery === 'getMoments') {
const url = `https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all?timezone_offset=-480&type=${message.type}&offset=${message.offset}&update_baseline=${message.updateBaseline}`
return fetch(url)
.then(response => response.json())
.then(data => (data))
.catch(error => console.error(error))
}
}
function handleConnect() {
browser.runtime.onMessage.removeListener(handleMessage)
browser.runtime.onMessage.addListener(handleMessage)
}
export function setupMomentMsgLstnr() {
browser.runtime.onConnect.removeListener(handleConnect)
browser.runtime.onConnect.addListener(handleConnect)
}
export default API_MOMENT

View File

@@ -1,29 +1,30 @@
import browser from 'webextension-polyfill'
import type { APIMAP } from '../utils'
import { AHS } from '../utils'
function handleMessage(message: any) {
if (message.contentScriptQuery === 'getUnreadMsg') {
const url = 'https://api.bilibili.com/x/msgfeed/unread?build=0&mobi_app=web'
return fetch(url)
.then(response => response.json())
.then(data => (data))
.catch(error => console.error(error))
}
else if (message.contentScriptQuery === 'getUnreadDm') {
const url = 'https://api.vc.bilibili.com/session_svr/v1/session_svr/single_unread?build=0&mobi_app=web&unread_type=0'
return fetch(url)
.then(response => response.json())
.then(data => (data))
.catch(error => console.error(error))
}
const API_NOTIFICATION: APIMAP = {
getUnreadMsg: {
url: 'https://api.bilibili.com/x/msgfeed/unread',
_fetch: {
method: 'get',
},
params: {
build: 0,
mobi_app: 'web',
},
afterHandle: AHS.J_D,
},
getUnreadDm: {
url: 'https://api.vc.bilibili.com/session_svr/v1/session_svr/single_unread',
_fetch: {
method: 'get',
},
params: {
build: 0,
mobi_app: 'web',
unread_type: 0,
},
afterHandle: AHS.J_D,
},
}
function handleConnect() {
browser.runtime.onMessage.removeListener(handleMessage)
browser.runtime.onMessage.addListener(handleMessage)
}
export function setupNotificationMsgLstnr() {
browser.runtime.onConnect.removeListener(handleConnect)
browser.runtime.onConnect.addListener(handleConnect)
}
export default API_NOTIFICATION

View File

@@ -1,29 +1,29 @@
import browser from 'webextension-polyfill'
import type { APIMAP } from '../utils'
import { AHS } from '../utils'
function handleMessage(message: any) {
const API_RANKING: APIMAP = {
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/7873a79022a5606e2391d93b411a05576a0df111/docs/video_ranking/ranking.md#%E8%8E%B7%E5%8F%96%E5%88%86%E5%8C%BA%E8%A7%86%E9%A2%91%E6%8E%92%E8%A1%8C%E6%A6%9C%E5%88%97%E8%A1%A8
if (message.contentScriptQuery === 'getRankingVideos') {
const url = `https://api.bilibili.com/x/web-interface/ranking/v2?rid=${message.rid ?? 0}&type=${message.type ?? 'all'}`
return fetch(url)
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error))
}
else if (message.contentScriptQuery === 'getRankingPgc') {
const url = `https://api.bilibili.com/pgc/web/rank/list?day=3&season_type=${message.seasonType}`
return fetch(url)
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error))
}
getRankingVideos: {
url: 'https://api.bilibili.com/x/web-interface/ranking/v2',
_fetch: {
method: 'get',
},
params: {
rid: 0,
type: 'all',
},
afterHandle: AHS.J_D,
},
getRankingPgc: {
url: 'https://api.bilibili.com/pgc/web/rank/list',
_fetch: {
method: 'get',
},
params: {
season_type: 1,
},
afterHandle: AHS.J_D,
},
}
function handleConnect() {
browser.runtime.onMessage.removeListener(handleMessage)
browser.runtime.onMessage.addListener(handleMessage)
}
export function setupRankingMsgLstnr() {
browser.runtime.onConnect.removeListener(handleConnect)
browser.runtime.onConnect.addListener(handleConnect)
}
export default API_RANKING

View File

@@ -1,21 +1,18 @@
import browser from 'webextension-polyfill'
import type { APIMAP } from '../utils'
import { AHS } from '../utils'
function handleMessage(message: any) {
if (message.contentScriptQuery === 'getSearchSuggestion') {
const url = `https://s.search.bilibili.com/main/suggest?term=${message.term}&highlight=`
return fetch(url)
.then(response => response.json())
.then(data => (data))
.catch(error => console.error(error))
}
const API_SEARCH: APIMAP = {
getSearchSuggestion: {
url: 'https://s.search.bilibili.com/main/suggest',
_fetch: {
method: 'get',
},
params: {
term: '',
highlight: '',
},
afterHandle: AHS.J_D,
},
}
function handleConnect() {
browser.runtime.onMessage.removeListener(handleMessage)
browser.runtime.onMessage.addListener(handleMessage)
}
export function setupSearchMsgLstnr() {
browser.runtime.onConnect.removeListener(handleConnect)
browser.runtime.onConnect.addListener(handleConnect)
}
export default API_SEARCH

View File

@@ -1,30 +1,22 @@
import browser from 'webextension-polyfill'
import type { APIMAP } from '../utils'
import { AHS } from '../utils'
function handleMessage(message: any) {
const API_USER: APIMAP = {
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/e379d904c2753fa30e9083f59016f07e89d19467/docs/login/login_info.md#%E5%AF%BC%E8%88%AA%E6%A0%8F%E7%94%A8%E6%88%B7%E4%BF%A1%E6%81%AF
if (message.contentScriptQuery === 'getUserInfo') {
const url = 'https://api.bilibili.com/x/web-interface/nav'
return fetch(url)
.then(response => response.json())
.then(data => (data))
.catch(error => console.error(error))
}
else if (message.contentScriptQuery === 'getUserStat') {
const url = 'https://api.bilibili.com/x/web-interface/nav/stat'
return fetch(url)
.then(response => response.json())
.then(data => (data))
.catch(error => console.error(error))
}
getUserInfo: {
url: 'https://api.bilibili.com/x/web-interface/nav',
_fetch: {
method: 'get',
},
afterHandle: AHS.J_D,
},
getUserStat: {
url: 'https://api.bilibili.com/x/web-interface/nav/stat',
_fetch: {
method: 'get',
},
afterHandle: AHS.J_D,
},
}
function handleConnect() {
browser.runtime.onMessage.removeListener(handleMessage)
browser.runtime.onMessage.addListener(handleMessage)
}
export function setupUserMsgLstnr() {
browser.runtime.onConnect.removeListener(handleConnect)
browser.runtime.onConnect.addListener(handleConnect)
}
export default API_USER

View File

@@ -1,128 +1,107 @@
import browser from 'webextension-polyfill'
import type { APIMAP } from '../utils'
import { AHS } from '../utils'
function handleMessage(message: any) {
// #region APP端api遺棄
/** Recommend Videos */
// if (message.contentScriptQuery === 'getRecommendVideos') {
// // https://github.com/indefined/UserScripts/blob/master/bilibiliHome/bilibiliHome.API.md#%E8%8E%B7%E5%8F%96%E9%A6%96%E9%A1%B5%E5%86%85%E5%AE%B9
// const url = `${APP_URL}/x/feed/index?build=1&idx=${message.idx}&appkey=27eb53fc9058f8c3&access_key=${message.accessKey}`
// return fetch(url)
// .then(response => response.json())
// .then(data => data)
// .catch(error => console.error(error))
// }
// /** Submit a video that is not of interest */
// else if (message.contentScriptQuery === 'submitDislike') {
// // https://github.com/indefined/UserScripts/blob/master/bilibiliHome/bilibiliHome.API.md#%E6%8F%90%E4%BA%A4%E4%B8%8D%E5%96%9C%E6%AC%A2
// let url = `https://app.bilibili.com/x/feed/dislike?access_key=${message.accessKey}
// &goto=${message.goto}
// &id=${message.id}
// &mid=${message.mid}
// &reason_id=${message.reasonID}
// &rid=${message.rid}
// &tag_id=${message.tagID}
// &build=5000000`
// // remove url empty spaces
// url = url.replace(/\s+/g, '')
// return fetch(url)
// .then(response => response.json())
// .then(data => data)
// .catch(error => console.error(error))
// }
// /** Undo a video that is not of interest */
// else if (message.contentScriptQuery === 'undoDislike') {
// // https://github.com/indefined/UserScripts/blob/master/bilibiliHome/bilibiliHome.API.md#%E6%92%A4%E9%94%80%E4%B8%8D%E5%96%9C%E6%AC%A2
// let url = `https://app.bilibili.com/x/feed/dislike/cancel?access_key=${message.accessKey}
// &goto=${message.goto}
// &id=${message.id}
// &mid=${message.mid}
// &reason_id=${message.reasonID}
// &rid=${message.rid}
// &tag_id=${message.tagID}
// &build=5000000`
// // remove url empty spaces
// url = url.replace(/\s+/g, '')
// return fetch(url)
// .then(response => response.json())
// .then(data => data)
// .catch(error => console.error(error))
// }
// #endregion
if (message.contentScriptQuery === 'getRecommendVideos') {
const url = `https://api.bilibili.com/x/web-interface/index/top/feed/rcmd?fresh_idx=${message.refreshIdx}&feed_version=V2&fresh_type=4&ps=30&plat=1`
return fetch(url)
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error))
}
else if (message.contentScriptQuery === 'getAppRecommendVideos') {
// const url = `https://app.bilibili.com/x/feed/index?build=1&idx=${message.idx}&appkey=27eb53fc9058f8c3&access_key=${message.accessKey}`
const url = `https://app.bilibili.com/x/v2/feed/index?build=74800100&device=pad&mobi_app=iphone&c_locate=${message.cLocate}&s_locale=${message.sLocale}&idx=${message.idx}&appkey=${message.appkey}&access_key=${message.accessKey}`
return fetch(url)
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error))
}
else if (message.contentScriptQuery === 'dislikeVideo') {
const url = `https://api.bilibili.com/x/feed/dislike?access_key=${message.accessKey}&appkey=${message.appkey}&feedback_id=${message.feedbackId}&reason_id=${message.reasonId}`
return fetch(url)
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error))
}
const API_VIDEO: APIMAP = {
getRecommendVideos: {
url: 'https://api.bilibili.com/x/web-interface/index/top/feed/rcmd',
_fetch: {
method: 'get',
},
params: {
fresh_idx: 0,
feed_version: 'V2',
fresh_type: 4,
ps: 30,
plat: 1,
},
afterHandle: AHS.J_D,
},
getAppRecommendVideos: {
url: 'https://app.bilibili.com/x/v2/feed/index',
_fetch: {
method: 'get',
},
params: {
build: 74800100,
device: 'pad',
mobi_app: 'iphone',
c_locate: 'CN',
s_locale: 'zh-CN',
idx: 0,
appkey: '27eb53fc9058f8c3',
access_key: '',
},
afterHandle: AHS.J_D,
},
dislikeVideo: {
url: 'https://api.bilibili.com/x/feed/dislike',
_fetch: {
method: 'post',
},
params: {
access_key: '',
appkey: '27eb53fc9058f8c3',
feedback_id: '',
reason_id: 1,
},
afterHandle: AHS.J_D,
},
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/video/info.md#%E8%8E%B7%E5%8F%96%E8%A7%86%E9%A2%91%E8%B6%85%E8%AF%A6%E7%BB%86%E4%BF%A1%E6%81%AFweb%E7%AB%AF
else if (message.contentScriptQuery === 'getVideoInfo') {
const url = `https://api.bilibili.com/x/web-interface/view/detail?${
message.aid ? `aid=${message.aid}` : `bvid=${message.bvid}`
}`
return fetch(url)
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error))
}
getVideoInfo: {
url: 'https://api.bilibili.com/x/web-interface/view/detail',
_fetch: {
method: 'get',
},
params: {
aid: '',
bvid: '',
},
afterHandle: AHS.J_D,
},
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/comment/list.md#%E8%8E%B7%E5%8F%96%E8%AF%84%E8%AE%BA%E5%8C%BA%E6%98%8E%E7%BB%86_%E7%BF%BB%E9%A1%B5%E5%8A%A0%E8%BD%BD
else if (message.contentScriptQuery === 'getVideoComments') {
const url = `https://api.bilibili.com/x/v2/reply?csrf=${
message.csrf
}&type=1&oid=${message.oid}&sort=${message.sort ?? 0}&nohot=${
message.nohot ?? 0
}&pn=${message.pn ?? 1}&ps=${message.ps ?? 20}`
return fetch(url)
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error))
}
getVideoComments: {
url: 'https://api.bilibili.com/x/v2/reply',
_fetch: {
method: 'get',
},
params: {
csrf: '',
type: 1,
oid: '',
sort: 0,
nohot: 0,
pn: 1,
ps: 20,
},
afterHandle: AHS.J_D,
},
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/def57d7a70ed1f39080069ba0f40648ce6ce2b90/docs/video_ranking/popular.md#%E8%8E%B7%E5%8F%96%E5%BD%93%E5%89%8D%E7%83%AD%E9%97%A8%E8%A7%86%E9%A2%91%E5%88%97%E8%A1%A8
else if (message.contentScriptQuery === 'getPopularVideos') {
const url = `https://api.bilibili.com/x/web-interface/popular?pn=${message.pn ?? 1}&ps=${message.ps ?? 20}`
return fetch(url)
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error))
}
getPopularVideos: {
url: 'https://api.bilibili.com/x/web-interface/popular',
_fetch: {
method: 'get',
},
params: {
pn: 1,
ps: 20,
},
afterHandle: AHS.J_D,
},
// https://socialsisteryi.github.io/bilibili-API-collect/docs/video/videostream_url.html#%E8%8E%B7%E5%8F%96%E8%A7%86%E9%A2%91%E6%B5%81%E5%9C%B0%E5%9D%80-web%E7%AB%AF
else if (message.contentScriptQuery === 'getVideoPreview') {
const url = `https://api.bilibili.com/x/player/wbi/playurl?qn=${message.qn ?? 32}&fnver=${message.fnver ?? 0}&fnval=${message.fnval ?? 1}
&bvid=${message.bvid}&cid=${message.cid}&voice_balance=1&gaia_source=pre-load&web_location=1315873&from_client=BROWSER`
return fetch(url)
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error))
}
getVideoPreview: {
url: 'https://api.bilibili.com/x/player/wbi/playurl',
_fetch: {
method: 'get',
},
params: {
qn: 32,
fnver: 0,
fnval: 1,
bvid: '',
cid: '',
},
afterHandle: AHS.J_D,
},
}
function handleConnect() {
browser.runtime.onMessage.removeListener(handleMessage)
browser.runtime.onMessage.addListener(handleMessage)
}
export function setupVideoMsgLstnr() {
browser.runtime.onConnect.removeListener(handleConnect)
browser.runtime.onConnect.addListener(handleConnect)
}
export default API_VIDEO

View File

@@ -1,64 +1,62 @@
import browser from 'webextension-polyfill'
import type { APIMAP } from '../utils'
import { AHS } from '../utils'
function handleMessage(message: any) {
const API_WATCHLATER: APIMAP = {
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/history&toview/toview.md#%E8%A7%86%E9%A2%91%E6%B7%BB%E5%8A%A0%E7%A8%8D%E5%90%8E%E5%86%8D%E7%9C%8B
if (message.contentScriptQuery === 'saveToWatchLater') {
const url = 'https://api.bilibili.com/x/v2/history/toview/add'
return fetch(url, {
method: 'POST',
body: new URLSearchParams({
csrf: message.csrf,
aid: message.aid,
}),
})
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error))
}
saveToWatchLater: {
url: 'https://api.bilibili.com/x/v2/history/toview/add',
_fetch: {
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
body: {
aid: '',
csrf: '',
},
},
afterHandle: AHS.J_D,
},
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/history&toview/toview.md#%E5%88%A0%E9%99%A4%E7%A8%8D%E5%90%8E%E5%86%8D%E7%9C%8B%E8%A7%86%E9%A2%91
else if (message.contentScriptQuery === 'removeFromWatchLater') {
const url = `https://api.bilibili.com/x/v2/history/toview/del?${message.aid ? `aid=${message.aid}` : ''}`
return fetch(url, {
method: 'POST',
body: new URLSearchParams({
csrf: message.csrf,
// aid: message.aid,
viewed: message.viewed,
}),
})
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error))
}
removeFromWatchLater: {
url: 'https://api.bilibili.com/x/v2/history/toview/del',
_fetch: {
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
body: {
viewed: '',
csrf: '',
},
},
params: {
aid: '',
},
afterHandle: AHS.J_D,
},
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/history&toview/toview.md#%E8%8E%B7%E5%8F%96%E7%A8%8D%E5%90%8E%E5%86%8D%E7%9C%8B%E8%A7%86%E9%A2%91%E5%88%97%E8%A1%A8
else if (message.contentScriptQuery === 'getAllWatchLaterList') {
const url = 'https://api.bilibili.com/x/v2/history/toview'
return fetch(url)
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error))
}
getAllWatchLaterList: {
url: 'https://api.bilibili.com/x/v2/history/toview',
_fetch: {
method: 'get',
},
afterHandle: AHS.J_D,
},
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/history&toview/toview.md#%E6%B8%85%E7%A9%BA%E7%A8%8D%E5%90%8E%E5%86%8D%E7%9C%8B%E8%A7%86%E9%A2%91%E5%88%97%E8%A1%A8
else if (message.contentScriptQuery === 'clearAllWatchLater') {
const url = 'https://api.bilibili.com/x/v2/history/toview/clear'
return fetch(url, {
method: 'POST',
body: new URLSearchParams({
csrf: message.csrf,
}),
})
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error))
}
clearAllWatchLater: {
url: 'https://api.bilibili.com/x/v2/history/toview/clear',
_fetch: {
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
body: {
csrf: '',
},
},
afterHandle: AHS.J_D,
},
}
function handleConnect() {
browser.runtime.onMessage.removeListener(handleMessage)
browser.runtime.onMessage.addListener(handleMessage)
}
export function setupWatchLaterMsgLstnr() {
browser.runtime.onConnect.removeListener(handleConnect)
browser.runtime.onConnect.addListener(handleConnect)
}
export default API_WATCHLATER

View File

@@ -12,7 +12,8 @@ function toData(data: Promise<any>): Promise<any> {
}
// if need sendResponse, use this
function sendResponseHandler(sendResponse: any) {
// return a FetchAfterHandler function
function sendResponseHandler(sendResponse: Function) {
return (data: any) => sendResponse(data)
}
@@ -20,9 +21,11 @@ function sendResponseHandler(sendResponse: any) {
const AHS: {
J_D: FetchAfterHandler[]
J_S: FetchAfterHandler[]
S: FetchAfterHandler[]
} = {
J_D: [toJsonHandler, toData],
J_S: [toJsonHandler, sendResponseHandler],
S: [sendResponseHandler],
}
interface Message {
@@ -41,47 +44,74 @@ interface _FETCH {
interface API {
url: string
_fetch: _FETCH
params: {
params?: {
[key: string]: any
}
afterHandle: ((response: Response) => Response | Promise<Response>)[]
}
// 重载API 可以为函数
type APIFunction = (message: Message, sender?: any, sendResponse?: Function) => any
type APIType = API | APIFunction
interface APIMAP {
[key: string]: API
[key: string]: APIType
}
// 工厂函数API_LISTENER_FACTORY
function apiListenerFactory(API_MAP: APIMAP) {
return (message: Message) => {
if (API_MAP[message?.contentScriptQuery]) {
try {
let { contentScriptQuery, ...rest } = message
rest = rest || {}
const { _fetch, url, params, afterHandle } = API_MAP[contentScriptQuery] as API
const { method, headers, body } = _fetch as _FETCH
const targetParams = Object.assign({}, params, rest)
let targetUrl = url
let targetBody = Object.assign({}, body)
return (message: Message, sender?: any, sendResponse?: Function) => {
const contentScriptQuery = message.contentScriptQuery
// 检测是否有contentScriptQuery
if (!contentScriptQuery || !API_MAP[contentScriptQuery])
return console.error('no contentScriptQuery')
if (API_MAP[contentScriptQuery] instanceof Function)
return (API_MAP[contentScriptQuery] as APIFunction)(message, sender, sendResponse)
if (method === 'get') {
const urlParams = new URLSearchParams()
for (const key in targetParams)
urlParams.append(key, targetParams[key])
targetUrl += `?${urlParams.toString()}`
}
else {
targetBody = JSON.stringify(targetParams)
}
// get cant take body
const fetchOpt = method === 'get' ? { method, headers } : { method, headers, body: targetBody }
let baseFunc = fetch(targetUrl, fetchOpt)
afterHandle.forEach(func => baseFunc = baseFunc.then(func))
baseFunc.catch(console.error)
try {
let { contentScriptQuery, ...rest } = message
// rest above two part body or params
rest = rest || {}
return baseFunc
let { _fetch, url, params = {}, afterHandle } = API_MAP[contentScriptQuery] as API
const { method, headers, body } = _fetch as _FETCH
// merge params and body
const targetParams = Object.assign({}, params)
let targetBody = Object.assign({}, body)
Object.keys(rest).forEach((key) => {
if (body && body[key] !== undefined)
targetBody[key] = rest[key]
else
targetParams[key] = rest[key]
})
// generate body or params
if (method === 'get') {
const urlParams = new URLSearchParams()
for (const key in targetParams)
targetParams[key] && urlParams.append(key, targetParams[key])
url += `?${urlParams.toString()}`
}
catch (e) {
console.error(e)
else {
// post
targetBody = (headers && headers['Content-Type'] && headers['Content-Type'].includes('application/x-www-form-urlencoded'))
? new URLSearchParams(targetBody)
: JSON.stringify(targetBody)
}
// get cant take body
const fetchOpt = method === 'get' ? { method, headers } : { method, headers, body: targetBody }
// fetch and after handle
let baseFunc = fetch(url, fetchOpt)
afterHandle.forEach((func) => {
if (func.name === sendResponseHandler.name && sendResponse)
// sendResponseHandler 是一个特殊的后处理函数需要传入sendResponse
baseFunc = baseFunc.then(sendResponseHandler(sendResponse))
else
baseFunc = baseFunc.then(func)
})
baseFunc.catch(console.error)
return baseFunc
}
catch (e) {
console.error(e)
}
}
}

View File

@@ -64,7 +64,7 @@ async function getFavoriteCategories() {
await browser.runtime
.sendMessage({
contentScriptQuery: 'getFavoriteCategories',
mid: getUserID(),
up_mid: getUserID(),
})
.then((res) => {
if (res.code === 0) {
@@ -83,8 +83,8 @@ function getFavoriteResources() {
browser.runtime
.sendMessage({
contentScriptQuery: 'getFavoriteResources',
mediaId: activatedMediaId.value,
pageNum: currentPageNum.value,
media_id: activatedMediaId.value,
pn: currentPageNum.value,
keyword: '',
})
.then((res) => {

View File

@@ -139,13 +139,13 @@ function getHistoryUrl(item: HistoryItem) {
* @param {HistoryType} type
* @param {number} viewAt Last viewed timestamp
*/
function getHistoryList(type: HistoryType, viewAt = 0 as number) {
function getHistoryList(type: HistoryType, view_at = 0 as number) {
isLoading.value = true
browser.runtime
.sendMessage({
contentScriptQuery: 'getHistoryList',
type,
viewAt,
view_at,
})
.then((res) => {
if (res.code === 0) {

View File

@@ -89,14 +89,14 @@ function onClickTab(tabId: number) {
})
}
function getTopBarNewMoments(typeList: number[]) {
function getTopBarNewMoments(type_list: number[]) {
moments.length = 0
isLoading.value = true
browser.runtime
.sendMessage({
contentScriptQuery: 'getTopBarNewMoments',
uid: getUserID(),
typeList,
type_list,
})
.then((res) => {
if (res.code === 0) {
@@ -125,14 +125,14 @@ function getTopBarNewMoments(typeList: number[]) {
})
}
function getTopbarHistoryMoments(typeList: number[]) {
function getTopbarHistoryMoments(type_list: number[]) {
isLoading.value = true
browser.runtime
.sendMessage({
contentScriptQuery: 'getTopbarHistoryMoments',
uid: getUserID(),
typeList,
offsetDynamicID: moments[moments.length - 1].dynamic_id_str,
type_list,
offset_dynamic_id: moments[moments.length - 1].dynamic_id_str,
})
.then((res) => {
if (res.code === 0) {
@@ -157,7 +157,7 @@ function getTopbarLiveMoments(page: number) {
.sendMessage({
contentScriptQuery: 'getTopbarLiveMoments',
page,
pageSize: 10,
pagesize: 10,
})
.then((res) => {
if (res.code === 0) {

View File

@@ -75,7 +75,7 @@ async function getFavoriteCategories() {
await browser.runtime
.sendMessage({
contentScriptQuery: 'getFavoriteCategories',
mid: getUserID(),
up_mid: getUserID(),
})
.then((res: FavoritesCategoryResult) => {
if (res.code === 0) {
@@ -99,19 +99,19 @@ async function getFavoriteCategories() {
* @param keyword
*/
async function getFavoriteResources(
mediaId: number,
pageNum: number,
media_id: number,
pn: number,
keyword = '' as string,
) {
if (pageNum === 1)
if (pn === 1)
isFullPageLoading.value = true
isLoading.value = true
try {
const res: FavoritesResult = await browser.runtime
.sendMessage({
contentScriptQuery: 'getFavoriteResources',
mediaId,
pageNum,
media_id,
pn,
keyword,
})
@@ -160,7 +160,7 @@ function handleUnfavorite(favoriteResource: FavoriteResource) {
browser.runtime.sendMessage({
contentScriptQuery: 'patchDelFavoriteResources',
resources: `${favoriteResource.id}:${favoriteResource.type}`,
mediaId: selectedCategory.value?.id,
media_id: selectedCategory.value?.id,
csrf: getCSRF(),
}).then((res) => {
if (res.code === 0)

View File

@@ -59,7 +59,7 @@ function getHistoryList() {
.sendMessage({
contentScriptQuery: 'getHistoryList',
type: 'all',
viewAt:
view_at:
historyList.length > 0
? historyList[historyList.length - 1].view_at
: 0,

View File

@@ -79,7 +79,7 @@ async function getFollowedUsersVideos() {
contentScriptQuery: 'getMoments',
type: 'video',
offset: offset.value,
updateBaseline: updateBaseline.value,
update_baseline: updateBaseline.value,
})
if (response.code === -101) {

View File

@@ -117,7 +117,7 @@ async function getRecommendVideos() {
try {
const response: forYouResult = await browser.runtime.sendMessage({
contentScriptQuery: 'getRecommendVideos',
refreshIdx: refreshIdx.value++,
fresh_idx: refreshIdx.value++,
})
if (!response.data) {
@@ -157,9 +157,9 @@ async function getAppRecommendVideos() {
try {
const response: AppForYouResult = await browser.runtime.sendMessage({
contentScriptQuery: 'getAppRecommendVideos',
accessKey: accessKey.value,
sLocale: settings.value.language !== LanguageType.Mandarin_CN ? 'zh-Hant_TW' : 'zh-Hans_CN',
cLocale: settings.value.language !== LanguageType.Mandarin_CN ? 'zh-Hant_TW' : 'zh-Hans_CN',
access_key: accessKey.value,
s_locale: settings.value.language !== LanguageType.Mandarin_CN ? 'zh-Hant_TW' : 'zh-Hans_CN',
c_locale: settings.value.language !== LanguageType.Mandarin_CN ? 'zh-Hant_TW' : 'zh-Hans_CN',
appkey: TVAppKey.appkey,
idx: appVideoList.length > 0 ? appVideoList[appVideoList.length - 1].idx : 1,
})

View File

@@ -140,7 +140,7 @@ function getRankingPgc() {
isLoading.value = true
browser.runtime.sendMessage({
contentScriptQuery: 'getRankingPgc',
seasonType: activatedRankingType.value.seasonType,
season_type: activatedRankingType.value.seasonType,
}).then((response: RankingPgcResult) => {
if (response.code === 0)
Object.assign(PgcList, response.result.list)

View File

@@ -84,7 +84,7 @@ async function getFollowedUsersVideos() {
contentScriptQuery: 'getMoments',
type: 'pgc',
offset: offset.value,
updateBaseline: updateBaseline.value,
update_baseline: updateBaseline.value,
})
if (response.code === -101) {