d280e5e5873797786520adaa8fdff631c07e2438
- 通知重构:归档与通知解耦(Listings.notified 列),tick 末尾统一发,1s 间隔,失败自动重试(30s tick) - 每商品一条图文消息:title/price/condition/seller 名/product_url + 高清图 - 图片用 multipart 上传本地字节(原先传 URL 让 Telegram 下载,遇 carousell CDN 不稳定导致间歇 400) - 图片 URL 去 _progressive_thumbnail 后缀(高清原图) - condition 归一化:New→Brand new、Used→Used,加第 6 档;从所有 paragraph 找 condition(修位置漂移) - listed_at 加 active_bump fallback(被顶置商品) - compose extra_hosts 钉 api.telegram.org 到 IPv4 149.154.166.110(容器无 IPv6 时 DNS 只返 AAAA) - bot 换 @carousellFoundBot,chat @MrFullStackDev
carousell-monitor
Watches Carousell search pages (sorted by recent) for new listings, archives every listing to a NocoDB base (with image URL + thumbnail), and alerts Telegram.
How it works
monitor.pyruns in a Docker container on DSM, self-bootstrapping its NocoDB schema (Listings+Settingstables) and looping forever.- Every
TICK_SECONDSit reads the watch list from the Settings table and polls each enabled watch's URL on its owncheck_interval_minutes. - Dedupe key =
product_url(param-less listing URL). First run per watch = seed archive only (no Telegram). After that, new listings are archived and alerted as"<title>: N new listings". - The container marks itself unhealthy (Docker healthcheck) if a tick fails to extract / gets rate-limited / crashes.
Schema
Listings — product_url (unique), title, price (numeric), condition
(SingleSelect), image_url, image (Attachment → thumbnail), seller_name,
seller_url, search_title, search_url, listed_at, first_seen_at.
Settings — title, url, enabled, notify, check_interval_minutes,
last_checked_at. Add/remove watches here from the NocoDB UI; no redeploy needed.
Run
# local (against LAN NocoDB)
NOCODB_URL=http://192.168.137.2:10380 \
NOCODB_TOKEN=... TELEGRAM_BOT_TOKEN=... TELEGRAM_CHAT_ID=... \
python monitor.py
# docker
docker build -t hoelee/carousell-monitor:latest .
docker compose up -d
Deploy (DSM via Portainer)
Private build — no registry. The compose at /volume1/docker/carousell-monitor
is cloned from Gitea and built on DSM (build: .), then deployed as a Portainer
stack with the secrets passed as stack environment variables.
# on DSM
cd /volume1/docker/carousell-monitor
sudo docker compose up -d --build
Files
monitor.py— main loop, schema bootstrap, fetch/parse, NocoDB IO, Telegram.healthcheck.py— Docker HEALTHCHECK probe (/data/health.json).Dockerfile,docker-compose.yml,.env.example.AGENTS.md— AI-agent entry.SECRETS.md— credentials (private repo).
Description
Watches Carousell search pages for new listings, archives every result to NocoDB with photos, and pushes Telegram alerts. Python stdlib, self-hosted Docker/Portainer stack (NocoDB + monitor in one compose file).
alertingautomationcarouselldockerdocker-composelisting-trackermalaysiamarketplacemonitornocodbnotificationsportainerprice-monitorpythonscraperself-hostedtelegram-bot
Readme
MIT
489 KiB
Languages
Python
99.6%
Dockerfile
0.4%