Last active
August 30, 2025 16:15
-
-
Save behnamonline/03ae7d9f517200a08ba4ce3712b707fe to your computer and use it in GitHub Desktop.
Web Scraper to Telegram Bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
create a KV and bind to your worker -> kv_link | |
*/ | |
const pageUrl = "https://ledc.ir/%D8%AE%D8%A7%D9%85%D9%88%D8%B4%DB%8C%D9%87%D8%A7%DB%8C-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D8%B1%DB%8C%D8%B2%DB%8C-%D8%B4%D8%AF%D9%87"; | |
const botToken = "2365785233:AAG7afaplinQtnGgLvfgEgsAhbUQERSSYXFo"; | |
const chatId = "@barghmire"; | |
export default { | |
async fetch(request, env, ctx) { | |
const url = new URL(request.url); | |
if (url.pathname == "/bot" || url.pathname.startsWith("/bot")) { | |
return handleRequest(env, request); | |
} else { | |
return new Response(firstpage, { status: 200 , headers:{"Content-type":"text/html"} }); | |
} | |
}, | |
async scheduled(event, env, ctx) { | |
ctx.waitUntil(handleRequest(env)); | |
}, | |
}; | |
async function handleRequest(env, request = null) { | |
const kv = env.kv_link; | |
let dev = false; | |
if (request) { | |
const url = new URL(request.url); | |
if (url.searchParams.get("dev") === "1") { | |
dev = true; | |
} | |
} | |
const url = gproxy(pageUrl); // استفاده از گوگل ترسلیت برای لود کردن صفحه | |
try { | |
const res = await fetch(url, { | |
headers: { | |
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115 Safari/537.36", | |
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", | |
"Accept-Language": "fa-IR,fa;q=0.9,en;q=0.8" | |
} | |
}); | |
const html = await res.text(); | |
// شروع پردازش صفحه | |
const conditions = [ | |
["بروجرد", "جعفری"], | |
["بروجرد", "بهار"] | |
]; | |
const tableMatch = html.match(/<table[\s\S]*?<\/table>/i); | |
const firstTable = tableMatch ? tableMatch[0] : ""; | |
const trMatches = [...firstTable.matchAll(/<tr[\s\S]*?<\/tr>/gi)]; | |
const rows = []; | |
trMatches.forEach((tr, idx) => { | |
const trHtml = tr[0]; | |
const text = trHtml.replace(/<[^>]+>/g, " "); // متن خالص | |
const matched = conditions.find(words => | |
words.every(w => text.includes(w)) | |
); | |
if (matched) { | |
const tdMatches = [...trHtml.matchAll(/<td[^>]*>([\s\S]*?)<\/td>/gi)]; | |
const third = tdMatches[2] ? tdMatches[2][1].replace(/<[^>]+>/g, "").trim() : null; | |
rows.push({ label: matched.join(","), value: third }); | |
} | |
}); | |
const date = extractPersianDate(html) || "none"; | |
const lastDate = await kv.get("last_date"); | |
if (!dev) { | |
if (date == "none") { | |
return new Response("try again ...", { status: 200 }); | |
} | |
if (lastDate === date) { | |
return new Response("تاریخ مشابه قبلی است، ارسال انجام نشد.", { status: 200 }); | |
} | |
} | |
let message = date + "\n\n"; | |
rows.forEach(r => { | |
message += `<b>${r.label}: ${r.value}</b>\n`; | |
}); | |
// پایان پردازش صفخه | |
// ارسال به تلگرام | |
const telegramUrl = `https://api.telegram.org/bot${botToken}/sendMessage?chat_id=${chatId}&text=${encodeURIComponent(message)}&parse_mode=html`; | |
await fetch(telegramUrl); | |
await kv.put("last_date", date); | |
if (dev) { | |
return new Response(message+"\n"+html, { headers: { "Content-Type": "text/plain; charset=utf-8" } }); | |
} | |
return new Response(message, { headers: { "Content-Type": "text/plain; charset=utf-8" } }); | |
} catch (err) { | |
return new Response("Error: " + err.message, { status: 500 }); | |
} | |
} | |
function gproxy(url) { | |
try { | |
let u = new URL(url); | |
u.hostname = u.hostname.replace(/\./g, "-") + ".translate.goog"; | |
["_x_tr_sl=en", "_x_tr_tl=fa", "_x_tr_hl=en", "_x_tr_pto=wapp"] | |
.forEach(p => { let [k, v] = p.split("="); u.searchParams.set(k, v) }); | |
return u.toString(); | |
} catch (e) { return null } | |
} | |
function extractPersianDate(text) { | |
const match = text.match(/(شنبه|یکشنبه|دوشنبه|سهشنبه|سه شنبه|چهارشنبه|پنجشنبه|جمعه)\s+\d{4}\/\d{2}\/\d{2}/); | |
return match ? match[0] : null; | |
} | |
const firstpage = ` | |
<!DOCTYPE html> | |
<html lang="fa" dir="rtl"> | |
<head> | |
<meta charset="utf-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |
<title>ربات برق</title> | |
<meta name="color-scheme" content="dark light" /> | |
<link rel="preconnect" href="https://fonts.googleapis.com"> | |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800&display=swap" rel="stylesheet"> | |
<style> | |
:root { | |
--bg: #0b1220; | |
--card: rgba(255, 255, 255, 0.06); | |
--button-start: #ee22c0; | |
--button-end: #990d74; | |
--button-text: #f8fafc; | |
--ring: rgba(59, 130, 246, 0.5); | |
--button-success: #22c55e; | |
} | |
* { box-sizing: border-box; } | |
html, body { height: 100%; } | |
body { | |
margin: 0; | |
background: radial-gradient(1200px 800px at 70% 20%, #111a32 0%, transparent 60%), | |
radial-gradient(900px 600px at 20% 80%, #0e1a30 0%, transparent 55%), | |
var(--bg); | |
color: #e5e7eb; | |
font-family: 'Inter', system-ui, -apple-system, Segoe UI, Roboto, 'Helvetica Neue', Arial, "Noto Sans", "Apple Color Emoji", "Segoe UI Emoji"; | |
display: grid; | |
place-items: center; | |
min-height: 100svh; | |
} | |
.wrap { | |
width: min(92vw, 700px); | |
padding: 32px; | |
border-radius: 24px; | |
background: linear-gradient(180deg, rgba(255,255,255,0.08), rgba(255,255,255,0.03)); | |
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45), inset 0 1px 0 rgba(255,255,255,0.06); | |
backdrop-filter: blur(8px); | |
-webkit-backdrop-filter: blur(8px); | |
display: grid; | |
gap: 20px; | |
justify-items: center; | |
text-align: center; | |
} | |
h1 { margin: 0; font-size: clamp(22px, 4vw, 28px); font-weight: 800; } | |
p { margin: 0; font-size: clamp(13px, 2.8vw, 14px); opacity: 0.7; } | |
.btn { | |
--sizeY: clamp(56px, 12vw, 84px); | |
--sizeX: clamp(200px, 65vw, 380px); | |
border: 0; | |
border-radius: 999px; | |
height: var(--sizeY); | |
width: var(--sizeX); | |
font-size: clamp(18px, 5vw, 26px); | |
font-weight: 800; | |
color: var(--button-text); | |
background: linear-gradient(135deg, var(--button-start), var(--button-end)); | |
cursor: pointer; | |
position: relative; | |
transition: transform 200ms ease, filter 200ms ease, box-shadow 200ms ease, background 200ms ease; | |
outline: none; | |
} | |
.btn:before { | |
content: ""; | |
position: absolute; | |
inset: 2px; | |
border-radius: 999px; | |
background: linear-gradient(135deg, rgba(255,255,255,0.16), rgba(255,255,255,0.02)); | |
pointer-events: none; | |
} | |
.btn.success { | |
background: var(--button-success) !important; | |
} | |
.btn.loading { | |
animation: pulseBg 0.5s infinite alternate; | |
} | |
@keyframes pulseBg { | |
from { filter: brightness(0.7); } | |
to { filter: brightness(1.3); } | |
} | |
.pulse { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; filter: blur(30px); opacity: 0.35; animation: float 6s ease-in-out infinite; } | |
.pulse span { width: min(80vw, 420px); height: min(80vw, 420px); border-radius: 50%; background: radial-gradient(circle at 50% 50%, #2563eb, transparent 60%); } | |
@keyframes float { 0%,100%{transform:translateY(0);} 50%{transform:translateY(6px);} } | |
</style> | |
</head> | |
<body> | |
<div class="wrap"> | |
<h1>ربات برق</h1> | |
<img src="https://i.ibb.co/ZzFk08G6/hhh.png"style="width:130px;z-index:999"> | |
<p>برای ارسال روی دکمه زیر بزن.</p> | |
<div class="pulse" aria-hidden="true"><span></span></div> | |
<button id="startBtn" class="btn" type="button">...</button> | |
</div> | |
<script> | |
const btn = document.getElementById('startBtn'); | |
btn.textContent = 'بزن'; | |
btn.addEventListener('click', async () => { | |
btn.textContent = '...'; | |
btn.classList.add('loading'); | |
try { | |
const res = await fetch('/bot/?dev=1'); | |
if (res.ok) { | |
btn.classList.remove('loading'); | |
btn.classList.add('success'); | |
btn.textContent = 'ارسال شد'; | |
setTimeout(() => { | |
btn.classList.remove('success'); | |
btn.textContent = 'بزن'; | |
}, 2000); | |
} else { | |
btn.classList.remove('loading'); | |
btn.textContent = 'خطا'; | |
setTimeout(() => { btn.textContent = 'بزن'; }, 1000); | |
} | |
} catch (e) { | |
btn.classList.remove('loading'); | |
btn.textContent = 'خطا'; | |
setTimeout(() => { btn.textContent = 'بزن'; }, 1000); | |
} | |
}); | |
</script> | |
</body> | |
</html> | |
`; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment