import 'dotenv/config'; import { Telegraf } from 'telegraf'; import qrcode from 'qrcode-terminal'; import { Client, LocalAuth, MessageMedia } from 'whatsapp-web.js'; const { TELEGRAM_BOT_TOKEN, WA_TARGET, WA_GROUP_ID } = process.env; if (!TELEGRAM_BOT_TOKEN) { console.error('⚠️ ضع TELEGRAM_BOT_TOKEN في .env'); process.exit(1); } if (!WA_TARGET && !WA_GROUP_ID) { console.error('⚠️ ضع WA_TARGET أو WA_GROUP_ID في .env'); process.exit(1); } // ---- WhatsApp Web client ---- const waClient = new Client({ authStrategy: new LocalAuth({ clientId: 'tg2wa-session' }), puppeteer: { headless: true, // شغّل بدون واجهة args: ['--no-sandbox', '--disable-setuid-sandbox'] } }); // QR لأول مرة waClient.on('qr', qr => qrcode.generate(qr, { small: true })); waClient.on('ready', () => console.log('✅ WhatsApp جاهز')); waClient.on('auth_failure', m => console.error('❌ Auth failure:', m)); waClient.on('disconnected', r => console.warn('⚠️ WA disconnected:', r)); // مساعدات const numberToChatId = (num) => `${num}@c.us`; const targetChatId = WA_GROUP_ID ? WA_GROUP_ID : numberToChatId(WA_TARGET); // إرسال نص لواتساب async function sendTextToWA(text) { try { await waClient.sendMessage(targetChatId, text); } catch (e) { console.error('❌ فشل إرسال نص لواتساب:', e.message); } } // إرسال ميديا من URL async function sendMediaToWA(url, caption = '') { try { const media = await MessageMedia.fromUrl(url); await waClient.sendMessage(targetChatId, media, { caption }); } catch (e) { console.error('❌ فشل إرسال ميديا لواتساب:', e.message, url); } } // ---- Telegram bot ---- const bot = new Telegraf(TELEGRAM_BOT_TOKEN); // أي رسالة نصية في تيليجرام → واتساب bot.on('text', async (ctx) => { const from = ctx.from?.username ? `@${ctx.from.username}` : (ctx.from?.first_name || 'TG'); const chatTitle = ctx.chat?.title ? `#${ctx.chat.title}` : ''; const text = ctx.message.text; await sendTextToWA(`💬 من تيليجرام ${chatTitle}\n👤 ${from}:\n${text}`); }); // صور bot.on('photo', async (ctx) => { try { const photoSizes = ctx.message.photo; const largest = photoSizes[photoSizes.length - 1]; const fileId = largest.file_id; const link = await ctx.telegram.getFileLink(fileId); const caption = ctx.message.caption || ''; await sendMediaToWA(link.href, caption ? `🖼️ ${caption}` : '🖼️ صورة من تيليجرام'); } catch (e) { console.error('❌ فشل معالجة صورة TG:', e.message); } }); // فيديو bot.on('video', async (ctx) => { try { const fileId = ctx.message.video.file_id; const link = await ctx.telegram.getFileLink(fileId); const caption = ctx.message.caption || ''; await sendMediaToWA(link.href, caption ? `🎬 ${caption}` : '🎬 فيديو من تيليجرام'); } catch (e) { console.error('❌ فشل معالجة فيديو TG:', e.message); } }); // ملفات (مستندات) bot.on('document', async (ctx) => { try { const fileId = ctx.message.document.file_id; const link = await ctx.telegram.getFileLink(fileId); const name = ctx.message.document.file_name || 'ملف'; await sendMediaToWA(link.href, `📎 ${name}`); } catch (e) { console.error('❌ فشل معالجة مستند TG:', e.message); } }); // ستickers (نحاول تحويلها كصورة) bot.on('sticker', async (ctx) => { try { const fileId = ctx.message.sticker.file_id; const link = await ctx.telegram.getFileLink(fileId); await sendMediaToWA(link.href, '🧩 ملصق من تيليجرام'); } catch (e) { console.error('❌ فشل معالجة ملصق TG:', e.message); } }); // تشغيل النظام (async () => { try { await waClient.initialize(); await bot.launch(); console.log('🚀 بدأ الجسر: Telegram → WhatsApp'); // إيقاف نظيف process.once('SIGINT', () => bot.stop('SIGINT')); process.once('SIGTERM', () => bot.stop('SIGTERM')); } catch (e) { console.error('❌ فشل الإقلاع:', e.message); process.exit(1); } })();