mirror of
https://github.com/wassname/chatGPTBox.git
synced 2026-07-09 06:21:40 +08:00
275 lines
8.5 KiB
JavaScript
275 lines
8.5 KiB
JavaScript
import Browser from 'webextension-polyfill'
|
|
import { v4 as uuidv4 } from 'uuid'
|
|
import {
|
|
deleteConversation,
|
|
generateAnswersWithChatgptWebApi,
|
|
sendMessageFeedback,
|
|
} from './apis/chatgpt-web'
|
|
import { generateAnswersWithBingWebApi } from './apis/bing-web.mjs'
|
|
import {
|
|
generateAnswersWithChatgptApi,
|
|
generateAnswersWithGptCompletionApi,
|
|
} from './apis/openai-api'
|
|
import { generateAnswersWithCustomApi } from './apis/custom-api.mjs'
|
|
import { generateAnswersWithAzureOpenaiApi } from './apis/azure-openai-api.mjs'
|
|
import { generateAnswersWithWaylaidwandererApi } from './apis/waylaidwanderer-api.mjs'
|
|
import { generateAnswersWithPoeWebApi } from './apis/poe-web.mjs'
|
|
import {
|
|
azureOpenAiApiModelKeys,
|
|
bingWebModelKeys,
|
|
chatgptApiModelKeys,
|
|
chatgptWebModelKeys,
|
|
clearOldAccessToken,
|
|
customApiModelKeys,
|
|
defaultConfig,
|
|
getPreferredLanguageKey,
|
|
getUserConfig,
|
|
githubThirdPartyApiModelKeys,
|
|
gptApiModelKeys,
|
|
Models,
|
|
poeWebModelKeys,
|
|
setAccessToken,
|
|
} from '../config/index.mjs'
|
|
import { config as menuConfig } from '../content-script/menu-tools'
|
|
import { t, changeLanguage } from 'i18next'
|
|
import '../_locales/i18n'
|
|
import { openUrl } from '../utils/open-url'
|
|
|
|
async function getChatGptAccessToken() {
|
|
await clearOldAccessToken()
|
|
const userConfig = await getUserConfig()
|
|
if (userConfig.accessToken) {
|
|
return userConfig.accessToken
|
|
} else {
|
|
const cookie = (await Browser.cookies.getAll({ url: 'https://chat.openai.com/' }))
|
|
.map((cookie) => {
|
|
return `${cookie.name}=${cookie.value}`
|
|
})
|
|
.join('; ')
|
|
const resp = await fetch('https://chat.openai.com/api/auth/session', {
|
|
headers: {
|
|
Cookie: cookie,
|
|
},
|
|
})
|
|
if (resp.status === 403) {
|
|
throw new Error('CLOUDFLARE')
|
|
}
|
|
const data = await resp.json().catch(() => ({}))
|
|
if (!data.accessToken) {
|
|
throw new Error('UNAUTHORIZED')
|
|
}
|
|
await setAccessToken(data.accessToken)
|
|
return data.accessToken
|
|
}
|
|
}
|
|
|
|
async function getBingAccessToken() {
|
|
return (await Browser.cookies.get({ url: 'https://bing.com/', name: '_U' }))?.value
|
|
}
|
|
|
|
Browser.runtime.onConnect.addListener((port) => {
|
|
console.debug('connected')
|
|
const onMessage = async (msg) => {
|
|
console.debug('received msg', msg)
|
|
const session = msg.session
|
|
if (!session) return
|
|
const config = await getUserConfig()
|
|
if (!session.modelName) session.modelName = config.modelName
|
|
if (!session.aiName) session.aiName = Models[session.modelName].desc
|
|
port.postMessage({ session })
|
|
|
|
try {
|
|
if (chatgptWebModelKeys.includes(session.modelName)) {
|
|
const accessToken = await getChatGptAccessToken()
|
|
session.messageId = uuidv4()
|
|
if (session.parentMessageId == null) {
|
|
session.parentMessageId = uuidv4()
|
|
}
|
|
await generateAnswersWithChatgptWebApi(port, session.question, session, accessToken)
|
|
} else if (bingWebModelKeys.includes(session.modelName)) {
|
|
const accessToken = await getBingAccessToken()
|
|
if (session.modelName === 'bingFreeSydney')
|
|
await generateAnswersWithBingWebApi(port, session.question, session, accessToken, true)
|
|
else await generateAnswersWithBingWebApi(port, session.question, session, accessToken)
|
|
} else if (gptApiModelKeys.includes(session.modelName)) {
|
|
await generateAnswersWithGptCompletionApi(
|
|
port,
|
|
session.question,
|
|
session,
|
|
config.apiKey,
|
|
session.modelName,
|
|
)
|
|
} else if (chatgptApiModelKeys.includes(session.modelName)) {
|
|
await generateAnswersWithChatgptApi(
|
|
port,
|
|
session.question,
|
|
session,
|
|
config.apiKey,
|
|
session.modelName,
|
|
)
|
|
} else if (customApiModelKeys.includes(session.modelName)) {
|
|
await generateAnswersWithCustomApi(
|
|
port,
|
|
session.question,
|
|
session,
|
|
'',
|
|
config.customModelName,
|
|
)
|
|
} else if (azureOpenAiApiModelKeys.includes(session.modelName)) {
|
|
await generateAnswersWithAzureOpenaiApi(port, session.question, session)
|
|
} else if (githubThirdPartyApiModelKeys.includes(session.modelName)) {
|
|
await generateAnswersWithWaylaidwandererApi(port, session.question, session)
|
|
} else if (poeWebModelKeys.includes(session.modelName)) {
|
|
if (session.modelName === 'poeAiWebCustom')
|
|
await generateAnswersWithPoeWebApi(
|
|
port,
|
|
session.question,
|
|
session,
|
|
config.poeCustomBotName,
|
|
)
|
|
else
|
|
await generateAnswersWithPoeWebApi(
|
|
port,
|
|
session.question,
|
|
session,
|
|
Models[session.modelName].value,
|
|
)
|
|
}
|
|
} catch (err) {
|
|
console.error(err)
|
|
if (!err.message.includes('aborted')) {
|
|
if (
|
|
['message you submitted was too long', 'maximum context length'].some((m) =>
|
|
err.message.includes(m),
|
|
)
|
|
)
|
|
port.postMessage({ error: t('Exceeded maximum context length') + '\n' + err.message })
|
|
else port.postMessage({ error: err.message })
|
|
}
|
|
}
|
|
}
|
|
|
|
const onDisconnect = () => {
|
|
console.debug('port disconnected, remove listener')
|
|
port.onMessage.removeListener(onMessage)
|
|
port.onDisconnect.removeListener(onDisconnect)
|
|
}
|
|
|
|
port.onMessage.addListener(onMessage)
|
|
port.onDisconnect.addListener(onDisconnect)
|
|
})
|
|
|
|
Browser.runtime.onMessage.addListener(async (message) => {
|
|
if (message.type === 'FEEDBACK') {
|
|
const token = await getChatGptAccessToken()
|
|
await sendMessageFeedback(token, message.data)
|
|
} else if (message.type === 'DELETE_CONVERSATION') {
|
|
const token = await getChatGptAccessToken()
|
|
const data = message.data
|
|
await deleteConversation(token, data.conversationId)
|
|
} else if (message.type === 'OPEN_URL') {
|
|
const data = message.data
|
|
openUrl(data.url)
|
|
}
|
|
})
|
|
|
|
Browser.commands.onCommand.addListener(async (command) => {
|
|
const message = {
|
|
itemId: command,
|
|
selectionText: '',
|
|
useMenuPosition: false,
|
|
}
|
|
console.debug('command triggered', message)
|
|
|
|
if (command in menuConfig) {
|
|
if (menuConfig[command].action) {
|
|
menuConfig[command].action()
|
|
}
|
|
|
|
if (menuConfig[command].genPrompt) {
|
|
const currentTab = (await Browser.tabs.query({ active: true, currentWindow: true }))[0]
|
|
Browser.tabs.sendMessage(currentTab.id, {
|
|
type: 'CREATE_CHAT',
|
|
data: message,
|
|
})
|
|
}
|
|
}
|
|
})
|
|
|
|
function refreshMenu() {
|
|
Browser.contextMenus.removeAll().then(async () => {
|
|
await getPreferredLanguageKey().then((lang) => {
|
|
changeLanguage(lang)
|
|
})
|
|
const menuId = 'ChatGPTBox-Menu'
|
|
Browser.contextMenus.create({
|
|
id: menuId,
|
|
title: 'ChatGPTBox',
|
|
contexts: ['all'],
|
|
})
|
|
|
|
for (const [k, v] of Object.entries(menuConfig)) {
|
|
Browser.contextMenus.create({
|
|
id: menuId + k,
|
|
parentId: menuId,
|
|
title: t(v.label),
|
|
contexts: ['all'],
|
|
})
|
|
}
|
|
Browser.contextMenus.create({
|
|
id: menuId + 'separator1',
|
|
parentId: menuId,
|
|
contexts: ['selection'],
|
|
type: 'separator',
|
|
})
|
|
for (const index in defaultConfig.selectionTools) {
|
|
const key = defaultConfig.selectionTools[index]
|
|
const desc = defaultConfig.selectionToolsDesc[index]
|
|
Browser.contextMenus.create({
|
|
id: menuId + key,
|
|
parentId: menuId,
|
|
title: t(desc),
|
|
contexts: ['selection'],
|
|
})
|
|
}
|
|
|
|
Browser.contextMenus.onClicked.addListener((info, tab) => {
|
|
Browser.tabs.query({ active: true, currentWindow: true }).then((tabs) => {
|
|
const currentTab = tabs[0]
|
|
const message = {
|
|
itemId: info.menuItemId.replace(menuId, ''),
|
|
selectionText: info.selectionText,
|
|
useMenuPosition: tab.id === currentTab.id,
|
|
}
|
|
console.debug('menu clicked', message)
|
|
|
|
if (defaultConfig.selectionTools.includes(message.itemId)) {
|
|
Browser.tabs.sendMessage(currentTab.id, {
|
|
type: 'CREATE_CHAT',
|
|
data: message,
|
|
})
|
|
} else if (message.itemId in menuConfig) {
|
|
if (menuConfig[message.itemId].action) {
|
|
menuConfig[message.itemId].action()
|
|
}
|
|
|
|
if (menuConfig[message.itemId].genPrompt) {
|
|
Browser.tabs.sendMessage(currentTab.id, {
|
|
type: 'CREATE_CHAT',
|
|
data: message,
|
|
})
|
|
}
|
|
}
|
|
})
|
|
})
|
|
})
|
|
}
|
|
|
|
Browser.runtime.onMessage.addListener(async (message) => {
|
|
if (message.type === 'REFRESH_MENU') {
|
|
refreshMenu()
|
|
}
|
|
})
|
|
|
|
refreshMenu()
|