uweb/en/searchurl/bingAI/js/bingChatHub.js
2023-04-01 21:07:20 +08:00

483 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

var expUrl = new RegExp('^(https?://)([-a-zA-z0-9]+\\.)+([-a-zA-z0-9]+)+\\S*$');
function timeString() {
var d = new Date();
var year = d.getFullYear();
var month = (d.getMonth() + 1).toString().padStart(2, "0");
var date = d.getDate().toString().padStart(2, "0");
var hour = d.getHours().toString().padStart(2, "0");
var minute = d.getMinutes().toString().padStart(2, "0");
var second = d.getSeconds().toString().padStart(2, "0");
var offset = "+08:00"; // 你可以根据需要修改这个值
var s = year + "-" + month + "-" + date + "T" + hour + ":" + minute + ":" + second + offset;
return s;
}
function getUuidNojian() {
return URL.createObjectURL(new Blob()).split('/')[3].replace(/-/g, '');
}
function getUuid() {
return URL.createObjectURL(new Blob()).split('/')[3];
}
//聊天选项
let chatTypes = {
//更有创造力选项
create: [
"nlu_direct_response_filter",
"deepleo",
"disable_emoji_spoken_text",
"responsible_ai_policy_235",
"enablemm",
"h3imaginative",
"clgalileo",
"gencontentv3",
"telmet",
"jbfv2",
"c2b47e4f",
"dv3sugg"
],
//balance 平衡模式选项
balance: [
"nlu_direct_response_filter",
"deepleo",
"disable_emoji_spoken_text",
"responsible_ai_policy_235",
"enablemm",
"galileo",
"telmet",
"jbfv2",
"c2b47e4f",
"dv3sugg"
],
//精准选项
accurate: [
"nlu_direct_response_filter",
"deepleo",
"disable_emoji_spoken_text",
"responsible_ai_policy_235",
"enablemm",
"h3precise",
"telmet",
"jbfv2",
"c2b47e4f",
"dv3sugg",
"clgalileo"
]
}
//接收消息类型
let allowedMessageTypes = [
"Chat",
"InternalSearchQuery",
"InternalSearchResult",
"Disengaged",
"InternalLoaderMessage",
"RenderCardRequest",
"AdsQuery",
"SemanticSerp",
"GenerateContentQuery",
"SearchQuery"
]
//切片id也不知道是啥意思反正官网的更新了
let sliceIds = [
"semserpsup3",
"styleqnatg",
"lgintsuppcf",
"sydpayajax",
"toneexp",
"327telmet",
"325contents0",
"324jbfv2",
"303hubcancls0",
"321jobsgndv0",
"328throt",
"328postclss0"
]
class SendMessageManager {
//(会话id客户端id签名id是否是开始)
//(string,string,string,boolena)
constructor(conversationId, clientId, conversationSignature,invocationId) {
this.startTime = timeString();
this.invocationId = invocationId==undefined?1:invocationId;
this.conversationId = conversationId;
this.clientId = clientId;
this.conversationSignature = conversationSignature;
this.optionsSets = chatTypes.balance;
}
//chatTypes中的一种
setChatType(chatType) {
this.optionsSets = chatType;
}
//发送json数据
sendJson(chatWebSocket, json) {
let go = JSON.stringify(json) + '\u001e';
chatWebSocket.send(go);
console.log('发送', go)
}
//获取用于发送的握手数据
//(WebSocket)
sendShakeHandsJson(chatWebSocket) {
this.sendJson(chatWebSocket, {
"protocol": "json",
"version": 1
});
}
//获取用于发送的聊天数据
//(WebSocket,sreing)
sendChatMessage(chatWebSocket, chat) {
let pos = getStartProposes();
let previousMessages = [{
"text": getStartMessage(),
"author": "bot",
"adaptiveCards": [],
"suggestedResponses": [{
"text": pos[0],
"contentOrigin": "DeepLeo",
"messageType": "Suggestion",
"messageId": getUuid(),
"offense": "Unknown"
}, {
"text": pos[1],
"contentOrigin": "DeepLeo",
"messageType": "Suggestion",
"messageId": getUuid(),
"offense": "Unknown"
}, {
"text": pos[2],
"contentOrigin": "DeepLeo",
"messageType": "Suggestion",
"messageId": getUuid(),
"offense": "Unknown"
}],
"messageId": getUuid(),
"messageType": "Chat"
}];
let json = {
"arguments": [{
"source": "cib",
"optionsSets": this.optionsSets,
"allowedMessageTypes": allowedMessageTypes,
"sliceIds": sliceIds,
"verbosity": "verbose",
"traceId": getUuidNojian(),
"isStartOfSession": (this.invocationId <= 1) ? true : false,
"message": {
"locale": "zh-CN",
"market": "zh-CN",
"region": "US",
"location": "lat:47.639557;long:-122.128159;re=1000m;",
"locationHints": [
{
"Center": {
"Latitude": 30.474109798833613,
"Longitude": 114.39626256171093
},
"RegionType": 2,
"SourceType": 11
},
{
"country": "United States",
"state": "California",
"city": "Los Angeles",
"zipcode": "90060",
"timezoneoffset": -8,
"dma": 803,
"countryConfidence": 8,
"cityConfidence": 5,
"Center": {
"Latitude": 33.9757,
"Longitude": -118.2564
},
"RegionType": 2,
"SourceType": 1
}
],
"timestamp": this.startTime,
"author": "user",
"inputMethod": "Keyboard",
"text": chat,
"messageType": "Chat"
},
"conversationSignature": this.conversationSignature,
"participant": {
"id": this.clientId
},
"conversationId": this.conversationId,
"previousMessages": (this.invocationId <= 1) ? previousMessages : undefined
}],
"invocationId": this.invocationId.toString(),
"target": "chat",
"type": 4
};
this.sendJson(chatWebSocket, json);
this.invocationId++;
setLastInvocationId(this.invocationId);
}
}
//处理返回消息的类
class ReturnMessage {
//(WebSocket,function:可以不传)
constructor(catWebSocket, lisin) {
this.catWebSocket = catWebSocket;
this.onMessage = [(v) => {
//console.log(JSON.stringify(v))
}];
if ((typeof lisin) == 'function') {
this.regOnMessage(lisin);
}
catWebSocket.onmessage = (mess) => {
//console.log('收到', mess.data);
let sss = mess.data.split('\u001e');
for (let i = 0; i < sss.length; i++) {
if (sss[i] == '') {
continue;
}
for (let j in this.onMessage) {
if ((typeof this.onMessage[j]) == 'function') {
try {
this.onMessage[j](JSON.parse(sss[i]), this);
} catch (e) {
console.warn(e)
}
}
}
}
}
catWebSocket.onclose = (mess) => {
for (let i in this.onMessage) {
if ((typeof this.onMessage[i]) == 'function') {
try {
this.onMessage[i]({
type: 'close',
mess: '连接关闭'
}, this);
} catch (e) {
console.warn(e)
}
}
}
}
catWebSocket.onerror = (mess) => {
console.log(mess);
for (let i in this.onMessage) {
if ((typeof this.onMessage[i]) == 'function') {
try {
this.onMessage[i]({
type: 'error',
mess: mess
}, this);
} catch (e) {
console.warn(e)
}
}
}
}
}
/*
获取消息WebSocket
*/
getCatWebSocket() {
return this.catWebSocket;
}
/**
* 注册收到消息监听器
*/
//(function(json,ReturnMessage))
regOnMessage(theFun) {
this.onMessage[this.onMessage.length] = theFun;
}
}
//处理聊天的类
class Chat {
//theChatType chatTypes变量中的其中一个
//invocationId 可以不传
//(string,ture|false|'repeat',string,string,string,theChatType,int|undefined)
constructor(magicUrl, chatWithMagic, charID, clientId, conversationSignature, theChatType,invocationId) {
this.magicUrl = magicUrl;
this.chatWithMagic = chatWithMagic;
this.sendMessageManager = new SendMessageManager(charID, clientId, conversationSignature,invocationId);
if (theChatType) {
this.sendMessageManager.setChatType(theChatType);
}
}
/**
* 返回
{
ok:true|false
message:显示消息,
obj:ReturnMessage对象
}
当ok等于false时不返回ReturnMessage
* 参数 消息string,当收到消息的函数,当关闭时函数
*/
//(string,function:可以不传)
sendMessage(message, onMessage) {
try {
let restsrstUrl = 'wss://sydney.bing.com/sydney/ChatHub';
if (this.chatWithMagic==true) {
restsrstUrl = URLTrue(this.magicUrl.replace('http', 'ws'), "ChatHub");
}
let chatWebSocket = new WebSocket(restsrstUrl);
chatWebSocket.onopen = () => {
this.sendMessageManager.sendShakeHandsJson(chatWebSocket);
this.sendMessageManager.sendChatMessage(chatWebSocket, message);
}
return {
ok: true,
message: 'ok',
obj: new ReturnMessage(chatWebSocket, onMessage),
chatWithMagic: this.chatWithMagic==true?true:false
};
} catch (e) {
console.warn(e)
return {
ok: false,
message: "发生错误,可能是网络连接错误:" + e.message
};
}
}
}
/***
* 补齐url
*/
function URLTrue(magicUrl, thiePath) {
let url = magicUrl;
if (!url.endsWith('/')) {
url = url + '/';
}
url = url + thiePath;
return url;
}
//获取newbing权限
async function getPower() {
//设置cookies到魔法链接
let magicUrl = await getMagicUrl();
if (!magicUrl) {
return {
ok: false,
message: "需要设置魔法链接才能获取权限哦!"
};
}
if (!expUrl.test(magicUrl)) {
return {
ok: false,
message: "魔法链接不正确!请修改魔法链接。"
};
}
await copyCookies(magicUrl);
try {
await fetch(URLTrue(magicUrl, 'bingcopilotwaitlist'));
return {
ok: true,
message: "ok"
};
} catch (e) {
console.warn(e);
return {
ok: false,
message: "发生错误,可能是魔法链接无法链接:" + e.message
};
}
}
async function copyCookies(magicUrl) {}
//创建一个新对话
/**
返回结构如果ok等于false则无chat对象
{
ok:true|false,
message:显示消息,
obj:Cat对象
}
*/
async function createChat(theChatType) {
//设置cookies到魔法链接
let chatWithMagic = await getChatHubWithMagic();
let magicUrl = await getMagicUrl();
if (!magicUrl) {
return {
ok: false,
message: "需要设置魔法链接才能聊天哦!"
};
}
if (!expUrl.test(magicUrl)) {
return {
ok: false,
message: "魔法链接不正确!请修改魔法链接。"
};
}
let restartNewChat = document.getElementById('restartNewChat');
if(chatWithMagic=='repeat'){//如果是聊天复用
restartNewChat.classList.remove('onShow');
let resjson = await getLastChatJson();
if(resjson){//如果没有上次聊天或上次聊天已经失效就不返回,继续走创建聊天流程
let invocationId = await getLastChatInvocationId();
if(!invocationId){
invocationId = 1;
}
return {
ok: true,
message: 'ok',
obj: new Chat(magicUrl, chatWithMagic, resjson.conversationId, resjson.clientId, resjson.conversationSignature, theChatType,invocationId)
};
}
}
try {
await copyCookies(magicUrl);
let res = await fetch(URLTrue(magicUrl, 'Create'));
let resjson = await res.json();
if (!resjson.result) {
console.warn(resjson);
return {
ok: false,
message: "未知错误!"
};
}
if (resjson.result.value != 'Success') {
let type = resjson.result.value;
let mess = resjson.result.message;
if (resjson.result.value == 'UnauthorizedRequest') {
type = 'NoLogin'
mess = '首先你需要在bing登录微软账号请前往 https://cn.bing.com/ 登录微软账号。';
} else if (resjson.result.value == 'Forbidden') {
type = 'NoPower'
mess = '你还没有获得NewBing的使用权限';
}
console.warn(resjson);
return {
ok: false,
type: type,
message: mess
};
}
//保存成功的聊天
setLastChatJson(resjson);
return {
ok: true,
message: 'ok',
obj: new Chat(magicUrl, chatWithMagic, resjson.conversationId, resjson.clientId, resjson.conversationSignature, theChatType)
};
} catch (e) {
console.warn(e);
return {
ok: false,
message: "发生错误,可能是魔法链接无法链接:" + e.message
};
}
}