feat: Facebook Status Automation

- สร้างระบบ automation สำหรับ Facebook status draft
- Two-pass system: sessions → filter → compare → draft
- Ban list สำหรับกิจกรรมซ้ำทุกวัน
- Compare กับ 10 โพสย้อนหลัง (ไม่โพสซ้ำ)
- Draft style: คนทั่วไปอ่านเข้าใจ ไม่ใช้ technical jargon
- Cron: รันทุกวัน 20:00 น.

Components:
- facebook-status-generator.py (script)
- SKILL.md (Hermes skill)
- README.md (docs)
This commit is contained in:
Kunthawat Greethong
2026-07-02 11:38:48 +07:00
commit db8097f795
5 changed files with 680 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
# Facebook Status Automation
ระบบสร้าง Facebook status draft อัตโนมัติจาก Hermes sessions
## 🎯 วัตถุประสงค์
สร้าง personal brand โดย:
- อัพเดทสิ่งที่ทำให้คนเห็น (แต่ไม่โพสซ้ำ)
- เขียนให้คนที่ไม่รู้เรื่อง IT อ่านเข้าใจ
- โชว์ skill + mindset ผ่านงานจริง
## 📋 Logic
```
Sessions 24h → Filter (ban list) → Compare (10 posts) → Draft
```
### Ban List
กิจกรรมที่ทำซ้ำทุกวัน → ไม่ต้องเอามาโพส:
- `ai-news-reading`
- `morning-news-briefing`
- `daily-planning`
- `start-my-day`
- `end-my-day`
- `cron-model-update`
- `cookie-renewal`
### Comparison Rules
| เงื่อนไข | ผลลัพธ์ |
|---------|---------|
| อยู่ใน ban list | ❌ skip |
| เรื่องเดิม + โพสวันนี้แล้ว | ❌ skip |
| เรื่องเดิม + ไม่มี change ใหม่ | ❌ skip |
| เรื่องเดิม + มี change ใหม่ | ✅ โพส (แก้ wording) |
| เรื่องใหม่ | ✅ โพส |
| ไม่มีเรื่องน่าสนใจ | 🔕 ไม่โพส |
## 📂 ไฟล์
```
facebook-status-automation/
├── facebook-status-generator.py # script หลัก
├── README.md # เอกสารนี้
└── SKILL.md # Hermes skill (TODO)
```
## 🔧 การใช้งาน
### Test Run (Manual)
```bash
cd /Users/kunthawat/Gitea/moreminimore-personal-system/facebook-status-automation
python3 facebook-status-generator.py
```
### Cron Job (Auto)
รันทุกวัน 20:00 น. (8 โมงเย็น)
```bash
hermes cron create \
--name "Facebook Status Draft" \
--schedule "0 20 * * *" \
--script facebook-status-generator.py \
--deliver telegram
```
## 📊 Log File
`~/vault/.facebook-status-log.json`:
```json
{
"settings": {
"lookback_posts": 10,
"ban_list": [...]
},
"posts": [
{
"date": "2026-07-02",
"topics": ["ai-news-automation", "moreminimore-service"],
"draft": "...",
"article_link": null
}
],
"milestones": {
"ai-news-automation": {
"last_posted": "2026-07-02",
"last_change": "2026-06-25"
}
}
}
```
## 🎨 Draft Style
- ไม่มี technical jargon
- เน้นผลลัพธ์/ประโยชน์
- คนทั่วไปอ่านเข้าใจ
- สั้นกระชับ
### ✅ ดี
> วันนี้ปรับระบบ AI ให้สรุปข่าวอัตโนมัติทุกเช้า — ประหยัดเวลา 1 ชม./วัน
### ❌ ไม่ดี
> Today I updated the cron job configuration to use the moreminimore-ai model via custom LLM proxy
## 🔮 TODO
- [ ] สร้าง Hermes skill
- [ ] เชื่อม session_search จริง (ตอนนี้ mock)
- [ ] ใช้ LLM สรุปกิจกรรม (ตอนนี้ keyword matching)
- [ ] ใช้ humanizer skill ปรับ draft
- [ ] เช็ค blog articles + ใส่ link
- [ ] Support multiple languages

View File

@@ -0,0 +1,157 @@
---
name: facebook-status-automation
description: "Generate Facebook personal status drafts from recent Hermes sessions. Two-pass system: extract activities from 24h sessions → compare with last 10 posts → output copyable draft or skip if nothing new."
version: 1.0.0
author: Kunthawat
license: MIT
platforms: [macos, linux]
metadata:
hermes:
tags: [social-media, facebook, personal-brand, automation]
category: productivity
---
# Facebook Status Automation
สร้าง Facebook status draft จาก Hermes sessions ใน 24 ชม. ย้อนหลัง
มุ่งเป้า: **personal brand** สำหรับคนทั่วไปที่ไม่รู้เรื่อง IT
## When to use
- ผู้ใช้ขอให้สร้าง Facebook status จากสิ่งที่ทำวันนี้
- Cron job รันตอน 20:00 ทุกวัน
- ผู้ใช้ถามว่า "วันนี้มีอะไรน่าโพสไหม"
## Core Logic
```
1. session_search(limit=20, sort="newest") → ดึง sessions 24h ย้อนหลัง
2. อ่าน session content → สรุปกิจกรรม
3. Filter: กรอง ban list (กิจกรรมซ้ำทุกวัน)
4. Compare: เปรียบเทียบกับ 10 โพสย้อนหลัง (จาก .facebook-status-log.json)
5. Draft: สร้าง status ถ้ามีเรื่องใหม่ / skip ถ้าไม่มี
```
## Ban List
กิจกรรมที่ทำทุกวัน → ไม่ต้องโพส:
| Topic | เหตุผล |
|-------|--------|
| ai-news-reading / morning-news-briefing | cron รันทุกวัน |
| daily-planning / start-my-day | cron รันทุกวัน |
| end-my-day / evening-wrapup | cron รันทุกวัน |
| cron-model-update | internal config |
| cookie-renewal | internal maintenance |
เพิ่ม/ลบได้ใน `~/vault/.facebook-status-log.json``settings.ban_list`
## Comparison Rules
| เงื่อนไข | ผลลัพธ์ |
|---------|---------|
| อยู่ใน ban list | ❌ skip |
| เรื่องเดิม + โพสวันนี้แล้ว | ❌ skip |
| เรื่องเดิม + ไม่มี change ใหม่ (lookback_posts) | ❌ skip |
| เรื่องเดิม + มี change ใหม่ | ✅ โพส (ปรับ wording) |
| เรื่องใหม่ | ✅ โพส |
| ไม่มีเรื่องน่าสนใจ | 🔕 ไม่โพส → แจ้ง "วันนี้ไม่มีเรื่องน่าโพส" |
## Steps
### 1. ดึง Sessions
```
session_search(limit=20, sort="newest")
```
กรองเฉพาะ sessions ใน 24 ชม. ย้อนหลัง (ไม่ใช่ทุก session)
### 2. อ่าน + สรุปกิจกรรม
อ่าน content ของแต่ละ session → สรุปว่า:
- ทำอะไรไปบ้าง
- มี progress/achievement อะไรบ้าง
- มี blog article ไหม (ถ้ามี เก็บ link)
### 3. Filter Ban List
เปรียบเทียบ topic กับ ban_list ใน log file
ถ้า match → skip
### 4. Compare กับ 10 โพสย้อนหลัง
อ่าน `~/vault/.facebook-status-log.json`
- ดึง posts 10 ตัวล่าสุด
- เช็คว่า topic นี้เคยโพสหรือยัง
- ถ้าเคย → เช็คว่ามี change ใหม่ไหม
### 5. สร้าง Draft (ถ้าผ่าน)
เขียน Facebook status:
- ไม่ใช้ technical jargon
- เน้นผลลัพธ์/ประโยชน์สำหรับคนทั่วไป
- สั้น กระชับ
- ใส่ blog link ถ้ามี
### 6. อัพเดท Log
บันทึกลง `~/vault/.facebook-status-log.json`:
- เพิ่ม post entry ใหม่
- อัพเดท milestones
### 7. Output
ถ้ามี draft → แสดงให้ user copy
ถ้าไม่มี → แจ้ง "วันนี้ไม่มีเรื่องน่าโพส"
## Draft Style Guide
### ✅ เขียนแบบนี้
```
วันนี้ปรับระบบ AI ให้สรุปข่าวอัตโนมัติทุกเช้า — เขียน script ให้ทำงานเองตอน 7 โมง ไม่ต้องนั่งเปิดทีละเว็บ
```
### ❌ ไม่เขียนแบบนี้
```
Today I updated the cron job configuration to use the moreminimore-ai model
via custom LLM proxy endpoint for all scheduled tasks
```
### Rules
- เขียนเป็นไทย (หรือภาษาที่ user ต้องการ)
- ไม่ใช้คำ technical (cron, API, script → ใช้คำที่คนทั่วไปเข้าใจ)
- เน้น **สิ่งที่ได้** ไม่ใช่ **สิ่งที่ทำ** ("ประหยัดเวลา" ดีกว่า "ปรับ config")
- ไม่ต้องใส่ timestamp หรือเวลาที่ทำ
- ถ้ามี blog article → ใส่ link ท้ายโพส
## Files
| ไฟล์ | ที่อยู่ | หน้าที่ |
|-----|--------|--------|
| Log file | `~/vault/.facebook-status-log.json` | เก็บประวัติ + milestones |
| Script | `~/Gitea/moreminimore-personal-system/facebook-status-automation/facebook-status-generator.py` | Test run / debug |
| Skill | `~/.hermes/skills/productivity/facebook-status-automation/SKILL.md` | ไฟล์นี้ |
## Cron Setup
```bash
# รันทุกวัน 20:00 น.
hermes cron create \
--name "Facebook Status Draft" \
--schedule "0 20 * * *" \
--prompt "รัน facebook-status-automation skill" \
--skills facebook-status-automation \
--deliver telegram
```
## Pitfalls
1. **sessions 24h ≠ sessions ทั้งหมด** — ต้อง filter เวลาจริง ไม่ใช่ดึงทุก session
2. **ban list ต้องตรง topic ไม่ใช่ substring** — เช่น "morning-news-briefing" ต้องเช็คว่า topic match เต็ม ไม่ใช่แค่มี "morning" อยู่
3. **draft ต้อง human-readable** — ห้ามมี technical terms หลุดไป
4. **log file ต้อง update ทุกครั้งที่โพส** — ไม่งั้นจะโพสซ้ำ
5. **ถ้าไม่มีเรื่องน่าโพส → ไม่ต้องโพส** — ห้าม forced output

View File

@@ -0,0 +1,238 @@
#!/usr/bin/env python3
"""
Facebook Status Automation
สร้าง Facebook status draft จาก Hermes sessions ใน 24 ชม. ย้อนหลัง
"""
import json
import sys
from datetime import datetime, timezone, timedelta
from pathlib import Path
# Hermes tools available in cron context
from hermes_tools import terminal
def load_log(log_path):
"""โหลดไฟล์ log"""
result = terminal(f"cat {log_path}")
return json.loads(result["output"])
def save_log(log_path, data):
"""บันทึกไฟล์ log"""
content = json.dumps(data, indent=2, ensure_ascii=False)
with open(log_path, 'w', encoding='utf-8') as f:
f.write(content)
def get_recent_sessions():
"""ดึง sessions ใน 24 ชม. ย้อนหลัง (mock — จริง ๆ ต้อง call session_search)"""
# ใน production: from hermes_tools import session_search
# results = session_search(limit=20, sort="newest")
# Mock data สำหรับ test
return [
{"session_id": "20260702_105243_1a22ad", "title": "ปรับ cron ให้ใช้ moreminimore AI", "source": "tui"},
{"session_id": "20260626_101627_b0c64f", "title": "วางแผน moreminimore-service", "source": "tui"},
{"session_id": "cron_93fb9da1b231_20260702_090030", "title": "Morning News Briefing", "source": "cron"},
{"session_id": "cron_437e59dedd0e_20260702_070016", "title": "orbites-start-my-day", "source": "cron"},
]
def extract_activities(sessions, ban_list):
"""
สกัดกิจกรรมจาก sessions + กรองตาม ban list
ใน production ต้อง:
1. อ่าน session content จริง (session_search + scroll)
2. ใช้ LLM สรุปว่าทำอะไรไปบ้าง
3. กรอง ban list
ตอนนี้ mock ไว้ก่อน
"""
activities = []
for s in sessions:
title = s["title"].lower()
# Simple keyword matching (ใน production ใช้ LLM)
if "cron" in title and "model" in title:
activities.append({
"topic": "cron-model-update",
"description": "ปรับ cron ให้ใช้ moreminimore AI model",
"session": s["title"]
})
elif "moreminimore-service" in title:
activities.append({
"topic": "moreminimore-service",
"description": "วางแผน moreminimore-service",
"session": s["title"]
})
elif "morning news" in title or "briefing" in title:
activities.append({
"topic": "morning-news-briefing",
"description": "Morning News Briefing รัน",
"session": s["title"]
})
elif "start-my-day" in title:
activities.append({
"topic": "start-my-day",
"description": "orbites-start-my-day รัน",
"session": s["title"]
})
# กรองตาม ban list
kept = []
skipped = []
for a in activities:
if any(ban in a["topic"] for ban in ban_list):
skipped.append({**a, "reason": "อยู่ใน ban list"})
else:
kept.append(a)
return kept, skipped
def compare_with_history(candidates, log_data, today):
"""เปรียบเทียบกับ 10 โพสย้อนหลัง"""
posts = log_data["posts"]
lookback_posts = posts[-log_data["settings"]["lookback_posts"]:]
milestones = log_data["milestones"]
final_keep = []
final_skip = []
for candidate in candidates:
topic = candidate["topic"]
# หาว่าเคยโพสเรื่องนี้ไหม
posted_before = False
last_posted_date = None
for post in lookback_posts:
if topic in post["topics"]:
posted_before = True
last_posted_date = post["date"]
break
if not posted_before:
# ไม่เคยโพส → โพสได้
final_keep.append({**candidate, "reason": "🆕 เรื่องใหม่"})
else:
# เคยโพสแล้ว
if last_posted_date == today:
# โพสวันนี้แล้ว → SKIP
final_skip.append({**candidate, "reason": f"❌ เคยโพสวันนี้แล้ว"})
else:
# โพสวันอื่น → ดูว่ามี change ใหม่ไหม
milestone = milestones.get(topic, {})
last_change = milestone.get("last_change", "")
if last_change == today:
# มี change วันนี้ → โพสได้
final_keep.append({**candidate, "reason": f"🔄 มี change ใหม่"})
else:
# ไม่มี change → SKIP
final_skip.append({**candidate, "reason": f"❌ ไม่มี change ใหม่ (last: {last_change})"})
return final_keep, final_skip
def create_draft(candidates):
"""สร้าง Facebook status draft"""
if not candidates:
return None
# Simple template (ใน production ใช้ LLM + humanizer)
lines = []
for c in candidates:
lines.append(c["description"])
draft = "\n\n".join(lines)
return draft
def update_log(log_data, today, draft, topics):
"""อัพเดท log file"""
# เพิ่ม post ใหม่
log_data["posts"].append({
"date": today,
"topics": topics,
"draft": draft,
"article_link": None
})
# อัพเดท milestones
for topic in topics:
log_data["milestones"][topic] = {
"last_posted": today,
"last_change": today
}
return log_data
def main():
log_path = Path.home() / "vault" / ".facebook-status-log.json"
today = datetime.now(timezone.utc).strftime("%Y-%m-%d")
print("=" * 60)
print("📋 Facebook Status Automation")
print("=" * 60)
print(f"Date: {today}")
print()
# 1. โหลด log
log_data = load_log(log_path)
ban_list = log_data["settings"]["ban_list"]
# 2. ดึง sessions
print("🔎 Fetching sessions (24h)...")
sessions = get_recent_sessions()
print(f" Found: {len(sessions)} sessions")
# 3. สกัดกิจกรรม + กรอง ban list
print("\n🚫 Filtering activities...")
kept, skipped = extract_activities(sessions, ban_list)
print(f" Kept: {len(kept)}, Skipped: {len(skipped)}")
if not kept:
print("\n🔕 No activities after ban filter")
print("=" * 60)
return
# 4. เปรียบเทียบกับ history
print("\n🔍 Comparing with history...")
final_keep, final_skip = compare_with_history(kept, log_data, today)
print(f" Can post: {len(final_keep)}")
if not final_keep:
print("\n🔕 วันนี้ไม่มีเรื่องใหม่น่าโพส")
print("\nเหตุผล:")
for item in final_skip:
print(f"{item['description']}: {item['reason']}")
print("=" * 60)
return
# 5. สร้าง draft
print("\n📝 Generating draft...")
draft = create_draft(final_keep)
topics = [c["topic"] for c in final_keep]
# 6. อัพเดท log
log_data = update_log(log_data, today, draft, topics)
save_log(log_path, log_data)
print(" ✅ Log updated")
# 7. แสดง draft
print("\n" + "=" * 60)
print("📝 DRAFT สำหรับ copy:")
print("=" * 60)
print(draft)
print("=" * 60)
if __name__ == "__main__":
main()