diff --git a/.playwright-mcp/page-2026-02-27T08-17-03-261Z.png b/.playwright-mcp/page-2026-02-27T08-17-03-261Z.png new file mode 100644 index 0000000..a631115 Binary files /dev/null and b/.playwright-mcp/page-2026-02-27T08-17-03-261Z.png differ diff --git a/telegram-bot.js b/telegram-bot.js new file mode 100644 index 0000000..c50d90a --- /dev/null +++ b/telegram-bot.js @@ -0,0 +1,238 @@ +// QwenClaw Telegram Bot - Full Integration +// Listens to Telegram and processes messages through QwenClaw + +const TELEGRAM_BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN || '7975505515:AAHqNCZuFmD3MPJyUSAg81TysQ65K6HuY2s'; +const QWENCLAW_PATH = 'C:\\Users\\admin\\qwenclaw\\bin\\qwenclaw.js'; + +async function getUpdates(offset = 0) { + const url = `https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getUpdates?offset=${offset}&timeout=30`; + const response = await fetch(url); + return await response.json(); +} + +async function sendMessage(chatId, text, parseMode = 'Markdown') { + const url = `https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage`; + const response = await fetch(url, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + chat_id: chatId, + text: text, + parse_mode: parseMode + }) + }); + return await response.json(); +} + +async function sendTyping(chatId) { + const url = `https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendChatAction`; + await fetch(url, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + chat_id: chatId, + action: 'typing' + }) + }); +} + +async function executeQwenClaw(message) { + const { exec } = require('child_process'); + const util = require('util'); + const execPromise = util.promisify(exec); + + try { + const command = `node "${QWENCLAW_PATH}" send "${message.replace(/"/g, '\\"')}"`; + const { stdout, stderr } = await execPromise(command, { + timeout: 120000, + maxBuffer: 1024 * 1024 * 5 + }); + + return { + success: true, + output: stdout || stderr || 'Task completed' + }; + } catch (error) { + return { + success: true, + output: error.stdout || error.message || 'Task sent to QwenClaw' + }; + } +} + +async function handleCommand(chatId, command) { + console.log(`Command: ${command}`); + + switch(command) { + case '/start': + await sendMessage(chatId, ` +👋 *Welcome to QwenClaw Bot!* + +I'm your AI assistant powered by QwenClaw with 152+ skills. + +*What I can do:* +• Answer questions +• Write code +• Review files +• Automate tasks +• Research topics +• And much more! + +*Commands:* +/status - Check daemon status +/skills - List skills +/help - Show help + +*Just send any message* and I'll process it! + `); + break; + + case '/status': + const { exec } = require('child_process'); + const util = require('util'); + const execPromise = util.promisify(exec); + + try { + const { stdout } = await execPromise(`node "${QWENCLAW_PATH}" status`); + await sendMessage(chatId, ` +🐾 *QwenClaw Status* +━━━━━━━━━━━━━━━━━━━━ +\`\`\` +${stdout} +\`\`\` + `, null); + } catch (error) { + await sendMessage(chatId, '❌ Error getting status: ' + error.message); + } + break; + + case '/skills': + try { + const { stdout } = await execPromise(`node "${QWENCLAW_PATH}" skills`); + await sendMessage(chatId, ` +📚 *Available Skills* +━━━━━━━━━━━━━━━━━━━━ +\`\`\` +${stdout} +\`\`\` + `, null); + } catch (error) { + await sendMessage(chatId, '❌ Error listing skills: ' + error.message); + } + break; + + case '/help': + await sendMessage(chatId, ` +❓ *Help - QwenClaw Bot* + +*How to use:* +Just send me any message and I'll process it through QwenClaw AI! + +*Examples:* +• "Write a Python function to sort a list" +• "Review my latest code changes" +• "Summarize this article: [URL]" +• "Create a todo list for my project" +• "Explain quantum computing" + +*Commands:* +/start - Welcome message +/status - Check daemon status +/skills - List available skills +/help - This help message + +*Powered by QwenClaw v2.0* +152+ skills | Always-on daemon + `); + break; + + default: + await sendMessage(chatId, `❓ Unknown command. Send /help for available commands.`); + } +} + +async function processMessage(chatId, text, messageId) { + console.log(`Processing: ${text}`); + + // Show typing indicator + await sendTyping(chatId); + + // Send acknowledgment + const ackMsg = await sendMessage(chatId, ` +🤖 *Processing your request...* + +\`${text}\` + +⏳ One moment please... + `); + + // Execute QwenClaw + const result = await executeQwenClaw(text); + + // Delete acknowledgment + try { + const deleteUrl = `https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/deleteMessage`; + await fetch(deleteUrl, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + chat_id: chatId, + message_id: ackMsg.result.message_id + }) + }); + } catch (e) { + // Ignore delete errors + } + + // Send response (truncate if too long) + let response = result.output; + if (response.length > 4000) { + response = response.substring(0, 3900) + '\n\n... (truncated)'; + } + + await sendMessage(chatId, ` +✅ *QwenClaw Response:* +━━━━━━━━━━━━━━━━━━━━ +${response} + `, null); +} + +async function main() { + console.log('🤖 QwenClaw Telegram Bot starting...'); + console.log(`Bot: @QwenClaw_X_Bot`); + console.log(`Token: ${TELEGRAM_BOT_TOKEN.substring(0, 15)}...`); + console.log('Listening for messages...\n'); + + let offset = 0; + + while (true) { + try { + const data = await getUpdates(offset); + + if (data.ok && data.result.length > 0) { + for (const update of data.result) { + offset = update.update_id + 1; + + if (update.message) { + const chatId = update.message.chat.id; + const text = update.message.text; + const messageId = update.message.message_id; + + console.log(`[${new Date().toISOString()}] From ${chatId}: ${text}`); + + if (text.startsWith('/')) { + await handleCommand(chatId, text); + } else { + await processMessage(chatId, text, messageId); + } + } + } + } + } catch (error) { + console.error('Error:', error.message); + await new Promise(resolve => setTimeout(resolve, 5000)); + } + } +} + +main();