bingChatHub.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. var expUrl = new RegExp('^(https?://)([-a-zA-z0-9]+\\.)+([-a-zA-z0-9]+)+\\S*$');
  2. function getUuidNojian() {
  3. return URL.createObjectURL(new Blob()).split('/')[3].replace(/-/g, '');
  4. }
  5. class SendMessageManager {
  6. //(会话id,客户端id,签名id,是否是开始)
  7. //(string,string,string,boolena)
  8. constructor(conversationId, clientId, conversationSignature,invocationId) {
  9. this.invocationId = invocationId==undefined?1:invocationId;
  10. this.conversationId = conversationId;
  11. this.clientId = clientId;
  12. this.conversationSignature = conversationSignature;
  13. this.optionsSets = chatTypes.balance;
  14. }
  15. //chatTypes中的一种
  16. setChatType(chatType) {
  17. this.optionsSets = chatType;
  18. }
  19. //发送json数据
  20. sendJson(chatWebSocket, json) {
  21. let go = JSON.stringify(json) + '\u001e';
  22. chatWebSocket.send(go);
  23. console.log('发送', go)
  24. }
  25. //获取用于发送的握手数据
  26. //(WebSocket)
  27. sendShakeHandsJson(chatWebSocket) {
  28. this.sendJson(chatWebSocket, {
  29. "protocol": "json",
  30. "version": 1
  31. });
  32. }
  33. //获取用于发送的聊天数据
  34. //(WebSocket,sreing)
  35. async sendChatMessage(chatWebSocket, chat) {
  36. let optionsSets = chatTypes[this.optionsSets];
  37. let json = {
  38. "arguments": [{
  39. "source": source,
  40. "optionsSets": optionsSets,
  41. "allowedMessageTypes": allowedMessageTypes,
  42. "sliceIds": sliceIds,
  43. "verbosity": "verbose",
  44. "traceId": getUuidNojian(),
  45. "isStartOfSession": (this.invocationId <= 1) ? true : false,
  46. "message": await generateMessages(this,chat),
  47. "conversationSignature": this.conversationSignature,
  48. "participant": {
  49. "id": this.clientId
  50. },
  51. "conversationId": this.conversationId,
  52. "previousMessages": (this.invocationId <= 1) ? await getPreviousMessages() : undefined
  53. }],
  54. "invocationId": this.invocationId.toString(),
  55. "target": "chat",
  56. "type": 4
  57. };
  58. this.sendJson(chatWebSocket, json);
  59. this.invocationId++;
  60. }
  61. }
  62. //处理返回消息的类
  63. class ReturnMessage {
  64. //(WebSocket,function:可以不传)
  65. constructor(catWebSocket, lisin) {
  66. this.catWebSocket = catWebSocket;
  67. this.onMessage = [(v) => {
  68. //console.log(JSON.stringify(v))
  69. }];
  70. if ((typeof lisin) == 'function') {
  71. this.regOnMessage(lisin);
  72. }
  73. catWebSocket.onmessage = (mess) => {
  74. //console.log('收到', mess.data);
  75. let sss = mess.data.split('\u001e');
  76. for (let i = 0; i < sss.length; i++) {
  77. if (sss[i] == '') {
  78. continue;
  79. }
  80. for (let j in this.onMessage) {
  81. if ((typeof this.onMessage[j]) == 'function') {
  82. try {
  83. this.onMessage[j](JSON.parse(sss[i]), this);
  84. } catch (e) {
  85. console.warn(e)
  86. }
  87. }
  88. }
  89. }
  90. }
  91. catWebSocket.onclose = (mess) => {
  92. for (let i in this.onMessage) {
  93. if ((typeof this.onMessage[i]) == 'function') {
  94. try {
  95. this.onMessage[i]({
  96. type: 'close',
  97. mess: '连接关闭'
  98. }, this);
  99. } catch (e) {
  100. console.warn(e)
  101. }
  102. }
  103. }
  104. }
  105. catWebSocket.onerror = (mess) => {
  106. console.log(mess);
  107. for (let i in this.onMessage) {
  108. if ((typeof this.onMessage[i]) == 'function') {
  109. try {
  110. this.onMessage[i]({
  111. type: 'error',
  112. mess: mess
  113. }, this);
  114. } catch (e) {
  115. console.warn(e)
  116. }
  117. }
  118. }
  119. }
  120. }
  121. /*
  122. 获取消息WebSocket
  123. */
  124. getCatWebSocket() {
  125. return this.catWebSocket;
  126. }
  127. /**
  128. * 注册收到消息监听器
  129. */
  130. //(function(json,ReturnMessage))
  131. regOnMessage(theFun) {
  132. this.onMessage[this.onMessage.length] = theFun;
  133. }
  134. }
  135. //处理聊天的类
  136. class Chat {
  137. //theChatType chatTypes变量中的其中一个
  138. //invocationId 可以不传
  139. //(string,ture|false|'repeat',string,string,string,theChatType,int|undefined)
  140. constructor(magicUrl, chatWithMagic, charID, clientId, conversationSignature, theChatType,invocationId) {
  141. this.magicUrl = magicUrl;
  142. this.chatWithMagic = chatWithMagic;
  143. this.sendMessageManager = new SendMessageManager(charID, clientId, conversationSignature,invocationId);
  144. if (theChatType) {
  145. this.sendMessageManager.setChatType(theChatType);
  146. }
  147. }
  148. /**
  149. * 返回
  150. {
  151. ok:true|false,
  152. message:显示消息,
  153. obj:ReturnMessage对象
  154. }
  155. 当ok等于false时,不返回ReturnMessage
  156. * 参数 消息string,当收到消息的函数,当关闭时函数
  157. */
  158. //(string,function:可以不传)
  159. sendMessage(message, onMessage) {
  160. try {
  161. //let restsrstUrl = 'wss://sydney.bing.com/sydney/ChatHub';
  162. //if (this.chatWithMagic==true)
  163. let restsrstUrl = this.magicUrl.replace('http', 'ws')+"sydney/ChatHub";
  164. let chatWebSocket = new WebSocket(restsrstUrl);
  165. chatWebSocket.onopen = () => {
  166. this.sendMessageManager.sendShakeHandsJson(chatWebSocket);
  167. this.sendMessageManager.sendChatMessage(chatWebSocket, message);
  168. }
  169. return {
  170. ok: true,
  171. message: 'ok',
  172. obj: new ReturnMessage(chatWebSocket, onMessage),
  173. chatWithMagic: this.chatWithMagic==true?true:false
  174. };
  175. } catch (e) {
  176. console.warn(e)
  177. return {
  178. ok: false,
  179. message: "发生错误,可能是网络连接错误:" + e.message
  180. };
  181. }
  182. }
  183. }
  184. function URLTrue(url, thiePath) {
  185. return url + thiePath;
  186. }
  187. //获取newbing权限
  188. async function getPower() {}
  189. async function copyCookies(magicUrl) {}
  190. //创建一个新对话
  191. /**
  192. 返回结构,如果ok等于false则无chat对象
  193. {
  194. ok:true|false,
  195. message:显示消息,
  196. obj:Cat对象
  197. }
  198. */
  199. async function createChat(theChatType) {
  200. let chatWithMagic = await getChatHubWithMagic();
  201. let magicUrl = await getMagicUrl();
  202. let restartNewChat = document.getElementById('restartNewChat');
  203. if(chatWithMagic=='repeat'){//如果是聊天复用
  204. restartNewChat.classList.remove('onShow');
  205. let resjson = await getLastChatJson();
  206. if(resjson){//如果没有上次聊天或上次聊天已经失效就不返回,继续走创建聊天流程
  207. let invocationId = await getLastChatInvocationId();
  208. if(!invocationId){
  209. invocationId = 1;
  210. }
  211. return {
  212. ok: true,
  213. message: 'ok',
  214. obj: new Chat(magicUrl, chatWithMagic, resjson.conversationId, resjson.clientId, resjson.conversationSignature, theChatType,invocationId)
  215. };
  216. }
  217. }
  218. let mes;
  219. do {
  220. try {
  221. let url = URLTrue(magicUrl,'turing/conversation/create');
  222. let res = await fetch(url);
  223. if(!res.ok){
  224. if(res.headers.has('cf-mitigated')){
  225. let challengeUrl = `${magicUrl}/challenge?`+location.href;
  226. location.href=challengeUrl;
  227. return;
  228. }
  229. mes = `Error code: ${res.status} ${res.statusText}`;
  230. break;
  231. }
  232. let resjson = await res.json();
  233. if (!resjson.result || resjson.result.value != 'Success') {
  234. mes = resjson;
  235. break;
  236. }
  237. //保存成功的聊天
  238. setLastChatJson(resjson);
  239. return {
  240. ok: true,
  241. message: 'ok',
  242. obj: new Chat(magicUrl, chatWithMagic, resjson.conversationId, resjson.clientId, resjson.conversationSignature, theChatType)
  243. };
  244. } catch (e) {mes = e.message;}
  245. }while(false);
  246. return {
  247. ok: false,
  248. message: mes
  249. };
  250. }