feat: alert on any new notification, drop keyword filtering
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -25,7 +25,6 @@ FLARESOLVERR_URL = os.environ.get("FLARESOLVERR_URL", "http://192.168.10.76:819
|
||||
ZIPAIR_NOTIF_LIST = "https://www.zipair.net/en/notification/"
|
||||
ZIPAIR_NOTIF_BASE = "https://www.zipair.net"
|
||||
|
||||
TRIGGER_KEYWORDS = ["singapore", "winter"]
|
||||
|
||||
# ── FlareSolverr fetch ───────────────────────────────────────────────────────
|
||||
|
||||
@@ -83,8 +82,10 @@ def get_notification_slugs() -> list[str]:
|
||||
return []
|
||||
|
||||
# Match /en/notification/some-slug or /en/notification/123
|
||||
slugs = re.findall(r'href="(/(?:en|ja|ko|th|zh-tw|zh-cn)/notification/([^"?#/]+))"', html)
|
||||
# slugs is list of (full_path, slug) — dedupe by slug
|
||||
# Try both double and single quotes, and also JSON-style escaped URLs
|
||||
slugs = re.findall(r'["\'](/(?:en|ja|ko|th|zh-tw|zh-cn)/notification/([^"\'?#/]+))["\']', html)
|
||||
|
||||
# dedupe by slug
|
||||
seen = set()
|
||||
result = []
|
||||
for path, slug in slugs:
|
||||
@@ -94,20 +95,11 @@ def get_notification_slugs() -> list[str]:
|
||||
print(f" Found {len(result)} notification(s) on listing page.")
|
||||
return result # list of (slug, full_url)
|
||||
|
||||
# ── Keyword check ────────────────────────────────────────────────────────────
|
||||
|
||||
def matches_keywords(text: str) -> bool:
|
||||
lower = text.lower()
|
||||
return all(kw in lower for kw in TRIGGER_KEYWORDS)
|
||||
|
||||
# ── ntfy ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
def send_ntfy(slug: str, url: str):
|
||||
title = "✈️ ZIPAIR SIN→TYO Tickets On Sale!"
|
||||
message = (
|
||||
f"New ZIPAIR Singapore/winter announcement detected. "
|
||||
f"Check: {url}"
|
||||
)
|
||||
title = "✈️ New ZIPAIR Notification"
|
||||
message = f"New announcement posted: {slug}\n{url}"
|
||||
payload = json.dumps({
|
||||
"topic": NTFY_URL.rstrip("/").rsplit("/", 1)[-1],
|
||||
"title": title,
|
||||
@@ -138,7 +130,6 @@ def send_ntfy(slug: str, url: str):
|
||||
|
||||
def main():
|
||||
print(f"\n[{datetime.utcnow().isoformat()}Z] ZIPAIR monitor starting …")
|
||||
print(f" Keywords : {TRIGGER_KEYWORDS}")
|
||||
print(f" ntfy URL : {NTFY_URL}")
|
||||
print(f" FlareSolverr : {FLARESOLVERR_URL}")
|
||||
|
||||
@@ -159,33 +150,13 @@ def main():
|
||||
sys.exit(0)
|
||||
|
||||
print(f" {len(new_entries)} new notification(s): {[s for s,_ in new_entries]}")
|
||||
found_match = None
|
||||
|
||||
for slug, url in new_entries:
|
||||
print(f" Checking {slug} …")
|
||||
# Check slug itself first (fast, no extra fetch needed)
|
||||
if matches_keywords(slug):
|
||||
print(f" ✅ MATCH in slug: {slug}")
|
||||
found_match = (slug, url)
|
||||
break
|
||||
# Fetch full page and check content
|
||||
text = fs_fetch(url)
|
||||
time.sleep(1)
|
||||
if matches_keywords(text):
|
||||
print(f" ✅ MATCH in page content: {slug}")
|
||||
found_match = (slug, url)
|
||||
break
|
||||
print(f" No match.")
|
||||
print(f" 🚨 New notification: {slug} — sending ntfy …")
|
||||
send_ntfy(slug, url)
|
||||
|
||||
write_seen_slugs(all_slugs)
|
||||
|
||||
if found_match:
|
||||
slug, url = found_match
|
||||
print(f"\n🚨 Sending ntfy push for {slug}")
|
||||
send_ntfy(slug, url)
|
||||
print("Done — notification sent!")
|
||||
else:
|
||||
print("\nNo Singapore winter sale announcement found yet.")
|
||||
print("Done.")
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user