Spaces:
Runtime error
Runtime error
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); | |
} | |
})(); | |