diff --git a/apps/chat.js b/apps/chat.js index e20c942..8784462 100644 --- a/apps/chat.js +++ b/apps/chat.js @@ -66,7 +66,7 @@ import { SendDiceTool } from '../utils/tools/SendDiceTool.js' import { SendAvatarTool } from '../utils/tools/SendAvatarTool.js' import { SendMessageToSpecificGroupOrUserTool } from '../utils/tools/SendMessageToSpecificGroupOrUserTool.js' import { SetTitleTool } from '../utils/tools/SetTitleTool.js' -import { createCaptcha, solveCaptcha } from '../utils/bingCaptcha.js' +import { createCaptcha, solveCaptcha, solveCaptchaOneShot } from '../utils/bingCaptcha.js' try { await import('emoji-strip') @@ -233,7 +233,7 @@ export class chatgpt extends plugin { reg: '^#chatgpt删除对话', fnc: 'deleteConversation', permission: 'master' - }, + } // { // reg: '^#chatgpt必应验证码', // fnc: 'bingCaptcha' @@ -1678,42 +1678,34 @@ export class chatgpt extends plugin { } catch (error) { logger.error(error) const message = error?.message || error?.data?.message || error || '出错了' - // if (message && typeof message === 'string' && message.indexOf('CaptchaChallenge') > -1) { - // if (bingToken) { - // // let { id, regionId, image } = await createCaptcha(e, bingToken) - // // e.bingCaptchaId = id - // // e.token = bingToken - // // e.regionId = regionId - // // const { - // // conversationSignature, - // // conversationId, - // // clientId - // // } = error?.conversation - // // e.bingConversation = { - // // conversationSignature, - // // conversationId, - // // clientId - // // } - // return { - // text: '请在60秒内输入下面图片以通过必应人机验证', - // image, - // error: true, - // token: bingToken - // } - // } - // } else - if (message && typeof message === 'string' && message.indexOf('限流') > -1) { - throttledTokens.push(bingToken) - let bingTokens = JSON.parse(await redis.get('CHATGPT:BING_TOKENS')) - const badBingToken = bingTokens.findIndex(element => element.Token === bingToken) - const now = new Date() - const hours = now.getHours() - now.setHours(hours + 6) - bingTokens[badBingToken].State = '受限' - bingTokens[badBingToken].DisactivationTime = now - await redis.set('CHATGPT:BING_TOKENS', JSON.stringify(bingTokens)) + if (message && typeof message === 'string' && message.indexOf('CaptchaChallenge') > -1) { + if (bingToken) { + await e.reply('出现必应验证码,尝试解决中') + try { + let captchaResolveResult = await solveCaptchaOneShot(bingToken) + if (captchaResolveResult?.success) { + await e.reply('验证码已解决') + } else { + await e.reply('验证码解决失败') + } + } catch (err) { + logger.error(err) + await e.reply('验证码解决失败') + } + } + } else + if (message && typeof message === 'string' && message.indexOf('限流') > -1) { + throttledTokens.push(bingToken) + let bingTokens = JSON.parse(await redis.get('CHATGPT:BING_TOKENS')) + const badBingToken = bingTokens.findIndex(element => element.Token === bingToken) + const now = new Date() + const hours = now.getHours() + now.setHours(hours + 6) + bingTokens[badBingToken].State = '受限' + bingTokens[badBingToken].DisactivationTime = now + await redis.set('CHATGPT:BING_TOKENS', JSON.stringify(bingTokens)) // 不减次数 - } else if (message && typeof message === 'string' && message.indexOf('UnauthorizedRequest') > -1) { + } else if (message && typeof message === 'string' && message.indexOf('UnauthorizedRequest') > -1) { // token过期了 // let bingTokens = JSON.parse(await redis.get('CHATGPT:BING_TOKENS')) // const badBingToken = bingTokens.findIndex(element => element.Token === bingToken) @@ -1729,12 +1721,12 @@ export class chatgpt extends plugin { // bingTokens[badBingToken].exception = 1 // } // await redis.set('CHATGPT:BING_TOKENS', JSON.stringify(bingTokens)) - logger.warn(`token${bingToken}疑似不存在或已过期,再试试`) - retry = retry - 0.1 - } else { - retry-- - errorMessage = message === 'Timed out waiting for response. Try enabling debug mode to see more information.' ? (reply ? `${reply}\n不行了,我的大脑过载了,处理不过来了!` : '必应的小脑瓜不好使了,不知道怎么回答!') : message - } + logger.warn(`token${bingToken}疑似不存在或已过期,再试试`) + retry = retry - 0.1 + } else { + retry-- + errorMessage = message === 'Timed out waiting for response. Try enabling debug mode to see more information.' ? (reply ? `${reply}\n不行了,我的大脑过载了,处理不过来了!` : '必应的小脑瓜不好使了,不知道怎么回答!') : message + } } } while (retry > 0) if (errorMessage) { diff --git a/guoba.support.js b/guoba.support.js index 0d10068..9153cf5 100644 --- a/guoba.support.js +++ b/guoba.support.js @@ -465,6 +465,12 @@ export function supportGuoba () { bottomHelpMessage: '【一般情况无需也不建议开启】默认情况下仅创建对话走反代,对话时仍然直连微软。开启本选项将使对话过程也走反,需反代支持', component: 'Switch' }, + { + field: 'bingCaptchaOneShotUrl', + label: '必应验证码pass服务', + bottomHelpMessage: '必应出验证码会自动用该服务绕过', + component: 'Input' + }, { field: 'sydneyMood', label: '情感显示', diff --git a/utils/bingCaptcha.js b/utils/bingCaptcha.js index 3a6fe23..8aa32ea 100644 --- a/utils/bingCaptcha.js +++ b/utils/bingCaptcha.js @@ -1,9 +1,9 @@ import fetch from 'node-fetch' // this file is deprecated - -import { Config } from './config.js' +import {Config} from './config.js' import HttpsProxyAgent from 'https-proxy-agent' + const newFetch = (url, options = {}) => { const defaultOptions = Config.proxy ? { @@ -60,3 +60,27 @@ export async function solveCaptcha (id, regionId, text, token) { } } } + +export async function solveCaptchaOneShot (token) { + if (!token) { + throw new Error('no token') + } + let solveUrl = Config.bingCaptchaOneShotUrl + if (!solveUrl) { + throw new Error('no captcha source') + } + let result = await fetch(solveUrl, { + method: 'POST', + body: { + _U: token + } + }) + if (result.status === 200) { + return await result.json() + } else { + return { + success: false, + error: result.statusText + } + } +} diff --git a/utils/config.js b/utils/config.js index 808d366..36510bc 100644 --- a/utils/config.js +++ b/utils/config.js @@ -131,6 +131,7 @@ const defaultConfig = { serpSource: 'ikechan8370', extraUrl: 'https://cpe.ikechan8370.com', smartMode: false, + bingCaptchaOneShotUrl: 'http://bingcaptcha.ikechan8370.com/bing', version: 'v2.7.3' } const _path = process.cwd()