Add test for fetching live metadata from cnb issue

This commit is contained in:
xiongxiao
2026-02-20 03:53:05 +08:00
committed by cnb
parent 0ebc94a7d0
commit d16adc07fe
12 changed files with 346 additions and 952 deletions

View File

@@ -79,7 +79,7 @@ export class CNBCore {
}
delete _headers.Authorization;
}
// console.log('Request URL:', url, data, _headers);
console.log('Request URL:', url, data, _headers);
const response = await fetch(url || '', {
method,
headers: _headers,

View File

@@ -1,4 +1,5 @@
import { CNBCore, CNBCoreOptions, RequestOptions, Result } from "../cnb-core.ts";
import { extractAliveInfo } from "./issue-alive.ts";
export type IssueAssignee = {
nickname: string;
@@ -88,6 +89,51 @@ export class Issue extends CNBCore {
};
return this.post({ url, data: postData });
}
/**
* 获取alive issue的元数据
* @param repo
* @param issueNumber
* @returns
*/
async getAliveMetadata(repo: string, issueNumber: string | number): Promise<Result<AliveMetadata>> {
const url = this.hackURL + `/${repo}/-/issues/${issueNumber}`;
const resHtml = await this.get({
url,
useCookie: true,
headers: {
'Content-Type': 'text/html; charset=utf-8',
Accept: "text/html; charset=utf-8",
}
});
if (resHtml.code !== 200) {
return resHtml;
}
const html = resHtml.data as string;
const { aliveSessionID, aliveChannelID } = extractAliveInfo(html);
if (!aliveSessionID || !aliveChannelID) {
return {
code: 500,
message: 'Failed to extract alive metadata',
data: null,
};
}
const off = Date.now();
return {
code: 200,
message: 'success',
data: {
aliveSessionID,
aliveChannelID,
domain: 'alive.cnb.cool',
subscriptions: [
{ event: 'subscribe', data: { id: `${aliveChannelID}--issue:info-update`, off } },
{ event: 'subscribe', data: { id: `${aliveChannelID}--issue:add-comment`, off } },
{ event: 'subscribe', data: { id: `${aliveChannelID}--issue:comment-update`, off } },
{ event: 'subscribe', data: { id: `${aliveChannelID}--issue:invisible`, off } },
],
},
};
}
}
type GetListParams = {
@@ -119,4 +165,17 @@ type GetListParams = {
updated_time_begin?: string;
/** 问题更新时间过滤-结束,例如: 2022-01-31 */
updated_time_end?: string;
}
export type AliveMetadata = {
aliveSessionID: string;
aliveChannelID: string;
domain: string;
subscriptions: {
event: 'subscribe',
data: {
id: string;
off: number;
}
}[]
}

15
src/issue/issue-alive.ts Normal file
View File

@@ -0,0 +1,15 @@
export function extractAliveInfo(html: string): { aliveSessionID: string | null; aliveChannelID: string | null } {
const match = html.match(/<script[^>]*id="__NEXT_DATA__"[^>]*>([\s\S]*?)<\/script>/);
if (!match || !match[1]) {
return { aliveSessionID: null, aliveChannelID: null };
}
try {
const data = JSON.parse(match[1]);
const aliveSessionID = data?.props?.pageProps?.aliveSessionID ?? null;
const aliveChannelID = data?.props?.pageProps?.aliveChannelID ?? null;
return { aliveSessionID, aliveChannelID };
} catch {
return { aliveSessionID: null, aliveChannelID: null };
}
}

View File

@@ -0,0 +1,24 @@
```js
fetch("wss://alive.cnb.cool/?id=26354bd0-3e00-4869-93c9-b687f19d96c1", {
"headers": {
"accept-language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"cache-control": "no-cache",
"pragma": "no-cache",
"sec-websocket-extensions": "permessage-deflate; client_max_window_bits",
"sec-websocket-key": "vXnvsfo4splpfeDSnJLxKA==",
"sec-websocket-protocol": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoiY29va2llIiwic2NvcGUiOiIiLCJtZXRhIjp7IkxpY2Vuc2UiOnsiY29tbW9uTmFtZSI6IiouY25iLmNvb2wiLCJub3RCZWZvcmUiOiIyMDI1LTA2LTE4VDA5OjE3OjE5WiIsIm5vdEFmdGVyIjoiMjAzNS0wNi0xNlQwOToxNzoxOVoiLCJpc3N1ZXIiOiJUZW5jZW50LCBJbmMiLCJvcmdhbml6YXRpb24iOiLohb7orq_kupEiLCJtZW1iZXJzIjoxMDAwMDAwLCJjaGFubmVsIjoiU2FhUyJ9LCJyb290X29yZ2FuaXphdGlvbl9zZXR0aW5nIjp7ImhpZGVfbWVtYmVycyI6MCwiaGlkZV9zdWJfZ3JvdXBzIjowLCJzaG93X3ByaXZhdGVfcmVwb193YXRlcm1hcmsiOjAsImdyb3VwX3Byb3RlY3Rpb24iOjEsImVtYWlsX3ZlcmlmaWNhdGlvbiI6IiIsInZhbHVlcyI6IiJ9fSwicGxhdGZvcm0iOiIiLCJ1c2VyX2lkIjoiIiwidXNlcl9lbWFpbCI6IiIsIm5pY2tuYW1lIjoiIiwidXNlcm5hbWUiOiIiLCJ2ZXJpZmllZCI6ZmFsc2UsImZyZWV6ZSI6ZmFsc2UsImJhbiI6ZmFsc2UsImxvY2tlZCI6ZmFsc2UsInVzZXJfZGV2aWNlX3R5cGUiOjAsInNsdWciOiJrZXZpc3VhbC9rZXZpc3VhbCIsInNsdWdfaWQiOiIxOTE1NDE1NDE0NTE4NjU3MDI0Iiwic2x1Z190eXBlIjoxLCJzbHVnX3N0YXR1cyI6MCwic2x1Z19mcmVlemUiOmZhbHNlLCJzbHVnX3Zpc2liaWxpdHkiOiJQdWJsaWMiLCJzbHVnX3Jvb3RfaWQiOiIxOTE1MzUzNzE5MDE4MzM2MjU2Iiwic2x1Z19yb2xlIjoiVW5rbm93biIsImxhbmd1YWdlIjoiZW4tVVMiLCJjb250ZXh0Ijoie30iLCJpc3MiOiJhY2Nlc3Mtcm91dGVyLTVmNzg5ZGM3N2ItN3Y1bnMiLCJpYXQiOjE3NzE1Mjk1MTQsImp0aSI6Ijk2MjYzIn0.PrlpGLNw7-1ucm3CiTQsPH7nIYFgvhZqQGhlws3R4ME",
"sec-websocket-version": "13"
},
"body": null,
"method": "GET",
"mode": "cors",
"credentials": "omit"
});
```
```json
{"event":"subscribe","data":{"id":"495b92b2fbcd908e6ca1c809a3873bb373a7a6c6b814dfce5ff60b5f87dd0944--issue:info-update","off":1771529514922}}
{"event":"subscribe","data":{"id":"495b92b2fbcd908e6ca1c809a3873bb373a7a6c6b814dfce5ff60b5f87dd0944--issue:add-comment","off":1771529514922}}
{"event":"subscribe","data":{"id":"495b92b2fbcd908e6ca1c809a3873bb373a7a6c6b814dfce5ff60b5f87dd0944--issue:comment-update","off":1771529514922}}
{"event":"subscribe","data":{"id":"495b92b2fbcd908e6ca1c809a3873bb373a7a6c6b814dfce5ff60b5f87dd0944--issue:invisible","off":1771529514922}}
```

File diff suppressed because one or more lines are too long