163 行
5.0 KiB
TypeScript
163 行
5.0 KiB
TypeScript
import {v4 as uuidv4} from 'uuid';
|
|
//@ts-ignore
|
|
import UserAgent from 'user-agents';
|
|
import tlsClient from 'tls-client';
|
|
import {Session} from "tls-client/dist/esm/sessions";
|
|
import {Params} from "tls-client/dist/esm/types";
|
|
import {parseJSON, toEventCB, toEventStream} from "../../utils";
|
|
import {Chat, ChatOptions, Request, Response, ResponseStream} from "../base";
|
|
|
|
const userAgent = new UserAgent();
|
|
|
|
interface IRequestOptions {
|
|
page?: number;
|
|
count?: number;
|
|
safeSearch?: string;
|
|
onShoppingPage?: string;
|
|
mkt?: string;
|
|
responseFilter?: string;
|
|
domain?: string;
|
|
queryTraceId?: string | null;
|
|
chat?: any[] | null;
|
|
includeLinks?: string;
|
|
detailed?: string;
|
|
debug?: string;
|
|
proxy?: string | null;
|
|
}
|
|
|
|
interface SearchResult {
|
|
search: {
|
|
third_party_search_results: {
|
|
name: string,
|
|
url: string,
|
|
displayUrl: string,
|
|
snippet: string,
|
|
language: null | string,
|
|
thumbnailUrl: string,
|
|
isFamilyFriendly: null | boolean,
|
|
isNavigational: null | boolean,
|
|
snmix_link: null | string
|
|
}[],
|
|
rankings: {
|
|
pole: null,
|
|
sidebar: null,
|
|
mainline: {
|
|
answerType: string,
|
|
resultIndex: number,
|
|
value: {
|
|
id: string
|
|
}
|
|
}[]
|
|
},
|
|
query_context: {
|
|
spelling: null,
|
|
originalQuery: string
|
|
},
|
|
third_party_web_results_source: number
|
|
},
|
|
time: number,
|
|
query: string,
|
|
exactAbTestSlices: {
|
|
abUseQueryRewriter: string
|
|
}
|
|
}
|
|
|
|
export class You extends Chat {
|
|
private session: Session;
|
|
|
|
constructor(props?: ChatOptions) {
|
|
super(props);
|
|
this.session = new tlsClient.Session({clientIdentifier: 'chrome_108'});
|
|
this.session.headers = this.getHeaders();
|
|
if (this.options?.proxy) {
|
|
this.session.proxy = this.options.proxy;
|
|
}
|
|
}
|
|
|
|
private async request(req: Request) {
|
|
let {
|
|
page = 1,
|
|
count = 10,
|
|
safeSearch = 'Moderate',
|
|
onShoppingPage = 'False',
|
|
mkt = '',
|
|
responseFilter = 'WebPages,Translations,TimeZone,Computation,RelatedSearches',
|
|
domain = 'youchat',
|
|
queryTraceId = null,
|
|
chat = null,
|
|
includeLinks = "False",
|
|
detailed = "False",
|
|
debug = "False",
|
|
} = req.options || {};
|
|
if (!chat) {
|
|
chat = [];
|
|
}
|
|
return await this.session.get(
|
|
'https://you.com/api/streamingSearch', {
|
|
params: {
|
|
q: req.prompt,
|
|
page: page + '',
|
|
count: count + '',
|
|
safeSearch: safeSearch + '',
|
|
onShoppingPage: onShoppingPage + '',
|
|
mkt: mkt + '',
|
|
responseFilter: responseFilter + '',
|
|
domain: domain + '',
|
|
queryTraceId: queryTraceId || uuidv4(),
|
|
chat: JSON.stringify(chat),
|
|
} as Params,
|
|
}
|
|
);
|
|
}
|
|
|
|
public async askStream(req: Request): Promise<ResponseStream> {
|
|
const response = await this.request(req);
|
|
return {text: toEventStream(response.content), other: {}}
|
|
}
|
|
|
|
public async ask(
|
|
req: Request): Promise<Response> {
|
|
const response = await this.request(req);
|
|
return new Promise(resolve => {
|
|
const res: Response = {
|
|
text: '',
|
|
other: {},
|
|
};
|
|
toEventCB(response.content, (eventName, data) => {
|
|
let obj: any;
|
|
switch (eventName) {
|
|
case 'youChatToken':
|
|
obj = parseJSON(data,{}) as any;
|
|
res.text += obj.youChatToken;
|
|
break;
|
|
case 'done':
|
|
resolve(res);
|
|
return;
|
|
default:
|
|
obj = parseJSON(data,{}) as any;
|
|
res.other[eventName] = obj;
|
|
return;
|
|
}
|
|
});
|
|
})
|
|
}
|
|
|
|
getHeaders(): { [key: string]: string } {
|
|
return {
|
|
authority: 'you.com',
|
|
accept: 'text/event-stream',
|
|
'accept-language': 'en,fr-FR;q=0.9,fr;q=0.8,es-ES;q=0.7,es;q=0.6,en-US;q=0.5,am;q=0.4,de;q=0.3',
|
|
'cache-control': 'no-cache',
|
|
referer: 'https://you.com/search?q=who+are+you&tbm=youchat',
|
|
'sec-ch-ua': '"Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"',
|
|
'sec-ch-ua-mobile': '?0',
|
|
'sec-ch-ua-platform': '"Windows"',
|
|
'sec-fetch-dest': 'empty',
|
|
'sec-fetch-mode': 'cors',
|
|
'sec-fetch-site': 'same-origin',
|
|
cookie: `safesearch_guest=Moderate; uuid_guest=${uuidv4()}`,
|
|
'user-agent': userAgent.toString(),
|
|
};
|
|
}
|
|
}
|