Openclaw-skills facebook-group-monitor
git clone https://github.com/phuc-nt/openclaw-skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/phuc-nt/openclaw-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/facebook-group-monitor" ~/.claude/skills/phuc-nt-openclaw-skills-facebook-group-monitor && rm -rf "$T"
T=$(mktemp -d) && git clone --depth=1 https://github.com/phuc-nt/openclaw-skills "$T" && mkdir -p ~/.openclaw/skills && cp -r "$T/facebook-group-monitor" ~/.openclaw/skills/phuc-nt-openclaw-skills-facebook-group-monitor && rm -rf "$T"
facebook-group-monitor/SKILL.mdFacebook Group Monitor Skill
Overview
Playwright-based headless browser scraper for Facebook groups. Default behavior: captures a stitched "feed strip" (scrolls 3× viewport, crops to feed column, stitches into 1 JPEG) → agent calls vision model once with a custom prompt to extract and interpret all new posts in a single LLM call.
Requires one-time manual login via terminal to establish a persistent browser session.
Setup
See references/SETUP.md for installation and first-time login instructions.
File Locations (after install)
- Script:
scripts/fb-group-monitor.py - Shell wrapper:
scripts/fb-group-monitor.sh - Browser session: auto-created at
(persistent login)scripts/.browser-data/ - Seen posts: auto-created at
(dedup tracking)scripts/.seen-posts.json - Screenshots:
or customscripts/screenshots/--shots-dir
Commands
1. Check login session
scripts/fb-group-monitor.sh status
Output:
{"success": true, "action": "status", "message": "Session active — logged in to Facebook."}
2. Scrape new posts (with feed strip screenshot)
scripts/fb-group-monitor.sh scrape <GROUP_URL> [--limit N] [--shots-dir <PATH>]
Parameters:
: Full URL (https://www.facebook.com/groups/123456) or just group IDGROUP_URL
: Max posts to scrape (default: 10)--limit N
: ⚠️ REQUIRED for vision — save screenshots in agent workspace so image tool can read them--shots-dir <PATH>
: Skip screenshots (faster, text-only mode)--no-shots
Example:
scripts/fb-group-monitor.sh scrape "https://www.facebook.com/groups/123456789" --limit 10 --shots-dir ./temp-screenshots
Output JSON (with feed strip screenshot):
{ "success": true, "action": "scrape", "group_name": "Example Group Name", "group_url": "https://www.facebook.com/groups/123456789", "total_scraped": 6, "new_count": 3, "feed_screenshot": "/path/to/temp-screenshots/feed_abc12345_1741800000.jpg", "posts": [ { "author": "Poster Name", "text": "Post content (may be truncated by Facebook's 'See more')...", "url": "https://facebook.com/groups/123456/posts/789", "images": 3 }, { "author": "Another Poster", "text": "Text-only post, no images...", "url": "https://facebook.com/groups/123456/posts/790", "images": 0 } ], "message": "Found 3 new posts / 6 total." }
Note:
is a single stitched JPEG covering the full feed (3 viewport scrolls). Individual posts no longer have afeed_screenshot— usescreenshot_path(top-level) instead.feed_screenshot
3. Clean old screenshots
scripts/fb-group-monitor.sh clean-shots
Auto-removes screenshots older than 48h and caps at 100 max. Script also auto-cleans before each scrape.
4. Login (one-time, from terminal)
scripts/fb-group-monitor.sh login
Opens browser, login manually, press Enter to save session. Session lasts weeks/months.
Agent Workflow
When triggered by cron or user request to check a group:
Step 1: Scrape
scripts/fb-group-monitor.sh scrape "<GROUP_URL>" --limit 10 --shots-dir ./temp-screenshots
⚠️ Use
pointing to a path within the workspace so the image tool can access screenshots.--shots-dir
Step 2: Analyze feed screenshot + combine with text
If
is present (1 stitched image covering the full feed):feed_screenshot
- Compose a dynamic prompt using the author list from the JSON, so vision focuses on the correct new posts (the feed strip also contains already-seen posts)
- Call image tool with both
andimage
parameters:promptimage tool: image: <feed_screenshot path> prompt: "Facebook group feed. Find and analyze posts by these people (new posts to process): - [Author 1]: "[first few words of text from JSON]" — N images - [Author 2]: "[first few words of text from JSON]" ... For EACH post, do 2 things: 1. EXTRACT: book/product name, author/publisher (read from cover), price (including handwritten prices), condition (new/used/marked/yellowed). 2. INTERPRET: is the deal worth it (price vs market if known), is the item rare/valuable, actual condition assessment from photos." - ⚠️ NEVER call image tool with empty
— default prompt just describes the image generically{} - ⚠️ Feed strip includes old posts — always include author + text snippet so vision targets the right posts
- After getting vision result: match by author, add
from JSONurl - Prioritize image content over truncated
field ("see more" posts)text
If
is absent (screenshot failed):feed_screenshot
- Read directly from
field of each posttext - Summarize available information, note "no screenshot available"
Step 3: Report to user
MUST include the original post link in each item for verification.
Format per new post: 📌 *[Title/Summary]* 👤 Author: [author] 💰 Price: [price or "unknown"] 📝 Condition: [description] 💡 Note: [deal assessment or insight, if any] 🔗 [post URL]
Step 4: If no new posts → stay silent (no notification)
Step 5: If success == false
→ report error briefly
success == false⚠️ Anti-duplicate rule
- Send Telegram only ONCE per run, regardless of whether vision succeeded or failed
- If
tool returns an error → report once and stop, do NOT retrymessage - If vision fails → fallback to text, send once with note "⚠️ Vision unavailable, text only"
Important Notes
- Rate limiting: Recommended cron interval ≥ 2 hours — safe for Facebook
- Session expired: If error "Not logged in" → run
from terminallogin - UI changes: Facebook updates DOM frequently → selectors may need updates
- "See more": Text is truncated — feed strip screenshot usually has complete content
- Feed strip: Scrolls 3× viewport height, crops to feed column, stitches 1 JPEG — reduces vision calls from N to 1
- Screenshot quality: JPEG 82% — sufficient for LLM vision to read text and identify product images
- Vision model: Use a vision-capable model (e.g. Gemini Flash) for the image tool call