diff --git a/README.md b/README.md index 049ccb9a..1bc4107c 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ https://bing.github1s.tk ## 环境和依赖 - Node.js >= 18 -- Bing AI 的[身份信息](#如何获取-BING_HEADER)) +- Bing AI 的[用户信息](#如何获取-BING_HEADER)) ## 安装和使用 diff --git a/src/components/chat-notification.tsx b/src/components/chat-notification.tsx index 012e0768..a1401368 100644 --- a/src/components/chat-notification.tsx +++ b/src/components/chat-notification.tsx @@ -59,7 +59,13 @@ function getAction(error: ChatError, reset: () => void) { if (error.code === ErrorCode.BING_UNAUTHORIZED) { reset() return ( - 没有获取到身份信息或身份信息失效,点此重新设置 + 没有获取到用户信息或用户信息失效,点此重新设置 + ) + } + if (error.code === ErrorCode.BING_IMAGE_UNAUTHORIZED) { + reset() + return ( + 画图需要用户信息,系统没有获取到有效的用户信息,点此设置 ) } return error.message diff --git a/src/components/chat-panel.tsx b/src/components/chat-panel.tsx index 5aaee3ed..09638fb6 100644 --- a/src/components/chat-panel.tsx +++ b/src/components/chat-panel.tsx @@ -121,7 +121,7 @@ export function ChatPanel({ rows={1} value={input} onChange={e => setInput(e.target.value.slice(0, 8000))} - placeholder={voiceListening ? '持续对话中...对话完成说“发送”即可' : 'Shift + Enter 换行'} + placeholder={voiceListening ? '持续对话中...对话完成说“发送”即可' : 'Shift + Enter 换行,输入 / 选择提示词'} spellCheck={false} className="message-input min-h-[24px] w-full text-base resize-none bg-transparent focus-within:outline-none" /> diff --git a/src/components/prompts/form.tsx b/src/components/prompts/form.tsx index 75a73062..8ff36c2c 100644 --- a/src/components/prompts/form.tsx +++ b/src/components/prompts/form.tsx @@ -160,7 +160,7 @@ function CommunityPrompts(props: { insertPrompt: (text: string) => void }) { return ( <>
- {remotePrompts.map((prompt, index) => ( + {remotePrompts?.length ? remotePrompts.map((prompt, index) => ( void }) { insertPrompt={props.insertPrompt} addToLocal={() => copyToLocal(prompt)} /> - ))} + )) : }
提示词贡献地址: diff --git a/src/components/settings.tsx b/src/components/settings.tsx index df0b7223..3aa9e821 100644 --- a/src/components/settings.tsx +++ b/src/components/settings.tsx @@ -90,7 +90,7 @@ export function Settings() { className={`${imageOnly ? 'translate-x-6' : 'translate-x-1'} inline-block h-4 w-4 transform rounded-full bg-white transition`} /> - 身份信息仅用于画图(账号异常时使用) + 用户信息仅用于画图(账号异常时使用) {!imageOnly && ( diff --git a/src/lib/bots/bing/index.ts b/src/lib/bots/bing/index.ts index e9df5bd9..4c43bf49 100644 --- a/src/lib/bots/bing/index.ts +++ b/src/lib/bots/bing/index.ts @@ -300,31 +300,33 @@ export class BingWebBot { } private async createImage(prompt: string, id: string) { - try { - const headers = { - 'Accept-Encoding': 'gzip, deflate, br, zsdch', - 'User-Agent': this.ua, - 'x-ms-useragent': 'azsdk-js-api-client-factory/1.0.0-beta.1 core-rest-pipeline/1.10.0 OS/Win32', - cookie: this.cookie, - } - const query = new URLSearchParams({ - prompt, - id + const headers = { + 'Accept-Encoding': 'gzip, deflate, br, zsdch', + 'User-Agent': this.ua, + 'x-ms-useragent': 'azsdk-js-api-client-factory/1.0.0-beta.1 core-rest-pipeline/1.10.0 OS/Win32', + cookie: this.cookie, + } + const query = new URLSearchParams({ + prompt, + id + }) + const response = await fetch(this.endpoint + '/api/image?' + query.toString(), + { + method: 'POST', + headers, + mode: 'cors', + credentials: 'include' + }) + .then(async (response) => { + if (response.status == 200) { + return response.text(); + } else { + throw new ChatError(String(await response.text()), ErrorCode.BING_IMAGE_UNAUTHORIZED) + } }) - const response = await fetch(this.endpoint + '/api/image?' + query.toString(), - { - method: 'POST', - headers, - mode: 'cors', - credentials: 'include' - }) - .then(res => res.text()) - if (response) { - this.lastText += '\n' + response - } - } catch (err) { - console.error('Create Image Error', err) + if (response) { + this.lastText += '\n' + response } } @@ -397,6 +399,12 @@ export class BingWebBot { debug('bing event', event) if (event.type === 3) { await Promise.all(this.asyncTasks) + .catch(error => { + params.onEvent({ + type: 'ERROR', + error: error instanceof ChatError ? error : new ChatError('Catch Error', ErrorCode.UNKOWN_ERROR), + }) + }) this.asyncTasks = [] params.onEvent({ type: 'UPDATE_ANSWER', data: { text: this.lastText } }) params.onEvent({ type: 'DONE' }) diff --git a/src/lib/bots/bing/types.ts b/src/lib/bots/bing/types.ts index fa7d8010..d57175fb 100644 --- a/src/lib/bots/bing/types.ts +++ b/src/lib/bots/bing/types.ts @@ -11,6 +11,7 @@ export enum BingConversationStyle { export enum ErrorCode { CONVERSATION_LIMIT = 'CONVERSATION_LIMIT', BING_UNAUTHORIZED = 'BING_UNAUTHORIZED', + BING_IMAGE_UNAUTHORIZED = 'BING_IMAGE_UNAUTHORIZED', BING_IP_FORBIDDEN = 'BING_IP_FORBIDDEN', BING_TRY_LATER = 'BING_TRY_LATER', BING_FORBIDDEN = 'BING_FORBIDDEN', diff --git a/src/lib/bots/bing/utils.ts b/src/lib/bots/bing/utils.ts index 53e93084..6f98f2fb 100644 --- a/src/lib/bots/bing/utils.ts +++ b/src/lib/bots/bing/utils.ts @@ -34,16 +34,20 @@ export const websocketUtils = { } export async function createImage(prompt: string, id: string, headers: HeadersInit): Promise { - const { headers: responseHeaders } = await fetch(`https://www.bing.com/images/create?partner=sydney&re=1&showselective=1&sude=1&kseed=7000&SFX=&q=${encodeURIComponent(prompt)}&iframeid=${id}`, + const { headers: responseHeaders } = await fetch(`https://www.bing.com/images/create?partner=sydney&showselective=1&sude=1&kseed=8500&SFX=4&q=${encodeURIComponent(prompt)}&iframeid=${id}`, { method: 'HEAD', - headers, + headers: { + ...headers, + Referer: 'https://www.bing.com/search?q=Bing+AI&showconv=1', + 'Sec-Fetch-Dest': 'iframe', + }, redirect: 'manual' }, ); if (!/&id=([^&]+)$/.test(responseHeaders.get('location') || '')) { - throw new Error(`CookieError`) + throw new Error(`没有登录或登录已过期`) } const resultId = RegExp.$1; @@ -66,7 +70,7 @@ export async function createImage(prompt: string, id: string, headers: HeadersIn export async function* streamAsyncIterable(stream: ReadableStream) { - const reader = stream.getReader() +const reader = stream.getReader() try { while (true) { const { done, value } = await reader.read() @@ -81,4 +85,3 @@ export async function* streamAsyncIterable(stream: ReadableStream) { } export const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)) - diff --git a/src/pages/api/image.ts b/src/pages/api/image.ts index 466d4dfc..6ba2c252 100644 --- a/src/pages/api/image.ts +++ b/src/pages/api/image.ts @@ -28,17 +28,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) }) res.end(response) } catch (e) { - if (/CookieError/.test(`${e}`)) { - res.writeHead(200, { - 'Content-Type': 'text/plain; charset=UTF-8', - }) - return res.end(`[没有身份信息或身份信息无效,请重新设置](#dialog="settings")`) - } - res.json({ - result: { - value: 'Error', - message: `${e}` - } + res.writeHead(500, { + 'Content-Type': 'text/plain; charset=UTF-8', }) + return res.end(`${e}`) } }