← Về thư mục
📄 / / root / .hermes / skills / operate / tg-topic-ops / SKILL.md

name: tg-topic-ops description: Manage Telegram forum topics (rename, swap, reicon, close) for the company's NV-Office group. Use when the user reports incorrect topic names, wants to restructure departments, or fix icon mismatches.


Skill: tg-topic-ops — Telegram Topic Operations

Replacement / reorganisation of existing Telegram forum topics. Not for initial creation (see setup-departments).

Tools

All commands use python3 /opt/ai-os/core/lib/tg_topics.py:

Action Command
Rename topic tg_topics.py edit "<chat_id>" <thread_id> --name "Tên Mới"
Set emoji icon tg_topics.py edit "<chat_id>" <thread_id> --icon <custom_emoji_id>
Look up icon ID tg_topics.py icons --find 🔬
Create topic(s) tg_topics.py create "<chat_id>" "Tên 1" "Tên 2" or --json
Get chat info tg_topics.py chatinfo "<chat_id>"
Verify bot tg_topics.py whoami

Chat ID for NV-Office: -1003707758328

CRITICAL PITFALL — Thread identity ≠ topic name ⚠️

Topic names are metadata. Topic content is ground truth.

A topic that says "R&D" on the label may contain Marketing messages, and a topic named "STR & MKT" may contain Policy Lab content. This happens when topics are renamed without considering which thread's message history belongs to which department.

NEVER assume the mapping from topic name to department role based on: - The current topic name alone - Which topic appears first / last in the list - The icon currently displayed

Always verify content by checking: - Screenshots the user provides (identify actual message content) - Recent messages in the topic (not just title) - The user's explicit correction if they report a mismatch

Correct approach when user reports "topic X has wrong content"

  1. Determine which thread_id has which content — ask the user, or read from their attached screenshot.
  2. Rename topics to match the content, not the name.
  3. Update the MAPPING dict in handoff.py (at /opt/ai-os/core/plugin/ai-os/handoff.py) — every alias must point to the correct thread_id.

Safe swap procedure (swap two topics' names)

# 1. Rename first topic to a TEMP name (frees the original name)
tg_topics.py edit "<chat_id>" <thread_A> --name "TEMP"

# 2. Rename second topic to what first topic should be
tg_topics.py edit "<chat_id>" <thread_B> --name "DESIRED_A"

# 3. Rename TEMP to what second topic should be
tg_topics.py edit "<chat_id>" <thread_A> --name "DESIRED_B"

Then update handoff.py MAPPING so all aliases point to the correct thread_id for their content.

Preference: rename over create

Before creating a new topic, check whether one with the same name or role already exists. Creating duplicate-named topics is confusing for the user. The bot cannot delete topics — only Telegram app users can (long-press → Delete topic). If you accidentally create a duplicate, rename it to something obvious (like ❌ (xoa)) so the user can identify and delete it.

Handoff.py & departments.json MAPPING

After any rename or swap, update BOTH files:

  1. /opt/ai-os/core/plugin/ai-os/handoff.py — alias → profile name mapping
# Template:
"<alias>": "<profile-name>"  # e.g. "sm": "bd-mkt", "marketing": "bd-mkt"
  1. /opt/ai-os/products/ceo/config/departments.json — profile name → thread_id mapping with display name, prefix, and aliases. This is the centralized config; handoff.py reads it via load_departments().
{
  "aliases": { "sm": "bd-mkt", "mk": "bd-mkt", ... },
  "departments": {
    "bd-mkt": {
      "name": "BD & MKT",
      "thread_id": 14,
      "prefix": "BD"
    }
  }
}

Every alias must point to the correct profile name. Keep forward-compatibility: old aliases (e.g. "sm", "str-mkt", "marketing") should still route after rename.

Batch rename with thread_id suffix

When renaming all threads to include IDs for discoverability (user wants "Name - id:XX" format):

python3 -c "
import sys; sys.path.append('/opt/ai-os/core/lib')
import tg_topics, json
chat_id = '-1003707758328'
token = tg_topics.load_token()
targets = [(18, 'IT & AI - id:18'), (12, 'R&D - id:12'), (14, 'BD & MKT - id:14'), ...]
results = []
for tid, new_name in targets:
    ok, res = tg_topics.api(token, 'editForumTopic', {'chat_id': chat_id, 'message_thread_id': tid, 'name': new_name})
    results.append({'thread_id': tid, 'ok': ok})
print(json.dumps(results, indent=2, ensure_ascii=False))
"

Then update departments.json and handoff.py to match. The script lives at /opt/ai-os/core/lib/tg_topics.py.

Nhi's preferences (user)