✅ 修复死循环问题 - 添加状态记忆功能
问题: 选择路径后重新发送文件,又显示选择卡片,导致死循环 解决方案: 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'));
|
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) {
|
async function handleFeishuEvent(req, res) {
|
||||||
const event = req.body;
|
const event = req.body;
|
||||||
log('📩 收到飞书请求');
|
log('📩 收到飞书请求');
|
||||||
@@ -99,8 +118,16 @@ async function handleMessage(event) {
|
|||||||
} else if (text.startsWith('/help') || text.startsWith('/qh')) {
|
} else if (text.startsWith('/help') || text.startsWith('/qh')) {
|
||||||
await handleHelpCommandV2(chatId, feishu);
|
await handleHelpCommandV2(chatId, feishu);
|
||||||
} else if (messageType === 'file' || messageContent.file_key) {
|
} 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('🔍 收到文件消息 - 发送配置卡片');
|
log('🔍 收到文件消息 - 发送配置卡片');
|
||||||
await handleFileReceivedWithCard(messageData, feishu, uploader);
|
await handleFileReceivedWithCard(messageData, feishu, uploader);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
await sendWelcomeCard(chatId, feishu);
|
await sendWelcomeCard(chatId, feishu);
|
||||||
}
|
}
|
||||||
@@ -192,9 +219,11 @@ async function handleCardInteraction(event) {
|
|||||||
const { bucket } = actionData.value;
|
const { bucket } = actionData.value;
|
||||||
log('🪣 选择存储桶:', bucket);
|
log('🪣 选择存储桶:', bucket);
|
||||||
|
|
||||||
|
setUserState(chatId, { bucket });
|
||||||
|
|
||||||
await feishu.sendMessage(chatId, {
|
await feishu.sendMessage(chatId, {
|
||||||
msg_type: 'text',
|
msg_type: 'text',
|
||||||
content: { text: `✅ 已选择存储桶:**${bucket}**\n\n请重新发送文件开始上传` }
|
content: { text: `✅ 已选择存储桶:**${bucket}**\n\n请重新发送文件开始上传(配置 5 分钟内有效)` }
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -204,9 +233,11 @@ async function handleCardInteraction(event) {
|
|||||||
const pathDesc = path_label || '原文件名';
|
const pathDesc = path_label || '原文件名';
|
||||||
log('📁 选择路径:', pathDesc);
|
log('📁 选择路径:', pathDesc);
|
||||||
|
|
||||||
|
setUserState(chatId, { upload_path, path_label });
|
||||||
|
|
||||||
await feishu.sendMessage(chatId, {
|
await feishu.sendMessage(chatId, {
|
||||||
msg_type: 'text',
|
msg_type: 'text',
|
||||||
content: { text: `✅ 已选择路径:**${pathDesc}**\n\n请重新发送文件开始上传` }
|
content: { text: `✅ 已选择路径:**${pathDesc}**\n\n请重新发送文件开始上传(配置 5 分钟内有效)` }
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -371,6 +402,66 @@ async function handleFileReceivedWithCard(messageData, feishu, uploader) {
|
|||||||
await feishu.sendCard(chatId, card);
|
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) {
|
async function handleConfigCommandV2(message, content, feishu, uploader) {
|
||||||
const chatId = message.chat_id;
|
const chatId = message.chat_id;
|
||||||
const text = content.text || '';
|
const text = content.text || '';
|
||||||
|
|||||||
Reference in New Issue
Block a user