196 lines
6.7 KiB
JavaScript
196 lines
6.7 KiB
JavaScript
// background.js - 后台服务工作线程
|
||
// 负责监听小红书私信通的WebSocket连接,捕获消息并转发给content.js
|
||
// 使用Chrome debugger API来捕获WebSocket消息,绕过反爬机制
|
||
|
||
console.log("Background script loaded.");
|
||
|
||
// 插件安装/更新事件监听器
|
||
chrome.runtime.onInstalled.addListener(() => {
|
||
console.log("小红书AI客服插件已安装。");
|
||
});
|
||
|
||
let init = false;
|
||
|
||
// ==================== 标签页监听 ====================
|
||
// 监听标签页更新事件,当用户访问小红书私信通页面时自动启动监听
|
||
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
||
// 检查条件:
|
||
// 1. tab.url 存在(确保页面有URL)
|
||
// 2. URL包含"sxt.xiaohongshu.com"(小红书私信通域名)
|
||
// 3. changeInfo.status === 'complete'(页面完全加载完成)
|
||
if (tab.url && tab.url.includes("sxt.xiaohongshu.com") && changeInfo.status === 'complete') {
|
||
console.log(`检测到小红书私信通页面加载完成: ${tab.url}`);
|
||
if (!init) {
|
||
init = true;
|
||
attachDebugger(tabId); // 附加调试器开始监听
|
||
}
|
||
}
|
||
});
|
||
|
||
// ==================== 调试器附加函数 ====================
|
||
// 使用Chrome debugger API附加到指定标签页
|
||
function attachDebugger(tabId) {
|
||
const debuggee = { tabId: tabId };
|
||
chrome.debugger.attach(debuggee, "1.3", () => {
|
||
if (chrome.runtime.lastError) {
|
||
console.error("调试器附加失败:", chrome.runtime.lastError.message);
|
||
return;
|
||
}
|
||
console.log(`调试器已成功附加到标签页 ${tabId}`);
|
||
chrome.debugger.sendCommand(debuggee, "Network.enable", {}, () => {
|
||
if (chrome.runtime.lastError) {
|
||
console.error("Network域启用失败:", chrome.runtime.lastError.message);
|
||
} else {
|
||
console.log("Network域已启用,开始监听WebSocket连接...");
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
// ==================== WebSocket事件监听 ====================
|
||
// 监听调试器事件,捕获WebSocket相关的所有活动
|
||
chrome.debugger.onEvent.addListener((source, method, params) => {
|
||
switch (method) {
|
||
case "Network.webSocketCreated":
|
||
// WebSocket连接创建事件
|
||
console.log("检测到WebSocket连接创建:", params.url);
|
||
break;
|
||
case "Network.webSocketFrameReceived":
|
||
// WebSocket接收消息事件
|
||
// 这是最重要的事件,包含了客户发送的私信内容
|
||
console.log("收到WebSocket消息:", params.response.payloadData);
|
||
// 将消息转发给content.js进行处理
|
||
chrome.tabs.sendMessage(source.tabId, { type: "WEBSOCKET_MESSAGE", data: params.response.payloadData });
|
||
break;
|
||
case "Network.webSocketFrameSent":
|
||
// WebSocket发送消息事件
|
||
console.log("发送WebSocket消息:", params.response.payloadData);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
});
|
||
|
||
// ==================== 调试器分离监听 ====================
|
||
// 监听调试器分离事件,了解监听何时结束
|
||
chrome.debugger.onDetach.addListener((source, reason) => {
|
||
console.log(`调试器已从标签页 ${source.tabId} 分离,原因: ${reason}`);
|
||
});
|
||
|
||
// ==================== 消息处理 ====================
|
||
// 监听来自content.js的消息(如AI回复记录)
|
||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||
if (message.type === "AI_REPLY_GENERATED") {
|
||
console.log("收到AI生成的回复:", message.data);
|
||
// 示例:保存到本地存储
|
||
chrome.storage.local.get(['ai_replies'], (result) => {
|
||
const replies = result.ai_replies || [];
|
||
replies.push(message.data);
|
||
if (replies.length > 100) {
|
||
replies.splice(0, replies.length - 100);
|
||
}
|
||
chrome.storage.local.set({ ai_replies: replies }, () => {
|
||
console.log('AI回复已保存到本地存储');
|
||
});
|
||
});
|
||
sendResponse({ status: 'success', message: 'AI回复已记录' });
|
||
}
|
||
});
|
||
|
||
/*
|
||
{{ AURA-X: Add - 新增Chrome扩展跨域代理消息监听. Approval: 寸止(ID:20240608-bg-cors-proxy) }}
|
||
监听前端消息,后台代理请求AI会话ID接口,并返回结果
|
||
*/
|
||
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
||
if (request.type === 'FETCH_AI_SESSION_ID') {
|
||
fetchAiSessionId().then(data => {
|
||
sendResponse({ success: true, data });
|
||
}).catch(error => {
|
||
sendResponse({ success: false, error: error.message });
|
||
});
|
||
// 必须返回true以支持异步响应
|
||
return true;
|
||
}
|
||
});
|
||
|
||
/*
|
||
{{ AURA-X: Add - 新增AI会话ID获取与记录功能. Approval: 寸止(ID:20240608-bg-fetch-session) }}
|
||
通过fetch获取AI会话ID,并记录当前会话信息
|
||
*/
|
||
let currentSessionInfo = null; // 用于存储当前会话信息
|
||
|
||
function fetchAiSessionId() {
|
||
// 使用fetch发起GET请求
|
||
return fetch('http://203.156.197.220:9876/chat/api/open', {
|
||
method: 'GET',
|
||
headers: {
|
||
'accept': '*/*',
|
||
'Authorization': 'Bearer application-263ec5c846faf2e3270e38e154c09a8f'
|
||
}
|
||
})
|
||
.then(response => {
|
||
// 检查响应状态
|
||
if (!response.ok) {
|
||
throw new Error('网络请求失败: ' + response.status);
|
||
}
|
||
// 返回JSON格式数据
|
||
return response.json();
|
||
})
|
||
.then(data => {
|
||
// 记录会话信息
|
||
currentSessionInfo = data;
|
||
// 输出到控制台,便于调试
|
||
console.log('当前AI会话信息:', currentSessionInfo);
|
||
return data;
|
||
})
|
||
.catch(error => {
|
||
console.error('获取AI会话ID失败:', error);
|
||
});
|
||
}
|
||
|
||
// 可在需要时调用fetchAiSessionId()
|
||
// fetchAiSessionId();
|
||
|
||
/*
|
||
{{ AURA-X: Add - 新增AI大模型消息POST代理接口. Approval: 寸止(ID:20240608-bg-chat-post) }}
|
||
通过fetch代理POST请求AI大模型接口
|
||
*/
|
||
function postAiChatMessage({ sessionId, message, csrfToken }) {
|
||
// 构造请求URL
|
||
const url = `http://203.156.197.220:9876/chat/api/chat_message/${sessionId}`;
|
||
// 组装请求体
|
||
const body = JSON.stringify({
|
||
message,
|
||
stream: false,
|
||
re_chat: false
|
||
});
|
||
// 发起POST请求
|
||
return fetch(url, {
|
||
method: 'POST',
|
||
headers: {
|
||
'accept': '*/*',
|
||
'Authorization': 'Bearer application-263ec5c846faf2e3270e38e154c09a8f',
|
||
'Content-Type': 'application/json',
|
||
'X-CSRFTOKEN': csrfToken
|
||
},
|
||
body
|
||
})
|
||
.then(response => {
|
||
if (!response.ok) {
|
||
throw new Error('网络请求失败: ' + response.status);
|
||
}
|
||
return response.json();
|
||
});
|
||
}
|
||
|
||
// 监听前端消息,代理POST请求
|
||
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
||
if (request.type === 'POST_AI_CHAT_MESSAGE') {
|
||
postAiChatMessage(request.data).then(data => {
|
||
sendResponse({ success: true, data });
|
||
}).catch(error => {
|
||
sendResponse({ success: false, error: error.message });
|
||
});
|
||
return true;
|
||
}
|
||
}); |