#!/usr/bin/env python3 """customize_icons.py — GỢI Ý + ÁP DỤNG icon cho các phòng ban (forum topics). Minh hoạ AI 3 vai trong 1 vòng: gợi ý (suggest) → user DUYỆT → thực thi (apply via editForumTopic). KHÔNG bắt model tự base64/tự mò — agent chỉ chạy 2 lệnh. python3 lib/customize_icons.py suggest -> đọc cơ cấu phòng (registry departments_setup: tên→thread) + 112 icon khả dụng, map mỗi phòng → icon hợp nghĩa (keyword). In JSON gợi ý. KHÔNG áp dụng. python3 lib/customize_icons.py apply --json '[{"thread_id":N,"custom_emoji_id":"...","name":"..?"}]' -> editForumTopic đổi icon (+ tên) theo bộ ĐÃ DUYỆT. """ import os import sys import json sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) import tg_topics # api, load_token import identity # resolve_user, load_index import setup_departments # resolve_chat_id # Ưu tiên icon theo nghĩa phòng ban — CHỈ dùng emoji CÓ THẬT trong bộ 112 icon của Telegram. PREF = [ (("điều hành", "quản trị", "vận hành", "operation", "admin", "ban giám", "general"), ["💼", "🏛", "🔝", "🧮"]), (("sales", "bán hàng", "kinh doanh", "cskh", "khách", "customer", "doanh thu", "bán"), ["💰", "📈", "🛒", "🛍"]), (("marketing", "truyền thông", "tăng trưởng", "growth", "brand", "thương hiệu", "quảng"), ["📣", "🔥", "📈", "🎤"]), (("nhân sự", "hr", "văn hóa", "con người", "people", "tuyển"), ["👨‍👩‍👧‍👦", "🪪", "👀"]), (("thông tin", "tri thức", "tài liệu", "dữ liệu", "data", "knowledge", "kiến thức", "info", "báo cáo"), ["📚", "🧠", "📁", "📝"]), (("tài chính", "kế toán", "finance", "ngân"), ["🧮", "💸", "🪙", "💱"]), (("kỹ thuật", "công nghệ", "sản phẩm", "product", "tech", "dev", "lab", "r&d", "nghiên cứu", "kỹ "), ["💻", "🤖", "🔬", "🧪"]), (("nội dung", "content", "thiết kế", "design", "sáng tạo"), ["🎨", "✍️", "🎬"]), (("họp", "meeting", "sự kiện", "event", "lịch"), ["📆", "🎉", "🎤"]), ] DEFAULT = ["📁", "⭐️", "📝"] def _norm(e): return (e or "").replace("️", "").strip() def _icon_map(token): ok, res = tg_topics.api(token, "getForumTopicIconStickers") if not ok or not isinstance(res, list): return {} m = {} for s in res: m.setdefault(_norm(s.get("emoji")), s.get("custom_emoji_id")) return m def _pick(name, im): low = (name or "").lower() for keys, emojis in PREF: if any(k in low for k in keys): for e in emojis: if _norm(e) in im: return _norm(e), im[_norm(e)] for e in DEFAULT: if _norm(e) in im: return _norm(e), im[_norm(e)] if im: k = next(iter(im)) return k, im[k] return None, None def main(): cmd = sys.argv[1] if len(sys.argv) > 1 else "suggest" token = tg_topics.load_token() user_id = identity.resolve_user() if cmd == "suggest": mp = {} if user_id: rec = identity.load_index().get("users", {}).get(user_id, {}) try: mp = json.loads(rec.get("departments_setup", "{}") or "{}") except Exception: mp = {} if not mp: print(json.dumps({"ok": False, "error": "Chưa có sơ đồ phòng ban — dựng phòng ban trước đã."}, ensure_ascii=False)) return 1 im = _icon_map(token) out = [] for name, tid in mp.items(): emo, eid = _pick(name, im) out.append({"dept": name, "thread_id": tid, "emoji": emo, "custom_emoji_id": eid}) print(json.dumps({"ok": True, "suggestions": out}, ensure_ascii=False, indent=2)) return 0 if cmd == "apply": if "--json" not in sys.argv: print(json.dumps({"ok": False, "error": "thiếu --json"}, ensure_ascii=False)) return 2 try: items = json.loads(sys.argv[sys.argv.index("--json") + 1]) except Exception as e: print(json.dumps({"ok": False, "error": "JSON lỗi: %s" % e}, ensure_ascii=False)) return 2 chat_id, _ = setup_departments.resolve_chat_id() if not chat_id: print(json.dumps({"ok": False, "error": "Không lấy được nhóm — @nhắc em trong nhóm."}, ensure_ascii=False)) return 1 results = [] for it in items: p = {"chat_id": chat_id, "message_thread_id": it.get("thread_id")} if it.get("custom_emoji_id"): p["icon_custom_emoji_id"] = it["custom_emoji_id"] if it.get("name"): p["name"] = setup_departments.clean_name(it["name"])[:128] ok, res = tg_topics.api(token, "editForumTopic", p) # TOPIC_NOT_MODIFIED = icon/tên đã giống sẵn → coi như thành công. if not ok and "NOT_MODIFIED" in str(res): ok = True res = "đã giống sẵn" results.append({"thread_id": it.get("thread_id"), "ok": ok, "error": None if ok else res}) print(json.dumps({"ok": all(r["ok"] for r in results), "results": results}, ensure_ascii=False, indent=2)) return 0 if all(r["ok"] for r in results) else 1 print(json.dumps({"ok": False, "error": "lệnh không rõ: %s" % cmd}, ensure_ascii=False)) return 1 if __name__ == "__main__": sys.exit(main())