✅ 修复死循环问题 - 添加状态记忆功能
问题: 选择路径后重新发送文件,又显示选择卡片,导致死循环 解决方案: 1. 添加用户状态临时存储(内存) 2. 选择存储桶/路径后保存状态(5 分钟有效) 3. 重新发送文件时,检测是否有保存的状态 4. 有状态则直接上传,无状态则显示选择卡片 使用流程: 1. 发送文件 → 显示选择卡片 2. 选择存储桶 → 保存状态,提示重新发送 3. 选择路径 → 保存状态,提示重新发送 4. 重新发送文件 → 使用保存的状态直接上传 5. 上传完成后清除状态 状态有效期:5 分钟
This commit is contained in:
95
src/index.js
95
src/index.js
@@ -30,6 +30,25 @@ function loadFullConfig() {
|
||||
return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
||||
}
|
||||
|
||||
// 用户临时状态存储(内存)
|
||||
const userStates = {};
|
||||
|
||||
function getUserState(chatId) {
|
||||
return userStates[chatId] || {};
|
||||
}
|
||||
|
||||
function setUserState(chatId, state) {
|
||||
userStates[chatId] = { ...userStates[chatId], ...state };
|
||||
// 5 分钟后清除状态
|
||||
setTimeout(() => {
|
||||
delete userStates[chatId];
|
||||
}, 5 * 60 * 1000);
|
||||
}
|
||||
|
||||
function clearUserState(chatId) {
|
||||
delete userStates[chatId];
|
||||
}
|
||||
|
||||
async function handleFeishuEvent(req, res) {
|
||||
const event = req.body;
|
||||
log('📩 收到飞书请求');
|
||||
@@ -99,8 +118,16 @@ async function handleMessage(event) {
|
||||
} else if (text.startsWith('/help') || text.startsWith('/qh')) {
|
||||
await handleHelpCommandV2(chatId, feishu);
|
||||
} else if (messageType === 'file' || messageContent.file_key) {
|
||||
// 检查是否有已保存的配置
|
||||
const state = getUserState(chatId);
|
||||
if (state.bucket || state.upload_path) {
|
||||
log('🔍 收到文件消息 - 使用已保存的配置');
|
||||
await handleFileUploadWithState(messageData, feishu, uploader, state);
|
||||
clearUserState(chatId);
|
||||
} else {
|
||||
log('🔍 收到文件消息 - 发送配置卡片');
|
||||
await handleFileReceivedWithCard(messageData, feishu, uploader);
|
||||
}
|
||||
} else {
|
||||
await sendWelcomeCard(chatId, feishu);
|
||||
}
|
||||
@@ -192,9 +219,11 @@ async function handleCardInteraction(event) {
|
||||
const { bucket } = actionData.value;
|
||||
log('🪣 选择存储桶:', bucket);
|
||||
|
||||
setUserState(chatId, { bucket });
|
||||
|
||||
await feishu.sendMessage(chatId, {
|
||||
msg_type: 'text',
|
||||
content: { text: `✅ 已选择存储桶:**${bucket}**\n\n请重新发送文件开始上传` }
|
||||
content: { text: `✅ 已选择存储桶:**${bucket}**\n\n请重新发送文件开始上传(配置 5 分钟内有效)` }
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -204,9 +233,11 @@ async function handleCardInteraction(event) {
|
||||
const pathDesc = path_label || '原文件名';
|
||||
log('📁 选择路径:', pathDesc);
|
||||
|
||||
setUserState(chatId, { upload_path, path_label });
|
||||
|
||||
await feishu.sendMessage(chatId, {
|
||||
msg_type: 'text',
|
||||
content: { text: `✅ 已选择路径:**${pathDesc}**\n\n请重新发送文件开始上传` }
|
||||
content: { text: `✅ 已选择路径:**${pathDesc}**\n\n请重新发送文件开始上传(配置 5 分钟内有效)` }
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -371,6 +402,66 @@ async function handleFileReceivedWithCard(messageData, feishu, uploader) {
|
||||
await feishu.sendCard(chatId, card);
|
||||
}
|
||||
|
||||
// 使用已保存的状态直接上传文件
|
||||
async function handleFileUploadWithState(messageData, feishu, uploader, state) {
|
||||
const chatId = messageData.chat_id;
|
||||
const messageId = messageData.message_id;
|
||||
const messageContent = JSON.parse(messageData.content);
|
||||
|
||||
const fileKey = messageContent.file_key;
|
||||
const fileName = messageContent.file_name;
|
||||
|
||||
if (!fileKey) return;
|
||||
|
||||
const targetBucket = state.bucket || 'default';
|
||||
let targetKey = state.upload_path || fileName;
|
||||
const pathLabel = state.path_label || '原文件名';
|
||||
|
||||
if (targetKey.startsWith('/')) targetKey = targetKey.substring(1);
|
||||
|
||||
log('📤 使用已保存配置上传:', fileName, 'bucket:', targetBucket, 'path:', targetKey);
|
||||
|
||||
try {
|
||||
await feishu.sendMessage(chatId, {
|
||||
msg_type: 'text',
|
||||
content: { text: `📥 正在下载:${fileName}` }
|
||||
});
|
||||
|
||||
const tempFile = await feishu.downloadFile(fileKey, messageId, chatId);
|
||||
log('✅ 文件下载完成:', tempFile);
|
||||
|
||||
await feishu.sendMessage(chatId, {
|
||||
msg_type: 'text',
|
||||
content: { text: `📤 上传中:${targetKey} → ${targetBucket} (路径:${pathLabel})` }
|
||||
});
|
||||
|
||||
const result = await uploader.upload(tempFile, targetKey, targetBucket);
|
||||
await uploader.refreshCDN(targetBucket, targetKey);
|
||||
|
||||
await feishu.sendMessage(chatId, {
|
||||
msg_type: 'text',
|
||||
content: {
|
||||
text: `✅ 上传成功!\n\n` +
|
||||
`📦 文件:${targetKey}\n` +
|
||||
`🔗 链接:${result.url}\n` +
|
||||
`💾 原文件:${fileName}\n` +
|
||||
`🪣 存储桶:${targetBucket}\n` +
|
||||
`📁 路径:${pathLabel}`
|
||||
}
|
||||
});
|
||||
|
||||
fs.unlinkSync(tempFile);
|
||||
log('🗑️ 临时文件已清理:', tempFile);
|
||||
|
||||
} catch (error) {
|
||||
log('上传失败:', error.message);
|
||||
await feishu.sendMessage(chatId, {
|
||||
msg_type: 'text',
|
||||
content: { text: `❌ 上传失败:${error.message}` }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function handleConfigCommandV2(message, content, feishu, uploader) {
|
||||
const chatId = message.chat_id;
|
||||
const text = content.text || '';
|
||||
|
||||
Reference in New Issue
Block a user