|
@@ -74,6 +74,53 @@ function isAdmin(userId) {
|
|
return process.env.ADMIN_IDS.split(',').includes(userId.toString());
|
|
return process.env.ADMIN_IDS.split(',').includes(userId.toString());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// 检查用户是否有权限操作机器人
|
|
|
|
+async function checkUserPermission(chatId, userId) {
|
|
|
|
+ try {
|
|
|
|
+ const [group] = await pool.query(
|
|
|
|
+ 'SELECT creator_id, COALESCE(operators, "[]") as operators FROM groups WHERE group_id = ?',
|
|
|
|
+ [chatId.toString()]
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ if (!group || !group[0]) {
|
|
|
|
+ console.log(`权限检查失败 - 群组不存在: ${chatId}`);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const groupInfo = group[0];
|
|
|
|
+ const userIdStr = userId.toString();
|
|
|
|
+ const isCreator = groupInfo.creator_id === userIdStr;
|
|
|
|
+
|
|
|
|
+ console.log(`权限检查 - 用户ID: ${userIdStr}, 创建者ID: ${groupInfo.creator_id}, 是否创建者: ${isCreator}`);
|
|
|
|
+
|
|
|
|
+ let operators = [];
|
|
|
|
+ try {
|
|
|
|
+ if (groupInfo.operators) {
|
|
|
|
+ operators = JSON.parse(groupInfo.operators);
|
|
|
|
+ if (!Array.isArray(operators)) {
|
|
|
|
+ operators = [];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (e) {
|
|
|
|
+ console.error('解析操作人列表失败:', e);
|
|
|
|
+ operators = [];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const isOperator = operators.some(op => {
|
|
|
|
+ const isOp = op.operator_id === userIdStr;
|
|
|
|
+ console.log(`检查操作人 - 操作人ID: ${op.operator_id}, 用户ID: ${userIdStr}, 是否匹配: ${isOp}`);
|
|
|
|
+ return isOp;
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ console.log(`权限检查结果 - 用户ID: ${userIdStr}, 是否创建者: ${isCreator}, 是否操作人: ${isOperator}`);
|
|
|
|
+
|
|
|
|
+ return isCreator || isOperator;
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('检查用户权限失败:', error);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
// 处理消息发送
|
|
// 处理消息发送
|
|
async function sendMessage(chatId, text, options = {}) {
|
|
async function sendMessage(chatId, text, options = {}) {
|
|
try {
|
|
try {
|
|
@@ -113,6 +160,16 @@ bot.on('message', async (msg) => {
|
|
const text = msg.text?.trim();
|
|
const text = msg.text?.trim();
|
|
if (!text) return;
|
|
if (!text) return;
|
|
|
|
|
|
|
|
+ // 检查用户权限
|
|
|
|
+ const hasPermission = await checkUserPermission(msg.chat.id, msg.from.id);
|
|
|
|
+ console.log(`用户权限检查 - 用户ID: ${msg.from.id}, 群组ID: ${msg.chat.id}, 是否有权限: ${hasPermission}`);
|
|
|
|
+
|
|
|
|
+ if (!hasPermission) {
|
|
|
|
+ // 如果不是创建人或操作人,直接返回
|
|
|
|
+ console.log(`用户无权限操作 - 用户ID: ${msg.from.id}, 群组ID: ${msg.chat.id}`);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
// 处理入款命令
|
|
// 处理入款命令
|
|
if (text.startsWith('+')) {
|
|
if (text.startsWith('+')) {
|
|
let amount, exchangeRate, feeRate;
|
|
let amount, exchangeRate, feeRate;
|
|
@@ -365,6 +422,116 @@ bot.on('message', async (msg) => {
|
|
await sendMessage(msg.chat.id, '汇率设置失败,请输入大于0的数字');
|
|
await sendMessage(msg.chat.id, '汇率设置失败,请输入大于0的数字');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ // 处理设置操作人命令
|
|
|
|
+ else if (text.startsWith('设置操作人')) {
|
|
|
|
+ try {
|
|
|
|
+ const groupId = msg.chat.id.toString();
|
|
|
|
+ const mentionedUser = msg.entities?.find(e => e.type === 'mention');
|
|
|
|
+
|
|
|
|
+ if (!mentionedUser) {
|
|
|
|
+ // 如果没有@用户,回复原消息并提示设置用户名
|
|
|
|
+ await bot.sendMessage(msg.chat.id, '请设置您的Telegram用户名后再试', {
|
|
|
|
+ reply_to_message_id: msg.message_id
|
|
|
|
+ });
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 获取被@的用户名
|
|
|
|
+ const username = text.slice(mentionedUser.offset + 1, mentionedUser.offset + mentionedUser.length);
|
|
|
|
+
|
|
|
|
+ // 获取群组信息
|
|
|
|
+ const [group] = await pool.query(
|
|
|
|
+ 'SELECT creator_id, COALESCE(operators, "[]") as operators FROM groups WHERE group_id = ?',
|
|
|
|
+ [groupId]
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ if (!group || !group[0]) {
|
|
|
|
+ await sendMessage(msg.chat.id, '群组信息不存在');
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const groupInfo = group[0];
|
|
|
|
+ const userId = msg.from.id.toString();
|
|
|
|
+
|
|
|
|
+ // 检查操作权限(群组创建者或现有操作人)
|
|
|
|
+ const isCreator = groupInfo.creator_id === userId;
|
|
|
|
+ let operators = [];
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ if (groupInfo.operators) {
|
|
|
|
+ operators = JSON.parse(groupInfo.operators);
|
|
|
|
+ if (!Array.isArray(operators)) {
|
|
|
|
+ operators = [];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (e) {
|
|
|
|
+ console.error('解析操作人列表失败:', e);
|
|
|
|
+ operators = [];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const isOperator = operators.some(op => op.operator_id === userId);
|
|
|
|
+
|
|
|
|
+ if (!isCreator && !isOperator) {
|
|
|
|
+ await sendMessage(msg.chat.id, '您没有权限设置操作人');
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 获取被@用户的ID
|
|
|
|
+ const [user] = await pool.query(
|
|
|
|
+ 'SELECT id FROM users WHERE username = ?',
|
|
|
|
+ [username]
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ let newOperatorId;
|
|
|
|
+ if (!user || !user[0]) {
|
|
|
|
+ // 如果用户不存在,创建新用户
|
|
|
|
+ try {
|
|
|
|
+ const [result] = await pool.query(
|
|
|
|
+ 'INSERT INTO users (username, password, role) VALUES (?, ?, ?)',
|
|
|
|
+ [username, '', 'user']
|
|
|
|
+ );
|
|
|
|
+ newOperatorId = result.insertId.toString();
|
|
|
|
+ console.log(`创建新用户成功 - 用户名: ${username}, ID: ${newOperatorId}`);
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('创建新用户失败:', error);
|
|
|
|
+ await sendMessage(msg.chat.id, '创建用户失败,请稍后重试');
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ newOperatorId = user[0].id.toString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 检查是否已经是操作人
|
|
|
|
+ if (operators.some(op => op.operator_id === newOperatorId)) {
|
|
|
|
+ await sendMessage(msg.chat.id, '该用户已经是操作人');
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 添加新操作人
|
|
|
|
+ operators.push({
|
|
|
|
+ operator_id: newOperatorId,
|
|
|
|
+ operator_username: username,
|
|
|
|
+ added_by: userId,
|
|
|
|
+ added_at: new Date().toISOString()
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 更新群组
|
|
|
|
+ await pool.query(
|
|
|
|
+ 'UPDATE groups SET operators = ? WHERE group_id = ?',
|
|
|
|
+ [JSON.stringify(operators), groupId]
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ await sendMessage(msg.chat.id, `已成功设置 @${username} 为操作人`);
|
|
|
|
+ console.log(`设置操作人成功 - 群组: ${msg.chat.title}, 新操作人: ${username}, 设置者: ${msg.from.username || msg.from.first_name}, 时间: ${new Date().toLocaleString()}`);
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('设置操作人失败:', error);
|
|
|
|
+ if (error.code === 'ER_BAD_FIELD_ERROR') {
|
|
|
|
+ await sendMessage(msg.chat.id, '系统正在升级,请稍后再试');
|
|
|
|
+ } else {
|
|
|
|
+ await sendMessage(msg.chat.id, '设置操作人失败,请稍后重试');
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
// 处理TRX地址
|
|
// 处理TRX地址
|
|
else if (/^T[A-Za-z0-9]{33}$/.test(text)) {
|
|
else if (/^T[A-Za-z0-9]{33}$/.test(text)) {
|
|
try {
|
|
try {
|
|
@@ -497,11 +664,17 @@ bot.on('new_chat_members', async (msg) => {
|
|
console.log(formatLog(groupData));
|
|
console.log(formatLog(groupData));
|
|
|
|
|
|
try {
|
|
try {
|
|
- // 直接使用 SQL 插入群组数据
|
|
|
|
|
|
+ // 直接使用 SQL 插入或更新群组数据
|
|
const [result] = await pool.query(`
|
|
const [result] = await pool.query(`
|
|
INSERT INTO groups
|
|
INSERT INTO groups
|
|
- (group_id, group_name, group_type, creator_id, is_active, last_join_time)
|
|
|
|
- VALUES (?, ?, ?, ?, true, CURRENT_TIMESTAMP)
|
|
|
|
|
|
+ (group_id, group_name, group_type, creator_id, is_active, last_join_time,
|
|
|
|
+ in_fee_rate, in_exchange_rate, out_fee_rate, out_exchange_rate, operators)
|
|
|
|
+ VALUES (?, ?, ?, ?, true, CURRENT_TIMESTAMP, 0.00, 1.0000, 0.00, 1.0000, '[]')
|
|
|
|
+ ON DUPLICATE KEY UPDATE
|
|
|
|
+ group_name = VALUES(group_name),
|
|
|
|
+ group_type = VALUES(group_type),
|
|
|
|
+ is_active = true,
|
|
|
|
+ last_join_time = CURRENT_TIMESTAMP
|
|
`, [
|
|
`, [
|
|
groupData.groupId,
|
|
groupData.groupId,
|
|
groupData.groupName,
|
|
groupData.groupName,
|
|
@@ -888,42 +1061,75 @@ async function handleBotAdded(msg, chatId, chatType, chatIdStr, existingGroup) {
|
|
群组链接: chatInfo.invite_link || '未设置',
|
|
群组链接: chatInfo.invite_link || '未设置',
|
|
更新时间: new Date().toLocaleString()
|
|
更新时间: new Date().toLocaleString()
|
|
};
|
|
};
|
|
- // console.log('机器人首次被添加到群组');
|
|
|
|
- // console.log(formatLog(groupInfo));
|
|
|
|
|
|
|
|
// 如果群组不存在,创建新群组
|
|
// 如果群组不存在,创建新群组
|
|
if (!existingGroup) {
|
|
if (!existingGroup) {
|
|
const groupData = {
|
|
const groupData = {
|
|
groupId: chatIdStr,
|
|
groupId: chatIdStr,
|
|
groupName: msg.chat.title || '未命名群组',
|
|
groupName: msg.chat.title || '未命名群组',
|
|
- groupType: chatType === 'private' ? 'private' : 'public',
|
|
|
|
|
|
+ groupType: chatType === 'private' ? 'personal' : chatType,
|
|
creatorId: msg.from.id.toString()
|
|
creatorId: msg.from.id.toString()
|
|
};
|
|
};
|
|
|
|
|
|
- const id = await Group.create({
|
|
|
|
- groupId: groupData.groupId,
|
|
|
|
- groupName: groupData.groupName,
|
|
|
|
- creatorId: groupData.creatorId
|
|
|
|
- });
|
|
|
|
|
|
+ try {
|
|
|
|
+ // 直接使用 SQL 插入或更新群组数据
|
|
|
|
+ const [result] = await pool.query(`
|
|
|
|
+ INSERT INTO groups
|
|
|
|
+ (group_id, group_name, group_type, creator_id, is_active, last_join_time,
|
|
|
|
+ in_fee_rate, in_exchange_rate, out_fee_rate, out_exchange_rate, operators)
|
|
|
|
+ VALUES (?, ?, ?, ?, true, CURRENT_TIMESTAMP, 0.00, 1.0000, 0.00, 1.0000, '[]')
|
|
|
|
+ ON DUPLICATE KEY UPDATE
|
|
|
|
+ group_name = VALUES(group_name),
|
|
|
|
+ group_type = VALUES(group_type),
|
|
|
|
+ is_active = true,
|
|
|
|
+ last_join_time = CURRENT_TIMESTAMP
|
|
|
|
+ `, [
|
|
|
|
+ groupData.groupId,
|
|
|
|
+ groupData.groupName,
|
|
|
|
+ groupData.groupType,
|
|
|
|
+ groupData.creatorId
|
|
|
|
+ ]);
|
|
|
|
|
|
- if (id) {
|
|
|
|
// 更新内存中的群组列表
|
|
// 更新内存中的群组列表
|
|
if (!data.allowedGroups.includes(chatIdStr)) {
|
|
if (!data.allowedGroups.includes(chatIdStr)) {
|
|
data.allowedGroups.push(chatIdStr);
|
|
data.allowedGroups.push(chatIdStr);
|
|
saveData();
|
|
saveData();
|
|
|
|
+ console.log(`群组已添加 - ID: ${chatIdStr}, 名称: ${groupData.groupName}`);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ // 发送欢迎消息
|
|
|
|
+ await bot.sendMessage(chatId, '感谢添加我为群组成员!使用 /help 查看可用命令。', {
|
|
|
|
+ parse_mode: 'HTML'
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 发送账单消息
|
|
|
|
+ const billMessage = await generateBillMessage(chatId);
|
|
|
|
+ if (billMessage) {
|
|
|
|
+ await bot.sendMessage(chatId, billMessage, {
|
|
|
|
+ parse_mode: 'HTML',
|
|
|
|
+ reply_markup: generateInlineKeyboard(chatId)
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ } catch (messageError) {
|
|
|
|
+ console.error('发送消息失败:', messageError.message);
|
|
|
|
+ }
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('创建群组失败:', {
|
|
|
|
+ 错误: error.message,
|
|
|
|
+ 群组ID: groupData.groupId
|
|
|
|
+ });
|
|
|
|
+ try {
|
|
|
|
+ await bot.sendMessage(chatId, '添加群组失败,请联系管理员。', {
|
|
|
|
+ parse_mode: 'HTML'
|
|
|
|
+ });
|
|
|
|
+ } catch (messageError) {
|
|
|
|
+ console.error('发送错误消息失败:', messageError.message);
|
|
}
|
|
}
|
|
- console.log('机器人首次被添加到群组');
|
|
|
|
- console.log(formatLog(groupInfo));
|
|
|
|
- await sendMessage(chatId, '感谢添加我为群组成员!使用 /help 查看可用命令。');
|
|
|
|
- } else {
|
|
|
|
- await sendMessage(chatId, '添加群组失败,请联系管理员。');
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch (error) {
|
|
} catch (error) {
|
|
- console.error(formatLog({
|
|
|
|
- 错误: '处理机器人首次加入群组失败',
|
|
|
|
- 详情: error.message
|
|
|
|
- }));
|
|
|
|
|
|
+ console.error('处理群组添加失败:', error.message);
|
|
await sendMessage(chatId, '添加群组失败,请联系管理员。');
|
|
await sendMessage(chatId, '添加群组失败,请联系管理员。');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1116,12 +1322,19 @@ bot.on('my_chat_member', async (msg) => {
|
|
chatType === 'supergroup' ? 'supergroup' : 'group';
|
|
chatType === 'supergroup' ? 'supergroup' : 'group';
|
|
|
|
|
|
// 如果是机器人首次被添加到群组(从非成员变为成员)
|
|
// 如果是机器人首次被添加到群组(从非成员变为成员)
|
|
- if (oldStatus === 'left' && newStatus === 'member' && existingGroup.group_type != newType) {
|
|
|
|
- await handleBotAdded(msg, chatId, chatType, chatIdStr, existingGroup);
|
|
|
|
|
|
+ if (oldStatus === 'left' && newStatus === 'member') {
|
|
|
|
+ if (!existingGroup) {
|
|
|
|
+ await handleBotAdded(msg, chatId, chatType, chatIdStr, null);
|
|
|
|
+ } else if (existingGroup.group_type !== newType) {
|
|
|
|
+ await handleBotAdded(msg, chatId, chatType, chatIdStr, existingGroup);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
if (existingGroup) {
|
|
if (existingGroup) {
|
|
await handleGroupUpdate(msg, chatId, chatType, chatIdStr, existingGroup, newStatus);
|
|
await handleGroupUpdate(msg, chatId, chatType, chatIdStr, existingGroup, newStatus);
|
|
|
|
+ } else if (newStatus === 'member') {
|
|
|
|
+ // 如果是新群组且机器人被添加为成员
|
|
|
|
+ await handleBotAdded(msg, chatId, chatType, chatIdStr, null);
|
|
}
|
|
}
|
|
} catch (error) {
|
|
} catch (error) {
|
|
console.error(formatLog({
|
|
console.error(formatLog({
|