generated from tailored/router-db-template
feat: update Bailian model and improve TypeScript configuration
- Changed Bailian model from 'qwen3-235b-a22b' to 'qwen-plus' in ai.ts - Updated model references in bailianModel to use simplified names - Modified tsconfig.json to set module to NodeNext, target to esnext, and adjusted paths for better module resolution - Added new query-keys.ts file in xhs package to implement getNoteByKeyword functionality with command line interface
This commit is contained in:
@@ -6,3 +6,9 @@ POSTGRES_DB=postgres
|
|||||||
|
|
||||||
REDIS_HOST=localhost
|
REDIS_HOST=localhost
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
|
|
||||||
|
|
||||||
|
XHS_USER_ID=
|
||||||
|
XHS_USER_NAME=
|
||||||
|
XHS_API_SIGN_URL=
|
||||||
|
XHS_ROOT_COOKIE=
|
||||||
28
.github/workflows/git-sync.yml
vendored
28
.github/workflows/git-sync.yml
vendored
@@ -1,28 +0,0 @@
|
|||||||
name: Sync to CNB
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
# - main
|
|
||||||
- 'releases/**'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
# This workflow is triggered on push events to the repository.
|
|
||||||
jobs:
|
|
||||||
sync:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Sync to CNB Repository
|
|
||||||
run: |
|
|
||||||
docker run --rm \
|
|
||||||
-v ${{ github.workspace }}:${{ github.workspace }} \
|
|
||||||
-w ${{ github.workspace }} \
|
|
||||||
-e PLUGIN_TARGET_URL="https://cnb.cool/kevisual/router-template.git" \
|
|
||||||
-e PLUGIN_AUTH_TYPE="https" \
|
|
||||||
-e PLUGIN_USERNAME="cnb" \
|
|
||||||
-e PLUGIN_PASSWORD=${{ secrets.GIT_PASSWORD }} \
|
|
||||||
-e PLUGIN_SYNC_MODE="rebase" \
|
|
||||||
tencentcom/git-sync
|
|
||||||
54
package.json
54
package.json
@@ -21,7 +21,7 @@
|
|||||||
"clean": "rm -rf dist",
|
"clean": "rm -rf dist",
|
||||||
"turbo:build": "turbo run build",
|
"turbo:build": "turbo run build",
|
||||||
"pub": "npm run build && envision pack -p -u",
|
"pub": "npm run build && envision pack -p -u",
|
||||||
"cmd": "tsx cmd/index.ts "
|
"cmd": "bun packages/xhs/src/test/command.ts "
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "abearxiong <xiongxiao@xiongxiao.me>",
|
"author": "abearxiong <xiongxiao@xiongxiao.me>",
|
||||||
@@ -36,43 +36,43 @@
|
|||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@kevisual/ai": "^0.0.8",
|
"@kevisual/ai": "^0.0.19",
|
||||||
"@kevisual/code-center-module": "0.0.23",
|
"@kevisual/code-center-module": "0.0.24",
|
||||||
"@kevisual/context": "^0.0.3",
|
"@kevisual/context": "^0.0.4",
|
||||||
"@kevisual/router": "0.0.23",
|
"@kevisual/router": "0.0.49",
|
||||||
"@kevisual/use-config": "^1.0.19",
|
"@kevisual/use-config": "^1.0.21",
|
||||||
"cookie": "^1.0.2",
|
"cookie": "^1.1.1",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.19",
|
||||||
"formidable": "^3.5.4",
|
"formidable": "^3.5.4",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.22",
|
||||||
"nanoid": "^5.1.5"
|
"nanoid": "^5.1.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@kevisual/app-assistant": "workspace:*",
|
|
||||||
"@kevisual/logger": "^0.0.4",
|
"@kevisual/logger": "^0.0.4",
|
||||||
"@kevisual/social-prompts": "workspace:*",
|
"@kevisual/social-prompts": "workspace:*",
|
||||||
"@kevisual/types": "^0.0.10",
|
"@kevisual/types": "^0.0.10",
|
||||||
"@kevisual/use-config": "^1.0.19",
|
"@kevisual/use-config": "^1.0.21",
|
||||||
"@kevisual/xhs": "workspace:*",
|
"@kevisual/xhs": "workspace:*",
|
||||||
"@types/bun": "^1.2.16",
|
"@types/bun": "^1.3.5",
|
||||||
"@types/crypto-js": "^4.2.2",
|
"@types/crypto-js": "^4.2.2",
|
||||||
"@types/formidable": "^3.4.5",
|
"@types/formidable": "^3.4.6",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^24.0.3",
|
"@types/node": "^25.0.3",
|
||||||
"bullmq": "^5.55.0",
|
"bullmq": "^5.66.2",
|
||||||
"commander": "^14.0.0",
|
"commander": "^14.0.2",
|
||||||
"concurrently": "^9.1.2",
|
"concurrently": "^9.2.1",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^10.1.0",
|
||||||
"dotenv": "^16.5.0",
|
"dotenv": "^17.2.3",
|
||||||
"inquire": "^0.4.8",
|
"inquire": "^0.4.8",
|
||||||
"ioredis": "^5.6.1",
|
"ioredis": "^5.8.2",
|
||||||
"nodemon": "^3.1.10",
|
"nodemon": "^3.1.11",
|
||||||
"openai": "^5.6.0",
|
"openai": "^6.15.0",
|
||||||
"pg": "^8.16.2",
|
"pg": "^8.16.3",
|
||||||
"rimraf": "^6.0.1",
|
"rimraf": "^6.1.2",
|
||||||
"sequelize": "^6.37.7",
|
"sequelize": "^6.37.7",
|
||||||
"tape": "^5.9.0",
|
"tape": "^5.9.0",
|
||||||
"typescript": "^5.8.3"
|
"turbo": "^2.7.2",
|
||||||
|
"typescript": "^5.9.3"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.12.1"
|
"packageManager": "pnpm@10.26.2"
|
||||||
}
|
}
|
||||||
17
packages/app-assistant/.gitignore
vendored
17
packages/app-assistant/.gitignore
vendored
@@ -1,17 +0,0 @@
|
|||||||
node_modules
|
|
||||||
|
|
||||||
dist
|
|
||||||
|
|
||||||
app.config.json5
|
|
||||||
|
|
||||||
apps.config.json
|
|
||||||
|
|
||||||
deploy.tar.gz
|
|
||||||
cache-file
|
|
||||||
|
|
||||||
/apps
|
|
||||||
|
|
||||||
logs
|
|
||||||
|
|
||||||
.env*
|
|
||||||
!.env.example
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@kevisual/app-assistant",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"description": "",
|
|
||||||
"main": "index.js",
|
|
||||||
"scripts": {
|
|
||||||
"dev": "echo \"Error: no test specified\" && exit 1"
|
|
||||||
},
|
|
||||||
"keywords": [],
|
|
||||||
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
|
|
||||||
"license": "MIT",
|
|
||||||
"packageManager": "pnpm@10.10.0",
|
|
||||||
"type": "module",
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/node": "^22.15.3",
|
|
||||||
"bullmq": "^5.51.1"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"nanoid": "^5.1.5"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export * from './provider/comments/xhs.ts';
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import { SocialBase } from '@/social/social-base.ts';
|
|
||||||
|
|
||||||
export class XHS extends SocialBase {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
import { nanoid } from 'nanoid';
|
|
||||||
|
|
||||||
export class SocialBase<T = any> {
|
|
||||||
id: string = '';
|
|
||||||
/**
|
|
||||||
* 是否运行中
|
|
||||||
*/
|
|
||||||
isRuning: boolean = false;
|
|
||||||
/**
|
|
||||||
* 应用的配置项
|
|
||||||
*/
|
|
||||||
config: T;
|
|
||||||
constructor(opts?: any) {
|
|
||||||
this.config = opts?.config || {};
|
|
||||||
this.id = opts?.id || nanoid();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 获取用户信息
|
|
||||||
*/
|
|
||||||
async getUserInfo() {
|
|
||||||
throw new Error('Method not implemented.');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 获取被 call 的信息
|
|
||||||
*/
|
|
||||||
async getMention() {
|
|
||||||
throw new Error('Method not implemented.');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送评论信息
|
|
||||||
*/
|
|
||||||
async sendComment() {
|
|
||||||
// throw new Error('Method not implemented.');
|
|
||||||
}
|
|
||||||
async getUnread() {
|
|
||||||
throw new Error('Method not implemented.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
const unreadUrl = 'https://edith.xiaohongshu.com/api/sns/web/unread_count';
|
|
||||||
const cookie =
|
|
||||||
'a1=xxxx;abRequestId=0a794332-4561-5f49-93f7-780b8b028e1f;access-token-creator.xiaohongshu.com=customer.creator.AT-68c517498636784561614544frjvxzj7yu8iewie;agora_session=6a0031373435393132333637323735343733393437313634000000000000;customerClientId=536706778174172;galaxy_creator_session_id=OhpHDDSoADhNEhnH5LLnQpletFLApu1fd91f;galaxy.creator.beaker.session.id=1745912429847011598150;gid=yjKqYfK0qDyYyj2DDSqd4ujxyW9kvxIuT62ddkMWhElyuxq8yDd6hl888q2WYy88j8i80yYD;loadts=1746020512562;sec_poison_id=441c932e-a6ac-4d8d-97ae-beb14adb1929;unread={%22ub%22:%2267eaf1fe000000001202c3ea%22%2C%22ue%22:%226803aa37000000001c0319d8%22%2C%22uc%22:35};web_session=040069b2e9c511ca302086ca253a4bde8b1cd1;webBuild=4.62.3;webId=97e5f097499594cad49aa0bd1a8ed83f;websectiga=3633fe24d49c7dd0eb923edc8205740f10fdb18b25d424d2a2322c6196d2a4ad;x-user-id-creator.xiaohongshu.com=639d86590000000026006076;xsecappid=xhs-pc-web;acw_tc=0a00df6217460205042195762e721fba339a0dbe8e4738b961a5ff15e74619;';
|
|
||||||
|
|
||||||
const cookieObj = cookie.split('; ').reduce((acc, item) => {
|
|
||||||
const [key, value] = item.split('=');
|
|
||||||
acc[key] = value;
|
|
||||||
return acc;
|
|
||||||
}, {} as Record<string, string>);
|
|
||||||
const web_session = cookieObj['web_session'] || '';
|
|
||||||
const a1 = cookieObj['a1'] || '';
|
|
||||||
|
|
||||||
const headers = {
|
|
||||||
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36',
|
|
||||||
Cookie: cookie,
|
|
||||||
};
|
|
||||||
|
|
||||||
const meUri = '/api/sns/web/v2/user/me';
|
|
||||||
const getSign = async (uri: string, data: any, a1: string, web_session?: string) => {
|
|
||||||
const signs = await fetch('http://localhost:5006/sign', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
uri,
|
|
||||||
data,
|
|
||||||
a1,
|
|
||||||
web_session: web_session,
|
|
||||||
}),
|
|
||||||
}).then((res) => res.json());
|
|
||||||
return signs;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getUserMe = async () => {
|
|
||||||
const sign = await getSign(meUri, null, a1, web_session);
|
|
||||||
// const sign = {
|
|
||||||
// 'x-s':
|
|
||||||
// 'XYW_eyJzaWduU3ZuIjoiNTYiLCJzaWduVHlwZSI6IngyIiwiYXBwSWQiOiJsb2dpbiIsInNpZ25WZXJzaW9uIjoiMSIsInBheWxvYWQiOiJjYWE4NzYyMjk5NzQ0NDkzNGVhMWIxNDBjNzA0NTI2YmI0ZGZiYjcyMWJjMWQyZTEzNDhhNzZmNmM4MTI5NzljM2VkMWRmMjU0MGNkZDRkZmEyZGE0YjIzOTg0MDMyYmNmNGE4NDU1MzU4ZmZhZDQ0NjkxNzg4YWRjN2U2MmU3YjJmMzdmZGMzZTgwOWQ5NDNmOTRkM2JhMzVjNmQ3MzE4MjA1OWI3MTYyZGU0YjgxYzcyMDI2NmQyM2EzMmY1MGQ2NTQ5MmQ0ZTlhOTA3NmExY2JmMTYyZGJhMWJiMzAxNTg3MmY3MWU5MmIyNDllZGM3MmRkMjhiNGQ4Y2I4MjI2ZWY3YTdkYjI3NGQ2Y2YyMjVkZjk2ZjFmNWJlN2M2ZDkwNjY1MTE4MWJkYWNmYmQzYzVhMDk4Nzg3YjNmNThjMjc1ZWNjNDQzODFkOGNjNmU2ODAyNDFiZTRiODIwZjlkMDUyNTAyODk1ODZhYjM1NTRlMDJjYjhmZDlmNzIyNjM0NDMzZDBiZmNjMzg5NGU2ZDJmNGFiNGVlNGY0MzljMSJ9',
|
|
||||||
// 'x-t': '1746022429225',
|
|
||||||
// };
|
|
||||||
console.log('sign', sign);
|
|
||||||
const baseURL = 'https://edith.xiaohongshu.com';
|
|
||||||
const xhsMeUri = baseURL + '/api/sns/web/v2/user/me';
|
|
||||||
const res = await fetch(xhsMeUri, {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
...headers,
|
|
||||||
...sign,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const data = await res.json();
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
getUserMe().then((res) => {
|
|
||||||
console.log('res', res);
|
|
||||||
});
|
|
||||||
|
|
||||||
export async function getUnread() {
|
|
||||||
const unreadUri = '/api/sns/web/unread_count';
|
|
||||||
const sign = await getSign(unreadUri, null, a1, web_session);
|
|
||||||
console.log('sign', sign);
|
|
||||||
const res = await fetch(unreadUrl, {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
...headers,
|
|
||||||
...sign,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const data = await res.json();
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
// getUnread().then((res) => {
|
|
||||||
// console.log('res', res);
|
|
||||||
// });
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "@kevisual/types/json/backend.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"baseUrl": "./",
|
|
||||||
"paths": {
|
|
||||||
"@/*": [
|
|
||||||
"src/*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"src/**/*.ts",
|
|
||||||
],
|
|
||||||
"exclude": [],
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import qs from 'querystring';
|
import qs from 'querystring';
|
||||||
import { get_xs } from './jsvmp/xhs';
|
|
||||||
import fs from 'fs';
|
|
||||||
|
|
||||||
import { getXCommon, getSearchId, SearchSortType, SearchNoteType } from './helper.js';
|
import { getSearchId, SearchSortType, SearchNoteType } from './helper.js';
|
||||||
import { ErrorEnum, DataFetchError, IPBlockError, SignError, NeedVerifyError } from './exception';
|
import { ErrorEnum, DataFetchError, IPBlockError, SignError, NeedVerifyError } from './exception';
|
||||||
|
|
||||||
const camelToUnderscore = (key) => {
|
const camelToUnderscore = (key) => {
|
||||||
@@ -93,24 +91,6 @@ class XhsClient {
|
|||||||
config.headers = newHeaders;
|
config.headers = newHeaders;
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
_preHeaders(url, data = null) {
|
|
||||||
let a1 = this.cookieDict.a1;
|
|
||||||
let b1 = '';
|
|
||||||
let x_s_result = get_xs(url, data, this.cookie);
|
|
||||||
const X_S = x_s_result['X-s'];
|
|
||||||
const X_t = x_s_result['X-t'].toString();
|
|
||||||
const X_S_COMMON = getXCommon(a1, b1, X_S, X_t);
|
|
||||||
return {
|
|
||||||
headers: {
|
|
||||||
'x-s': X_S,
|
|
||||||
'x-t': X_t,
|
|
||||||
// 'x-s-common': X_S_COMMON,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
getXCommon(a1, b1, x_s, x_t) {
|
|
||||||
return getXCommon(a1, b1 || '', x_s, String(x_t));
|
|
||||||
}
|
|
||||||
getCookieMap() {
|
getCookieMap() {
|
||||||
const cookie = this.cookie;
|
const cookie = this.cookie;
|
||||||
let cookieDict = {};
|
let cookieDict = {};
|
||||||
@@ -145,16 +125,6 @@ class XhsClient {
|
|||||||
this.axiosInstance.defaults.headers.Cookie = cookieStr;
|
this.axiosInstance.defaults.headers.Cookie = cookieStr;
|
||||||
this.cookie = cookieStr;
|
this.cookie = cookieStr;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Get X-S and X-T
|
|
||||||
* @param {*} url
|
|
||||||
* @param {*} data
|
|
||||||
* @param {*} cookie
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
get_xs(url, data, cookie) {
|
|
||||||
return get_xs(url, data, cookie);
|
|
||||||
}
|
|
||||||
|
|
||||||
async request(method, url, config = {}) {
|
async request(method, url, config = {}) {
|
||||||
try {
|
try {
|
||||||
@@ -277,17 +247,17 @@ class XhsClient {
|
|||||||
const endpoint = this.getEndpoint(config).endpoint;
|
const endpoint = this.getEndpoint(config).endpoint;
|
||||||
config = await this.requestSign(uri, data, config);
|
config = await this.requestSign(uri, data, config);
|
||||||
this.printResult('post', { uri, data, config });
|
this.printResult('post', { uri, data, config });
|
||||||
if (data) {
|
// if (data) {
|
||||||
return this.request('POST', `${endpoint}${uri}`, {
|
// return this.request('POST', `${endpoint}${uri}`, {
|
||||||
...config,
|
// ...config,
|
||||||
data: jsonStr,
|
// data: jsonStr,
|
||||||
headers: {
|
// headers: {
|
||||||
...config.headers,
|
// ...config.headers,
|
||||||
'Content-Type': 'application/json',
|
// 'Content-Type': 'application/json',
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
return this.request('POST', `${endpoint}${uri}`, { ...config, data });
|
// return this.request('POST', `${endpoint}${uri}`, { ...config, data });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -28,6 +28,12 @@ export const api: ApiInfo[] = [
|
|||||||
needSign: true,
|
needSign: true,
|
||||||
description: '获取@我的消息',
|
description: '获取@我的消息',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
uri: '/api/sns/web/v1/search/notes',
|
||||||
|
method: 'POST',
|
||||||
|
needSign: true,
|
||||||
|
description: '通过关键词搜索笔记',
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
type ReturnApiInfo = {
|
type ReturnApiInfo = {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { getApiInfo } from './xhs-api/api.ts';
|
import { getApiInfo } from './xhs-api/api.ts';
|
||||||
import { XhsClient as XhsClientBase } from '@kevisual/xhs-core';
|
import { XhsClient as XhsClientBase } from '@kevisual/xhs-core';
|
||||||
import { Mention, CommonentInfo, ResponseMession } from './xhs-type/mention.ts';
|
import { Mention, CommonentInfo, ResponseMession } from './xhs-type/mention.ts';
|
||||||
import { pick } from 'lodash-es';
|
import { method, pick } from 'lodash-es';
|
||||||
import { getNote } from './modules/get-note.ts';
|
import { getNote } from './modules/get-note.ts';
|
||||||
export type Result<T> = {
|
export type Result<T> = {
|
||||||
code: number; // 0: success
|
code: number; // 0: success
|
||||||
@@ -14,6 +14,7 @@ type SignInfo = {
|
|||||||
data: any;
|
data: any;
|
||||||
a1: string;
|
a1: string;
|
||||||
web_session?: string;
|
web_session?: string;
|
||||||
|
method?: 'GET' | 'POST';
|
||||||
};
|
};
|
||||||
type SignResponse = {
|
type SignResponse = {
|
||||||
a1: string;
|
a1: string;
|
||||||
@@ -27,10 +28,10 @@ type SignResponse = {
|
|||||||
};
|
};
|
||||||
type SignOptions = {
|
type SignOptions = {
|
||||||
signUrl?: string;
|
signUrl?: string;
|
||||||
|
method?: 'GET' | 'POST';
|
||||||
};
|
};
|
||||||
export const getSign = async (signInfo: SignInfo, options?: SignOptions): Promise<SignResponse> => {
|
export const getSign = async (signInfo: SignInfo, options?: SignOptions): Promise<SignResponse> => {
|
||||||
const { uri, data, a1, web_session } = signInfo;
|
const { uri, data, a1, method } = signInfo;
|
||||||
// console.log('getSign', uri, data, a1, web_session);
|
|
||||||
// let signUri = new URL(uri, 'http://light.xiongxiao.me:5006').pathname;
|
// let signUri = new URL(uri, 'http://light.xiongxiao.me:5006').pathname;
|
||||||
// signUri = '/api/sns/web/v2/user/me';
|
// signUri = '/api/sns/web/v2/user/me';
|
||||||
try {
|
try {
|
||||||
@@ -48,7 +49,7 @@ export const getSign = async (signInfo: SignInfo, options?: SignOptions): Promis
|
|||||||
uri: uri,
|
uri: uri,
|
||||||
data,
|
data,
|
||||||
a1,
|
a1,
|
||||||
web_session: web_session,
|
method: signInfo.method || 'POST',
|
||||||
}),
|
}),
|
||||||
}).then((res) => res.json());
|
}).then((res) => res.json());
|
||||||
return signs as SignResponse;
|
return signs as SignResponse;
|
||||||
@@ -92,6 +93,11 @@ export class XhsClient extends XhsClientBase {
|
|||||||
case 'sign':
|
case 'sign':
|
||||||
// console.log('sign', data);
|
// console.log('sign', data);
|
||||||
break;
|
break;
|
||||||
|
case 'post':
|
||||||
|
console.log('post', data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -158,7 +164,7 @@ export class XhsClient extends XhsClientBase {
|
|||||||
const response = await this.get(url, { num, cursor }, { sign: this.sign.bind(this) });
|
const response = await this.get(url, { num, cursor }, { sign: this.sign.bind(this) });
|
||||||
return response as Result<ReturnData>;
|
return response as Result<ReturnData>;
|
||||||
}
|
}
|
||||||
async getComment(noteId: string, xsecToken?: string) {}
|
async getComment(noteId: string, xsecToken?: string) { }
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @uri /api/sns/web/v1/you/mentions
|
* @uri /api/sns/web/v1/you/mentions
|
||||||
@@ -183,23 +189,26 @@ export class XhsClient extends XhsClientBase {
|
|||||||
if (apiInfo && !apiInfo?.needSign) {
|
if (apiInfo && !apiInfo?.needSign) {
|
||||||
return config || {};
|
return config || {};
|
||||||
}
|
}
|
||||||
const web_session = cookieDist['web_session'];
|
|
||||||
const a1 = cookieDist['a1'];
|
const a1 = cookieDist['a1'];
|
||||||
const res = await getSign({ uri, data, a1, web_session }, this.signConfig);
|
const res = await getSign({ uri, data, a1, method: 'POST' }, this.signConfig);
|
||||||
const _sign = res.sign;
|
console.log('sign response', res);
|
||||||
|
const _sign = res.sign
|
||||||
this.printResult('sign', { uri, apiInfo, res });
|
this.printResult('sign', { uri, apiInfo, res });
|
||||||
const xs = _sign?.['x-s'];
|
const xs = _sign?.['x-s'];
|
||||||
const xt = _sign?.['x-t'];
|
const xt = _sign?.['x-t'];
|
||||||
const b1 = _sign?.['b1'];
|
|
||||||
const newA1 = _sign?.['a1'];
|
const newA1 = _sign?.['a1'];
|
||||||
|
const xsCommon = _sign?.['x-s-common'];
|
||||||
|
const xB3Traceid = _sign?.['x-b3-traceid'];
|
||||||
if (a1 !== newA1) {
|
if (a1 !== newA1) {
|
||||||
this.setCookieMap({ a1: newA1 });
|
this.setCookieMap({ a1: newA1 });
|
||||||
this.printResult('cookie change', a1);
|
this.printResult('cookie change', a1);
|
||||||
}
|
}
|
||||||
|
// throw new Error('disable sign');
|
||||||
if (res && xs) {
|
if (res && xs) {
|
||||||
headers['x-s'] = xs;
|
headers['x-s'] = xs;
|
||||||
headers['x-t'] = xt;
|
headers['x-t'] = xt;
|
||||||
// headers['x-s-common'] = this.getXCommon(a1, b1, xs, xt);
|
headers['x-s-common'] = xsCommon;
|
||||||
|
headers['x-b3-traceid'] = xB3Traceid;
|
||||||
config.headers = headers;
|
config.headers = headers;
|
||||||
} else {
|
} else {
|
||||||
console.log('get sign error', res);
|
console.log('get sign error', res);
|
||||||
@@ -257,6 +266,21 @@ export class XhsClient extends XhsClientBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
getNote = getNote;
|
getNote = getNote;
|
||||||
|
async getNoteByKeyword(keyword: string, page?: number, pageSize?: number, sort?: string, noteType?: number): Promise<any> {
|
||||||
|
const uri = '/api/sns/web/v1/search/notes';
|
||||||
|
const data = {
|
||||||
|
keyword,
|
||||||
|
page: page || 1,
|
||||||
|
page_size: pageSize || 20,
|
||||||
|
sort: sort || SearchSortType.GENERAL,
|
||||||
|
note_type: noteType || SearchNoteType.ALL,
|
||||||
|
search_id: getSearchId(),
|
||||||
|
image_formats: ['jpg', 'webp', 'avif'],
|
||||||
|
ext_flags: []
|
||||||
|
};
|
||||||
|
const response = await this.post(uri, data, { sign: this.sign.bind(this) });
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type UnreadCount = {
|
type UnreadCount = {
|
||||||
@@ -265,3 +289,29 @@ type UnreadCount = {
|
|||||||
connections: number;
|
connections: number;
|
||||||
mentions: number;
|
mentions: number;
|
||||||
};
|
};
|
||||||
|
function getSearchId() {
|
||||||
|
const e = BigInt(Date.now()) << 64n;
|
||||||
|
const t = Math.floor(Math.random() * 2147483647);
|
||||||
|
return base36encode(e + BigInt(t));
|
||||||
|
}
|
||||||
|
function base36encode(num: bigint): string {
|
||||||
|
return num.toString(36).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
const SearchSortType = Object.freeze({
|
||||||
|
// default
|
||||||
|
GENERAL: { value: "general" },
|
||||||
|
// most popular
|
||||||
|
MOST_POPULAR: { value: "popularity_descending" },
|
||||||
|
// Latest
|
||||||
|
LATEST: { value: "time_descending" }
|
||||||
|
});
|
||||||
|
|
||||||
|
const SearchNoteType = Object.freeze({
|
||||||
|
// default
|
||||||
|
ALL: { value: 0 },
|
||||||
|
// only video
|
||||||
|
VIDEO: { value: 1 },
|
||||||
|
// only image
|
||||||
|
IMAGE: { value: 2 }
|
||||||
|
});
|
||||||
@@ -49,16 +49,16 @@ app
|
|||||||
path: 'mention',
|
path: 'mention',
|
||||||
key: 'getNote',
|
key: 'getNote',
|
||||||
description: '获取笔记',
|
description: '获取笔记',
|
||||||
validator: {
|
// validator: {
|
||||||
node_id: {
|
// node_id: {
|
||||||
type: 'string',
|
// type: 'string',
|
||||||
required: true,
|
// required: true,
|
||||||
},
|
// },
|
||||||
xsec_token: {
|
// xsec_token: {
|
||||||
type: 'string',
|
// type: 'string',
|
||||||
required: true,
|
// required: true,
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
isDebug: true,
|
isDebug: true,
|
||||||
})
|
})
|
||||||
.define(async (ctx) => {
|
.define(async (ctx) => {
|
||||||
@@ -108,13 +108,13 @@ app
|
|||||||
.route({
|
.route({
|
||||||
path: 'mention',
|
path: 'mention',
|
||||||
key: 'getMention',
|
key: 'getMention',
|
||||||
description: '获取提及列表',
|
// description: '获取提及列表',
|
||||||
validator: {
|
// validator: {
|
||||||
num: {
|
// num: {
|
||||||
type: 'number',
|
// type: 'number',
|
||||||
required: true,
|
// required: true,
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
})
|
})
|
||||||
.define(async (ctx) => {
|
.define(async (ctx) => {
|
||||||
const num = ctx.query.num;
|
const num = ctx.query.num;
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ import './query/mention.ts'
|
|||||||
import './query/unread.ts';
|
import './query/unread.ts';
|
||||||
import './query/get-userinfo.ts';
|
import './query/get-userinfo.ts';
|
||||||
import './query/get-connections.ts'
|
import './query/get-connections.ts'
|
||||||
|
import './query/query-keys.ts';
|
||||||
|
|
||||||
|
|
||||||
program
|
program
|
||||||
.command('test')
|
.command('test')
|
||||||
.description('test command')
|
.description('test command')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { xhsServices, app, xhsRootClient } from '../index.ts';
|
import { xhsServices, app, xhsRootClient } from '../index.ts';
|
||||||
import { useConfig } from '@kevisual/use-config/env';
|
import { useConfig } from '@kevisual/use-config/env';
|
||||||
const config = useConfig();
|
export const config = useConfig();
|
||||||
import { program } from 'commander';
|
import { program } from 'commander';
|
||||||
|
|
||||||
xhsRootClient.setCookie(config.XHS_ROOT_COOKIE || '');
|
xhsRootClient.setCookie(config.XHS_ROOT_COOKIE || '');
|
||||||
|
|||||||
29
packages/xhs/src/test/query/query-keys.ts
Normal file
29
packages/xhs/src/test/query/query-keys.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// getNoteByKeyword
|
||||||
|
|
||||||
|
import { xhsServices, program, config } from '../common.ts';
|
||||||
|
import util from 'node:util';
|
||||||
|
|
||||||
|
const getNoteByKeyword = async (keyword: string) => {
|
||||||
|
const client = xhsServices.getClient();
|
||||||
|
xhsServices.setSignConfig({
|
||||||
|
signUrl: config.XHS_API_SIGN_URL,
|
||||||
|
});
|
||||||
|
const res = await client.getNoteByKeyword(keyword).then((res) => {
|
||||||
|
console.log(util.inspect(res, { depth: null }));
|
||||||
|
return res;
|
||||||
|
});
|
||||||
|
console.log('type res', typeof res);
|
||||||
|
if (res.code === 0) {
|
||||||
|
console.log('total', res.data.total);
|
||||||
|
if (res.data.notes.length > 0) {
|
||||||
|
console.log('first note desc', res.data.notes[0].desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('get-note-by-keyword <keyword>')
|
||||||
|
.description('get note by keyword')
|
||||||
|
.action(async (keyword: string) => {
|
||||||
|
getNoteByKeyword(keyword);
|
||||||
|
});
|
||||||
879
pnpm-lock.yaml
generated
879
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@ import { config } from '../modules/config.ts';
|
|||||||
const createBaiLian = () => {
|
const createBaiLian = () => {
|
||||||
return new BailianProvider({
|
return new BailianProvider({
|
||||||
baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
|
baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
|
||||||
model: 'qwen3-235b-a22b',
|
model: 'qwen-plus',
|
||||||
apiKey: config.BAILIAN_API_KEY,
|
apiKey: config.BAILIAN_API_KEY,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -17,8 +17,8 @@ console.log('Bailian AI initialized with model:', config.BAILIAN_API_KEY);
|
|||||||
|
|
||||||
export const bailianModel = useContextKey('bailianModel', () => {
|
export const bailianModel = useContextKey('bailianModel', () => {
|
||||||
return {
|
return {
|
||||||
turbo: 'qwen-turbo-2025-04-28',
|
turbo: 'qwen-turbo',
|
||||||
plus: 'qwen-plus-2025-04-28',
|
plus: 'qwen-plus',
|
||||||
a22b235: 'qwen3-235b-a22b',
|
a22b235: 'qwen3-235b-a22b',
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,15 +1,24 @@
|
|||||||
{
|
{
|
||||||
"extends": "@kevisual/types/json/backend.json",
|
"extends": "@kevisual/types/json/backend.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": "./",
|
"module": "NodeNext",
|
||||||
|
"target": "esnext",
|
||||||
|
"baseUrl": ".",
|
||||||
|
"typeRoots": [
|
||||||
|
"./node_modules/@types",
|
||||||
|
"./node_modules/@kevisual/types/index.d.ts"
|
||||||
|
],
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": [
|
"@/*": [
|
||||||
"src/*"
|
"src/*"
|
||||||
|
],
|
||||||
|
"@agent/*": [
|
||||||
|
"agent/*"
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts",
|
"src/**/*",
|
||||||
|
"agent/**/*",
|
||||||
],
|
],
|
||||||
"exclude": [],
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user