mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-16 21:37:11 +00:00
尝试兼容napcat,修复伪人发送表情乱码 以及一些兼容性修改
This commit is contained in:
parent
c82c137596
commit
b4032881da
4 changed files with 134 additions and 28 deletions
|
|
@ -465,6 +465,17 @@ export const faceMapReverse = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function convertFaces (msg, handleAt = false, e) {
|
export async function convertFaces (msg, handleAt = false, e) {
|
||||||
|
if (!msg) return []
|
||||||
|
|
||||||
|
// 处理HTML实体编码和多余右括号
|
||||||
|
if (typeof msg === 'string') {
|
||||||
|
msg = msg.replace(/[/g, '[')
|
||||||
|
.replace(/]/g, ']')
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/\\/g, '') // 移除多余的反斜杠
|
||||||
|
.replace(/\]+/g, ']') // 将多个连续的右括号替换为单个右括号
|
||||||
|
}
|
||||||
|
|
||||||
handleAt = e?.isGroup && handleAt
|
handleAt = e?.isGroup && handleAt
|
||||||
let groupMembers
|
let groupMembers
|
||||||
let groupCardQQMap = {}
|
let groupCardQQMap = {}
|
||||||
|
|
@ -486,6 +497,7 @@ export async function convertFaces (msg, handleAt = false, e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let tmpMsg = ''
|
let tmpMsg = ''
|
||||||
let tmpFace = ''
|
let tmpFace = ''
|
||||||
let tmpAt = ''
|
let tmpAt = ''
|
||||||
|
|
@ -493,13 +505,20 @@ export async function convertFaces (msg, handleAt = false, e) {
|
||||||
let foundAt = false
|
let foundAt = false
|
||||||
let msgs = []
|
let msgs = []
|
||||||
for (let i = 0; i < msg.length; i++) {
|
for (let i = 0; i < msg.length; i++) {
|
||||||
// console.log(msg[i])
|
const char = msg[i]
|
||||||
if (msg[i] === '[') {
|
const nextChar = msg[i + 1]
|
||||||
|
|
||||||
|
if (char === '[') {
|
||||||
foundFace = true
|
foundFace = true
|
||||||
|
if (tmpMsg) {
|
||||||
|
msgs.push(tmpMsg)
|
||||||
|
tmpMsg = ''
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foundFace) {
|
if (!foundFace) {
|
||||||
if (handleAt && msg[i] === '@') {
|
if (handleAt && char === '@') {
|
||||||
foundAt = true
|
foundAt = true
|
||||||
if (tmpMsg) {
|
if (tmpMsg) {
|
||||||
msgs.push(tmpMsg)
|
msgs.push(tmpMsg)
|
||||||
|
|
@ -508,7 +527,7 @@ export async function convertFaces (msg, handleAt = false, e) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (handleAt && foundAt) {
|
if (handleAt && foundAt) {
|
||||||
tmpAt += msg[i]
|
tmpAt += char
|
||||||
if (groupCardQQMap[tmpAt]) {
|
if (groupCardQQMap[tmpAt]) {
|
||||||
foundAt = false
|
foundAt = false
|
||||||
msgs.push(segment.at(groupCardQQMap[tmpAt], groupMembers.get(groupCardQQMap[tmpAt]).card, false))
|
msgs.push(segment.at(groupCardQQMap[tmpAt], groupMembers.get(groupCardQQMap[tmpAt]).card, false))
|
||||||
|
|
@ -516,36 +535,53 @@ export async function convertFaces (msg, handleAt = false, e) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tmpMsg += msg[i]
|
tmpMsg += char
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (msg[i] !== ']') {
|
if (char !== ']') {
|
||||||
tmpFace += msg[i]
|
tmpFace += char
|
||||||
} else {
|
} else {
|
||||||
foundFace = false
|
foundFace = false
|
||||||
if (faceMapReverse[tmpFace] || faceMapReverse['/' + tmpFace] || faceMapReverse[_.trimStart(tmpFace, '/')]) {
|
// 处理CQ码格式
|
||||||
if (tmpMsg) {
|
if (tmpFace.startsWith('CQ:face,id=')) {
|
||||||
msgs.push(tmpMsg)
|
const faceId = parseInt(tmpFace.split('=')[1].split(',')[0])
|
||||||
}
|
msgs.push(segment.face(faceId))
|
||||||
msgs.push(segment.face(parseInt(faceMapReverse[tmpFace] || faceMapReverse['/' + tmpFace] || faceMapReverse[_.trimStart(tmpFace, '/')])))
|
tmpFace = ''
|
||||||
tmpMsg = ''
|
}
|
||||||
} else {
|
// 处理表情名称格式
|
||||||
tmpMsg += `[${tmpFace}]`
|
else if (faceMapReverse[tmpFace] || faceMapReverse['/' + tmpFace] || faceMapReverse[_.trimStart(tmpFace, '/')]) {
|
||||||
|
msgs.push(segment.face(parseInt(faceMapReverse[tmpFace] || faceMapReverse['/' + tmpFace] || faceMapReverse[_.trimStart(tmpFace, '/')])))
|
||||||
|
tmpFace = ''
|
||||||
|
} else {
|
||||||
|
// 如果找不到对应的表情,将整个内容作为普通文本处理
|
||||||
|
tmpMsg += `[${tmpFace}]`
|
||||||
|
tmpFace = ''
|
||||||
}
|
}
|
||||||
tmpFace = ''
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理剩余内容
|
||||||
if (tmpMsg) {
|
if (tmpMsg) {
|
||||||
msgs.push(tmpMsg)
|
msgs.push(tmpMsg)
|
||||||
|
tmpMsg = '' // 清空临时消息
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理未闭合的表情标记
|
||||||
if (tmpFace) {
|
if (tmpFace) {
|
||||||
msgs.push(`[${tmpFace}`)
|
if (tmpFace.endsWith(']')) {
|
||||||
|
msgs.push(`[${tmpFace.slice(0, -1)}]`) // 如果有多余的右括号,去掉它
|
||||||
|
} else {
|
||||||
|
msgs.push(`[${tmpFace}]`) // 正常添加右括号
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handleAt && tmpAt) {
|
if (handleAt && tmpAt) {
|
||||||
msgs.push(`@${tmpAt}`)
|
msgs.push(`@${tmpAt}`)
|
||||||
}
|
}
|
||||||
return msgs
|
|
||||||
|
// 确保返回数组
|
||||||
|
return Array.isArray(msgs) ? msgs : [msgs].filter(Boolean)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function testConvertFaces () {
|
export function testConvertFaces () {
|
||||||
|
|
|
||||||
|
|
@ -23,15 +23,85 @@ export class SerpImageTool extends AbstractTool {
|
||||||
|
|
||||||
func = async function (opts) {
|
func = async function (opts) {
|
||||||
let { q, limit = 2, source = 'bing' } = opts
|
let { q, limit = 2, source = 'bing' } = opts
|
||||||
let serpRes = await fetch(`https://serp.ikechan8370.com/image/${source}?q=${encodeURIComponent(q)}&limit=${limit}`, {
|
|
||||||
headers: {
|
|
||||||
'X-From-Library': 'ikechan8370'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
serpRes = await serpRes.json()
|
|
||||||
|
|
||||||
let res = serpRes.data
|
// 验证参数
|
||||||
return `images search results in json format:\n${JSON.stringify(res)}. the murl field is actual picture url. You should use sendPicture to send them`
|
if (!q || typeof q !== 'string') {
|
||||||
|
return {
|
||||||
|
error: 'Invalid search query',
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证搜索源
|
||||||
|
if (!['bing', 'yandex'].includes(source)) {
|
||||||
|
return {
|
||||||
|
error: 'Invalid search source. Must be either "bing" or "yandex"',
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 构建 URL
|
||||||
|
const url = `https://serp.ikechan8370.com/image/${source}?q=${encodeURIComponent(q)}&limit=${limit}`
|
||||||
|
console.log('Searching images with URL:', url)
|
||||||
|
|
||||||
|
let serpRes = await fetch(url, {
|
||||||
|
headers: {
|
||||||
|
'X-From-Library': 'ikechan8370',
|
||||||
|
'Accept': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 检查响应状态
|
||||||
|
if (!serpRes.ok) {
|
||||||
|
const errorText = await serpRes.text()
|
||||||
|
console.error('API error response:', errorText)
|
||||||
|
throw new Error(`HTTP error! status: ${serpRes.status}, response: ${errorText}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取响应文本并解析 JSON
|
||||||
|
const serpData = await serpRes.json()
|
||||||
|
console.log('API response:', JSON.stringify(serpData, null, 2))
|
||||||
|
|
||||||
|
// 验证响应格式
|
||||||
|
if (!serpData || serpData.code !== 200 || !Array.isArray(serpData.data)) {
|
||||||
|
console.error('Invalid response format:', serpData)
|
||||||
|
throw new Error('Invalid response format from server')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保返回的数据是数组
|
||||||
|
const res = Array.isArray(serpData.data) ? serpData.data : []
|
||||||
|
|
||||||
|
if (res.length === 0) {
|
||||||
|
return {
|
||||||
|
error: 'No images found',
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证每个图片 URL
|
||||||
|
const validImages = res.filter(img => {
|
||||||
|
if (!img || typeof img !== 'object') return false
|
||||||
|
if (!img.murl || typeof img.murl !== 'string') return false
|
||||||
|
if (!img.murl.startsWith('http')) return false
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
if (validImages.length === 0) {
|
||||||
|
return {
|
||||||
|
error: 'No valid image URLs found',
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return `images search results in json format:\n${JSON.stringify(validImages)}. the murl field is actual picture url. You should use sendPicture to send them`
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Search image error:', error)
|
||||||
|
return {
|
||||||
|
error: `Failed to search images: ${error.message}`,
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
description = 'Useful when you want to search images from the Internet.'
|
description = 'Useful when you want to search images from the Internet.'
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue