Spaces:
Sleeping
Sleeping
Update botsignal.py
Browse files- botsignal.py +12 -31
botsignal.py
CHANGED
|
@@ -319,7 +319,7 @@ INVITE_PATTERNS = [
|
|
| 319 |
# tautan undangan/shortener
|
| 320 |
r"(t\.me\/joinchat|t\.me\/\+|telegram\.me\/|discord\.gg\/|wa\.me\/|whatsapp\.com\/)",
|
| 321 |
r"(bit\.ly|tinyurl\.com|linktr\.ee)",
|
| 322 |
-
#
|
| 323 |
# r"t\.me\/[A-Za-z0-9_]+",
|
| 324 |
]
|
| 325 |
INVITE_REGEXES = [re.compile(p, re.IGNORECASE) for p in INVITE_PATTERNS]
|
|
@@ -409,7 +409,7 @@ async def _send_initial(msg, text: str) -> int:
|
|
| 409 |
try:
|
| 410 |
if getattr(msg, "photo", None):
|
| 411 |
m = await client.send_file(
|
| 412 |
-
TARGET_CHAT, msg.photo, caption=text, caption_entities=None, force_document=False
|
| 413 |
)
|
| 414 |
return m.id
|
| 415 |
doc = getattr(msg, "document", None)
|
|
@@ -426,7 +426,7 @@ async def _send_initial(msg, text: str) -> int:
|
|
| 426 |
ext = ext_guess
|
| 427 |
bio.name = f"media{ext}"
|
| 428 |
m = await client.send_file(
|
| 429 |
-
TARGET_CHAT, bio, caption=text, caption_entities=None, force_document=False
|
| 430 |
)
|
| 431 |
return m.id
|
| 432 |
except FloodWaitError as e:
|
|
@@ -435,8 +435,7 @@ async def _send_initial(msg, text: str) -> int:
|
|
| 435 |
except Exception as e:
|
| 436 |
debug_log("Gagal kirim media awal, fallback text", str(e))
|
| 437 |
try:
|
| 438 |
-
|
| 439 |
-
m = await client.send_message(TARGET_CHAT, text, link_preview=True, parse_mode='md')
|
| 440 |
return m.id
|
| 441 |
except FloodWaitError as e:
|
| 442 |
await asyncio.sleep(e.seconds + 1)
|
|
@@ -461,8 +460,7 @@ async def post_or_update(keyword: str, body: str, new_tier: str, src_msg, *, upd
|
|
| 461 |
# Jika tier naik, selalu edit
|
| 462 |
if TIER_ORDER.get(new_tier, 0) > TIER_ORDER.get(prev["tier"], 0):
|
| 463 |
try:
|
| 464 |
-
|
| 465 |
-
await client.edit_message(TARGET_CHAT, prev["msg_id"], text, parse_mode='md')
|
| 466 |
prev["tier"] = new_tier
|
| 467 |
last_body[keyword] = body
|
| 468 |
last_update_ts[keyword] = now_ts
|
|
@@ -490,25 +488,24 @@ async def post_or_update(keyword: str, body: str, new_tier: str, src_msg, *, upd
|
|
| 490 |
return
|
| 491 |
|
| 492 |
try:
|
| 493 |
-
# --- UPGRADE --- Menggunakan parse_mode='md' agar format **bold** berfungsi
|
| 494 |
if UPDATE_STRATEGY == "edit":
|
| 495 |
-
await client.edit_message(TARGET_CHAT, prev["msg_id"], text
|
| 496 |
last_body[keyword] = body
|
| 497 |
last_update_ts[keyword] = now_ts
|
| 498 |
if prev["msg_id"] != -1:
|
| 499 |
db_save_last_posted(keyword, prev["msg_id"], new_tier)
|
| 500 |
elif UPDATE_STRATEGY == "reply":
|
| 501 |
# kirim balasan ke pesan awal entitas
|
| 502 |
-
await client.send_message(TARGET_CHAT, text, reply_to=prev["msg_id"], link_preview=True
|
| 503 |
last_body[keyword] = body
|
| 504 |
last_update_ts[keyword] = now_ts
|
| 505 |
elif UPDATE_STRATEGY == "new":
|
| 506 |
-
await client.send_message(TARGET_CHAT, text, link_preview=True
|
| 507 |
last_body[keyword] = body
|
| 508 |
last_update_ts[keyword] = now_ts
|
| 509 |
else:
|
| 510 |
# fallback ke edit jika value salah
|
| 511 |
-
await client.edit_message(TARGET_CHAT, prev["msg_id"], text
|
| 512 |
last_body[keyword] = body
|
| 513 |
last_update_ts[keyword] = now_ts
|
| 514 |
if prev["msg_id"] != -1:
|
|
@@ -771,17 +768,6 @@ async def process_message(msg, source_chat_id: int) -> None:
|
|
| 771 |
if not cleaned_body.strip():
|
| 772 |
debug_log("Semua kalimat terfilter (kosong), dilewati", orig_text)
|
| 773 |
return
|
| 774 |
-
|
| 775 |
-
# --- UPGRADE --- Dapatkan nama channel sumber untuk transparansi
|
| 776 |
-
try:
|
| 777 |
-
source_entity = await client.get_entity(source_chat_id)
|
| 778 |
-
source_name = getattr(source_entity, 'title', 'Sumber Tidak Dikenal')
|
| 779 |
-
except Exception:
|
| 780 |
-
source_name = 'Sumber Tidak Dikenal'
|
| 781 |
-
|
| 782 |
-
# --- UPGRADE --- Tambahkan footer yang berisi info sumber dan peran
|
| 783 |
-
footer = f"\n\n**Sumber:** {source_name} | **Peran:** {role.upper()}"
|
| 784 |
-
body_with_footer = cleaned_body + footer
|
| 785 |
|
| 786 |
# Backfill safety: saat startup, hindari pesan yang terlalu lama
|
| 787 |
cutoff = startup_time_utc - timedelta(
|
|
@@ -797,8 +783,7 @@ async def process_message(msg, source_chat_id: int) -> None:
|
|
| 797 |
if entity_key:
|
| 798 |
recent_entity_keys.append(entity_key)
|
| 799 |
|
| 800 |
-
|
| 801 |
-
await post_or_update(topic_key, body_with_footer, class_label, msg, update_like=update_like)
|
| 802 |
debug_log(
|
| 803 |
f"Posted/Edited (role={role}, unique_groups={unique_groups}, key={topic_key}, tier={class_label}, update_like={update_like})",
|
| 804 |
orig_text,
|
|
@@ -808,17 +793,14 @@ async def process_message(msg, source_chat_id: int) -> None:
|
|
| 808 |
async def backfill_history(entity, limit: int) -> None:
|
| 809 |
if limit <= 0:
|
| 810 |
return
|
| 811 |
-
print(f"[Backfill] Tarik {limit} pesan terakhir dari {entity
|
| 812 |
async for m in client.iter_messages(entity, limit=limit):
|
| 813 |
try:
|
| 814 |
-
# --- UPGRADE --- Memastikan ID diteruskan dengan benar
|
| 815 |
chat_id = getattr(m.peer_id, 'channel_id', None) or \
|
| 816 |
getattr(m.peer_id, 'chat_id', None) or \
|
| 817 |
getattr(m.peer_id, 'user_id', None)
|
| 818 |
if chat_id:
|
| 819 |
-
# Telethon terkadang memberikan ID negatif untuk grup, kita butuh absolutnya
|
| 820 |
await process_message(m, source_chat_id=abs(chat_id))
|
| 821 |
-
|
| 822 |
except Exception as e:
|
| 823 |
debug_log(f"Error saat memproses backfill untuk pesan ID {m.id}", str(e))
|
| 824 |
|
|
@@ -827,7 +809,7 @@ async def backfill_history(entity, limit: int) -> None:
|
|
| 827 |
@client.on(events.NewMessage(chats=SOURCE_CHATS))
|
| 828 |
async def on_new_message(event):
|
| 829 |
try:
|
| 830 |
-
await process_message(event.message, source_chat_id=event.chat_id)
|
| 831 |
except Exception as e:
|
| 832 |
print(f"Process error di chat {event.chat_id}: {e}")
|
| 833 |
|
|
@@ -839,7 +821,6 @@ async def _resolve_and_tag_chats(raw_list, role_label: str) -> list:
|
|
| 839 |
try:
|
| 840 |
ent = await client.get_entity(src)
|
| 841 |
resolved.append(ent)
|
| 842 |
-
# --- UPGRADE --- Memastikan ID yang disimpan selalu positif untuk konsistensi
|
| 843 |
chat_roles[abs(int(ent.id))] = role_label
|
| 844 |
except Exception as e:
|
| 845 |
print(f"Gagal resolve sumber {src}: {e}")
|
|
|
|
| 319 |
# tautan undangan/shortener
|
| 320 |
r"(t\.me\/joinchat|t\.me\/\+|telegram\.me\/|discord\.gg\/|wa\.me\/|whatsapp\.com\/)",
|
| 321 |
r"(bit\.ly|tinyurl\.com|linktr\.ee)",
|
| 322 |
+
# UPGRADE: Aturan agresif yang memblokir semua link t.me biasa tetap dihapus
|
| 323 |
# r"t\.me\/[A-Za-z0-9_]+",
|
| 324 |
]
|
| 325 |
INVITE_REGEXES = [re.compile(p, re.IGNORECASE) for p in INVITE_PATTERNS]
|
|
|
|
| 409 |
try:
|
| 410 |
if getattr(msg, "photo", None):
|
| 411 |
m = await client.send_file(
|
| 412 |
+
TARGET_CHAT, msg.photo, caption=text, caption_entities=None, force_document=False
|
| 413 |
)
|
| 414 |
return m.id
|
| 415 |
doc = getattr(msg, "document", None)
|
|
|
|
| 426 |
ext = ext_guess
|
| 427 |
bio.name = f"media{ext}"
|
| 428 |
m = await client.send_file(
|
| 429 |
+
TARGET_CHAT, bio, caption=text, caption_entities=None, force_document=False
|
| 430 |
)
|
| 431 |
return m.id
|
| 432 |
except FloodWaitError as e:
|
|
|
|
| 435 |
except Exception as e:
|
| 436 |
debug_log("Gagal kirim media awal, fallback text", str(e))
|
| 437 |
try:
|
| 438 |
+
m = await client.send_message(TARGET_CHAT, text, link_preview=True)
|
|
|
|
| 439 |
return m.id
|
| 440 |
except FloodWaitError as e:
|
| 441 |
await asyncio.sleep(e.seconds + 1)
|
|
|
|
| 460 |
# Jika tier naik, selalu edit
|
| 461 |
if TIER_ORDER.get(new_tier, 0) > TIER_ORDER.get(prev["tier"], 0):
|
| 462 |
try:
|
| 463 |
+
await client.edit_message(TARGET_CHAT, prev["msg_id"], text)
|
|
|
|
| 464 |
prev["tier"] = new_tier
|
| 465 |
last_body[keyword] = body
|
| 466 |
last_update_ts[keyword] = now_ts
|
|
|
|
| 488 |
return
|
| 489 |
|
| 490 |
try:
|
|
|
|
| 491 |
if UPDATE_STRATEGY == "edit":
|
| 492 |
+
await client.edit_message(TARGET_CHAT, prev["msg_id"], text)
|
| 493 |
last_body[keyword] = body
|
| 494 |
last_update_ts[keyword] = now_ts
|
| 495 |
if prev["msg_id"] != -1:
|
| 496 |
db_save_last_posted(keyword, prev["msg_id"], new_tier)
|
| 497 |
elif UPDATE_STRATEGY == "reply":
|
| 498 |
# kirim balasan ke pesan awal entitas
|
| 499 |
+
await client.send_message(TARGET_CHAT, text, reply_to=prev["msg_id"], link_preview=True)
|
| 500 |
last_body[keyword] = body
|
| 501 |
last_update_ts[keyword] = now_ts
|
| 502 |
elif UPDATE_STRATEGY == "new":
|
| 503 |
+
await client.send_message(TARGET_CHAT, text, link_preview=True)
|
| 504 |
last_body[keyword] = body
|
| 505 |
last_update_ts[keyword] = now_ts
|
| 506 |
else:
|
| 507 |
# fallback ke edit jika value salah
|
| 508 |
+
await client.edit_message(TARGET_CHAT, prev["msg_id"], text)
|
| 509 |
last_body[keyword] = body
|
| 510 |
last_update_ts[keyword] = now_ts
|
| 511 |
if prev["msg_id"] != -1:
|
|
|
|
| 768 |
if not cleaned_body.strip():
|
| 769 |
debug_log("Semua kalimat terfilter (kosong), dilewati", orig_text)
|
| 770 |
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 771 |
|
| 772 |
# Backfill safety: saat startup, hindari pesan yang terlalu lama
|
| 773 |
cutoff = startup_time_utc - timedelta(
|
|
|
|
| 783 |
if entity_key:
|
| 784 |
recent_entity_keys.append(entity_key)
|
| 785 |
|
| 786 |
+
await post_or_update(topic_key, cleaned_body, class_label, msg, update_like=update_like)
|
|
|
|
| 787 |
debug_log(
|
| 788 |
f"Posted/Edited (role={role}, unique_groups={unique_groups}, key={topic_key}, tier={class_label}, update_like={update_like})",
|
| 789 |
orig_text,
|
|
|
|
| 793 |
async def backfill_history(entity, limit: int) -> None:
|
| 794 |
if limit <= 0:
|
| 795 |
return
|
| 796 |
+
print(f"[Backfill] Tarik {limit} pesan terakhir dari {getattr(entity, 'title', 'Unknown')} ...")
|
| 797 |
async for m in client.iter_messages(entity, limit=limit):
|
| 798 |
try:
|
|
|
|
| 799 |
chat_id = getattr(m.peer_id, 'channel_id', None) or \
|
| 800 |
getattr(m.peer_id, 'chat_id', None) or \
|
| 801 |
getattr(m.peer_id, 'user_id', None)
|
| 802 |
if chat_id:
|
|
|
|
| 803 |
await process_message(m, source_chat_id=abs(chat_id))
|
|
|
|
| 804 |
except Exception as e:
|
| 805 |
debug_log(f"Error saat memproses backfill untuk pesan ID {m.id}", str(e))
|
| 806 |
|
|
|
|
| 809 |
@client.on(events.NewMessage(chats=SOURCE_CHATS))
|
| 810 |
async def on_new_message(event):
|
| 811 |
try:
|
| 812 |
+
await process_message(event.message, source_chat_id=abs(event.chat_id))
|
| 813 |
except Exception as e:
|
| 814 |
print(f"Process error di chat {event.chat_id}: {e}")
|
| 815 |
|
|
|
|
| 821 |
try:
|
| 822 |
ent = await client.get_entity(src)
|
| 823 |
resolved.append(ent)
|
|
|
|
| 824 |
chat_roles[abs(int(ent.id))] = role_label
|
| 825 |
except Exception as e:
|
| 826 |
print(f"Gagal resolve sumber {src}: {e}")
|