106 lines
2.8 KiB
JavaScript
106 lines
2.8 KiB
JavaScript
'use strict';
|
|
|
|
exports.main = async (event, context) => {
|
|
// uniCloud HTTP 触发器:event 本身就是请求信息
|
|
// event.httpMethod = 'GET'/'POST'/'OPTIONS'
|
|
// event.body = 请求体
|
|
// event.headers = 请求头
|
|
// context.callbackWaitsForEmptyEventLoop = true 保持连接
|
|
|
|
const corsHeaders = {
|
|
'Access-Control-Allow-Origin': '*',
|
|
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
|
'Access-Control-Max-Age': '86400'
|
|
};
|
|
|
|
// 处理 CORS 预检
|
|
if (event.httpMethod === 'OPTIONS') {
|
|
return {
|
|
statusCode: 204,
|
|
headers: corsHeaders,
|
|
body: ''
|
|
};
|
|
}
|
|
|
|
// 设置等待空事件循环(保持 SSE 连接)
|
|
context.callbackWaitsForEmptyEventLoop = false;
|
|
|
|
// 解析请求体
|
|
let body = {};
|
|
try {
|
|
const raw = event.body || '';
|
|
if (event.isBase64Encoded) {
|
|
body = JSON.parse(Buffer.from(raw, 'base64').toString());
|
|
} else {
|
|
try { body = JSON.parse(raw); } catch (e) {
|
|
const params = new URLSearchParams(raw);
|
|
for (const [k, v] of params) body[k] = v;
|
|
}
|
|
}
|
|
} catch (e) {}
|
|
|
|
const { file_id, user_id, file_name, file_size, record_id } = body;
|
|
|
|
if (!file_id) {
|
|
return {
|
|
statusCode: 400,
|
|
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ error: '缺少 file_id' })
|
|
};
|
|
}
|
|
|
|
const COZE_TOKEN = 'sat_OiXlI4Da5Q99fxmul6pNfExmA6hR898UbxBDwrvjZ638APxRSlFnXbz6zyFedKNG';
|
|
const BOT_ID = '7689821072762011698';
|
|
|
|
const objectString = JSON.stringify([
|
|
{ type: 'file', file_id: file_id },
|
|
{ type: 'text', text: '请审查这份合同' }
|
|
]);
|
|
|
|
// 调用扣子(流式)
|
|
try {
|
|
const chatRes = await uniCloud.httpclient.request('https://api.coze.cn/v3/chat', {
|
|
method: 'POST',
|
|
dataType: 'text',
|
|
contentType: 'json',
|
|
timeout: 300000,
|
|
headers: { 'Authorization': 'Bearer ' + COZE_TOKEN },
|
|
data: {
|
|
bot_id: BOT_ID,
|
|
user_id: user_id || 'anonymous',
|
|
stream: true,
|
|
auto_save_history: true,
|
|
additional_messages: [{
|
|
role: 'user',
|
|
content: objectString,
|
|
content_type: 'object_string'
|
|
}]
|
|
}
|
|
});
|
|
|
|
// 返回 SSE 格式
|
|
const text = chatRes.data || '';
|
|
const sseBody = text.split('\n').map(line => {
|
|
if (line.startsWith('data:')) return line + '\n\n';
|
|
return '';
|
|
}).join('') + 'data: [DONE]\n\n';
|
|
|
|
return {
|
|
statusCode: 200,
|
|
headers: {
|
|
...corsHeaders,
|
|
'Content-Type': 'text/event-stream',
|
|
'Cache-Control': 'no-cache',
|
|
'Connection': 'keep-alive'
|
|
},
|
|
body: sseBody
|
|
};
|
|
} catch (e) {
|
|
return {
|
|
statusCode: 500,
|
|
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ error: e.message })
|
|
};
|
|
}
|
|
}; |