- bin/chats/: env-based paths, no /mnt/ /home/ hardcodes - bin/edelweiss-pilot: remove curasoft, use DOCS_BASE env var - bin/facts/crm: use KNOWLEDGE_MESH_SEED env var - compose.edelweiss.yml: remove curasoft volumes, use DOCS_BASE - docs/chat-import-plan.md: link to Gitea issue, no secrets - bin/seed-edelweiss-facts.py: removed (curasoft-only)
49 KiB
Chat Import Pipeline
<<<<<<< Updated upstream Plan and implementation details: eSlider/brain-chats-import#1
Progress tracked in that issue. This file kept as a local reference for agent sessions.
Key env vars (set in shell, never committed)
TELEGRAM_MCP_DIR telegram-mcp directory TELEGRAM_API_ID from telegram.env (not committed) TELEGRAM_API_HASH from telegram.env (not committed) TELEGRAM_PHONE from telegram.env (not committed) TELEGRAM_SESSION_STRING from telegram-mcp/.env (not committed) ONLYOFFICE_URL from .env (not committed) ONLYOFFICE_USER from .env (not committed) ONLYOFFICE_PASS from .env (not committed) OO_CLI path to oo binary (default: $HOME/go/bin/oo)
Quick reference
<<<<<<< HEAD ./bin/chat sync telegram --limit 100 ./bin/chat import ./bin/chat index # delegates to bin/kb/index ./bin/chat facts ./bin/chat apply --dry-run ||||||| parent of 313599b (bin/chats: Phase 1 MVP — Telegram sync/import/index/facts/apply)
1. Находки / Discoveries
Доступные платформы и данные
| Platform | Status | Credentials | Go Library |
|---|---|---|---|
| Telegram | ✅ Active MCP server, session string exists | API ID: 30382285, API Hash: fd8a8c1e987bb908b457f374b721c062, Session string in /mnt/8TB/projects/eslider/mcp-servers/telegram.env and /mnt/8TB/projects/eslider/mcp-servers/telegram-mcp/.env. Phone: +34643861471 |
iyear/tdl (7.5k★, Go, gotd/td, экспорт в JSON) |
✅ MCP server exists + Go bridge. No messages.db yet (empty). Needs QR re-auth + sync first |
MCP: /mnt/8TB/projects/eslider/mcp-servers/whatsapp-mcp/. Go bridge uses tulir/whatsmeow |
tulir/whatsmeow (7k★, Go, multi-device API) |
|
✅ Connected via mcp-server-linkedin. Full browser profile + cookies |
Browser profile: ~/.linkedin-mcp/profile/. Active cookies: ~/.linkedin-mcp/storage-state.json. Cookie backup: ~/.linkedin-mcp/cookies.json.bak-agent. Script cookies: /mnt/8TB/projects/eslider/cv/bin/creds/linkedin.cookies.json. JobHunt session: /mnt/8TB/projects/eslider/JobHunt/sessions/linkedin.json. Env: /mnt/8TB/projects/eslider/cv/.env (LINKEDIN_AUTH_TOKEN). |
swiftlysingh/lnk (Go CLI, Voyager API) |
|
| Gmail | ✅ Already working pipeline (bin/mail/sync.go + bin/mail/import) |
OAuth at ~/.gmail-mcp/ |
Already in 2dph |
| Twitter/X.com | ⚠️ Password only, no MCP, no session. Not needed now. | /mnt/8TB/projects/eslider/scratches/Accounts/twitter-pass.txt |
benoitpetit/xsh (Go CLI, cookie auth) |
| Google Calendar | ❌ Not connected yet. Gmail OAuth could extend | None | Нужен Google Calendar API |
Telegram session (проверен, активен)
- API credentials in:
/mnt/8TB/projects/eslider/mcp-servers/telegram.envTELEGRAM_API_ID=30382285TELEGRAM_API_HASH=fd8a8c1e987bb908b457f374b721c062TELEGRAM_PHONE=+34643861471TELEGRAM_SESSION_STRING— длинная строка, active session
- MCP server launcher:
/mnt/8TB/projects/eslider/mcp-servers/run-telegram-mcp.sh - Session generator:
/mnt/8TB/projects/eslider/mcp-servers/telegram-mcp/session_string_generator.py - Regenerator:
/mnt/8TB/projects/eslider/mcp-servers/regen-telegram-session.py
LinkedIn authentication (работает)
- Запускается через Cursor MCP:
uvx mcp-server-linkedin@latest --user-data-dir /home/ano/.linkedin-mcp/profile --no-auto-import - Cookie файлы:
~/.linkedin-mcp/storage-state.json— Playwright storage state (активные cookies)~/.linkedin-mcp/cookies.json.bak-agent— резерв~/.linkedin-mcp/cookies.json.bak-webtop-20260728T143535Z— резерв/mnt/8TB/projects/eslider/cv/bin/creds/linkedin.cookies.json— для скриптов/mnt/8TB/projects/eslider/JobHunt/sessions/linkedin.json— JobHunt
li_attoken:AQEDASsyC9gF8hS2AAABnC2A_vIAAAGcdZZfTk4Ahfp9wURXwTpCAAtRIw_htVldds5UN9JDr6L_hr3lN5CcPxnKDvy-CxQo0apf7K4pmftQzQYHdqpKNNzlNakcvEcOOalpqRxPhlTfIt8jxqevkZcr- Для Go подхода: можно читать cookie из
storage-state.jsonи использовать LinkedIn Voyager API напрямую
WhatsApp bridge (не синхронизирован)
- Go bridge at:
/mnt/8TB/projects/eslider/mcp-servers/whatsapp-mcp/whatsapp-bridge/ - Использует
tulir/whatsmeowGo library (уже вgo.mod) - SQLite store:
whatsapp-bridge/store/messages.db— не существует (0 байт), нужна первая авторизация по QR - Launcher:
/mnt/8TB/projects/eslider/mcp-servers/run-whatsapp-bridge-lharries.sh - QR images готовились:
/mnt/8TB/projects/produktor/work/data/export/whatsapp-qr.png - Пароль:
Oomtr78k39(из.envOnlyOffice, он же для многих сервисов)
OnlyOffice доступ
.envв корне 2dph:ONLYOFFICE_URL=https://office.produktor.io,ONLYOFFICE_USER=eslider@gmail.com,ONLYOFFICE_PASS=Oomtr78k39ooCLI установлен:/home/ano/go/bin/oo(go-onlyoffice)- go-onlyoffice repo:
/mnt/8TB/projects/eslider/go-onlyoffice/(main, public) - oo-workspace (каталог, private):
/mnt/8TB/projects/eslider/oo-workspace/
Gitea
- Instance:
https://git.produktor.io(черезgitea-apiwrapper) - Credentials:
~/.config/gitea/produktor.env - User:
eSlider, admin - Repos: 30+ приватных репозиториев
eSlider/2dphне существует на Gitea — проект только на GitHub- Для задачи: создать issue в существующем репо (например
eSlider/JobHunt) или создать новый репо
Rambox
Не используется. IndexedDB база не существует.
||||||| Stash base
Created: 2026-08-12
Author: Andriy Oblivantsev
Purpose: One-shot handoff for a new agent session to implement bin/chats
Plan and implementation details: eSlider/brain-chats-import#1
Stashed changes
Progress tracked in that issue. This file kept as a local reference for agent sessions.
<<<<<<< Updated upstream
2. Design Decisions
One binary: bin/chats
// Source interface — каждая платформа реализует
type Source interface {
Name() string // "telegram", "whatsapp", "linkedin"
Sync(ctx context.Context, out string) error
}
// CLI subcommands
chats sync telegram [--limit N] [--since DATE]
chats sync whatsapp [--qr] [--limit N]
chats sync linkedin [--limit N]
chats import // JSONL → markdown (all sources)
chats index // rebuild var/kb.lbug
chats facts // extract + cross-check
chats apply // push to OO CRM [--dry-run]
Directory layout (полные имена платформ)
var/chats/
telegram/<chat_id>/messages.jsonl
whatsapp/<jid>/messages.jsonl
linkedin/<conversation_id>/messages.jsonl
md/<source>/<chat_name>/message.md
JSONL format (одна строка = одно сообщение)
{"id":"123","ts":"2026-01-15T10:30:00Z","from":"me","text":"Hello!","media":null,"platform":"telegram"}
MD format (YAML frontmatter)
---
id: tg_12345
platform: telegram
chat_id: "-100123456"
chat_name: "John Doe"
participants: ["me", "John Doe"]
message_count: 1500
type: personal
---
# Чат с John Doe
**2026-01-15 10:30** — me: Hello!
Фильтр "личный чат"
- ≤3 участников
- Боты не считаются (Telegram:
user.is_bot == false) - Не канал, не публичная группа
- Telegram:
dialog.Type == "user"или супергруппа сparticipants_count <= 3(исключая ботов) - WhatsApp:
@s.whatsapp.net(не@g.us) - LinkedIn: 1:1 conversation
Очередность реализации
- Telegram — самый простой (session string + API ID/Hash активны)
- Import — конвертер JSONL → MD
- Index — интеграция с brain
- WhatsApp — после первого QR
- Facts — извлечение контактных данных
- LinkedIn — после проверки cookie
- Apply — запись в OO CRM
Тестирование (TDD, system tests only)
- Никаких unit-тестов, никаких моков
- Тесты используют реальные данные (слепки)
- Workflow use-case как тест:
- Написать тест с реальным сценарием (sync → import → index → search)
- Проверить что файлы созданы
- Проверить что поиск возвращает ожидаемые результаты
- A/B тест: сравнить два последовательных sync на идентичность
- Integration: тест через
ooCLI с--dry-run
Cross-check (detective method)
Перед записью в OO CRM — минимум 2 независимых источника:
- S1: Чат (текст сообщения, автор, дата)
- S2: OO CRM (существующий контакт/компания/deal) через
oo persons list/oo persons get - S3 (опционально): Corpus SoT (
knowledge-mesh-seed.yaml) или web-search - Факты с ≥2 источниками →
root=factsв brain +approve=trueдля CRM - Факты с 1 источником → предложение на review (catalog-паттерн)
Apply в OO CRM
Через oo CLI:
oo persons update <id> --about ... --job-title ...oo contacts info-add <id> --type Phone|LinkedIn --value ...oo opportunities create --contact-id ... --title ... --stage ...oo persons update <id> --company-id ...(ассоциация)oo projects contacts <project-id>(связь с проектом)
3. Implementation Plan
Phase 1: Telegram sync + import (MVP)
- Create
bin/chats/directory structure (nested Go module likebin/kbsearch/) - Implement
Sourceinterface - Implement
TelegramSourceusinggotd/td(import fromiyear/tdlor direct) - Write JSONL output to
var/chats/telegram/<id>/messages.jsonl - Implement
chats import— reads all JSONL, writes MD - Write system test: real sync → import → verify output
Phase 2: Brain indexing
- Implement
chats index— rebuildvar/kb.lbugwith corpus + chats - Write system test: sync → import → index →
bin/kb/search "query"→ verify recall
Phase 3: WhatsApp
- Implement
WhatsAppSourceusingtulir/whatsmeow - First run requires QR auth (save session for later reuse)
- Write sync output to
var/chats/whatsapp/<jid>/messages.jsonl
Phase 4: Facts extraction + cross-check
- Implement
chats facts:- Phone regex:
\+?\d{7,15} - LinkedIn URL regex:
linkedin\.com/in/[\w-]+ - Cross-check: match extracted values against OO CRM API
- Phone regex:
- Write facts to brain as
root=facts
Phase 5: LinkedIn + Apply
- Implement
LinkedInSourceusing Voyager API + cookies fromstorage-state.json - Implement
chats apply:- Build YAML catalog (as
oo-workspacedoes) - Run
oo catalog match→ review →oo catalog apply
- Build YAML catalog (as
4. Existing code references
| Code | Path | Purpose |
|---|---|---|
| Mail sync | bin/mail/sync.go + bin/mail/sync/ |
Pattern for chat sync (Go subprocess pattern) |
| Mail import | bin/mail/import |
Pattern for JSONL → MD conversion |
| Mail index | bin/mail/index_mail |
Pattern for brain rebuild with new corpus |
| kbsearch | bin/kbsearch/ |
Go module pattern (nested, system_ladybug tag) |
| kb/index | bin/kb/index |
Python brain index (upsert_leaf, init_schema) |
| kblib | bin/tools/kblib.py |
Python brain core (connect, upsert_leaf, hybrid_search) |
| facts/crm | bin/facts/crm |
Cross-check CRM facts pattern |
| facts/extract | bin/facts/extract |
2-source fact extraction pattern |
| oo-workspace catalog | /mnt/8TB/projects/eslider/oo-workspace/catalog/ |
Catalog scan/match/apply pattern (VCF, Thunderbird, projects) |
| WhatsApp bridge | /mnt/8TB/projects/eslider/mcp-servers/whatsapp-mcp/whatsapp-bridge/ |
Existing whatsmeow Go bridge |
| go-onlyoffice | /mnt/8TB/projects/eslider/go-onlyoffice/ |
OO CRM API library |
| oo CLI | /home/ano/go/bin/oo |
Built go-onlyoffice CLI |
5. Critical files
| File | Content |
|---|---|
~/.config/gitea/produktor.env |
Gitea URL + token |
/mnt/8TB/projects/eslider/mcp-servers/telegram.env |
Telegram API ID/Hash + phone + session |
/mnt/8TB/projects/eslider/mcp-servers/telegram-mcp/.env |
Telegram session string |
/mnt/8TB/projects/ai/2dph/.env |
ONLYOFFICE URL/USER/PASS |
/mnt/8TB/projects/eslider/cv/.env |
LinkedIn auth token |
~/.linkedin-mcp/storage-state.json |
LinkedIn active cookies |
/mnt/8TB/projects/eslider/go-onlyoffice/.env |
OO creds for oo CLI |
/mnt/8TB/projects/eslider/go-onlyoffice/go.mod |
Deps for go-onlyoffice |
/mnt/8TB/projects/eslider/oo-workspace/go.mod |
Deps for oo-workspace |
6. Agent prompt (для запуска новой сессии)
Скопируйте этот промпт при старте новой сессии:
Ты — ассистент для разработки chat import pipeline в проекте 2dph (eSlider/2dph).
Прочитай docs/chat-import-plan.md полностью. Это план, находки и дизайн.
Задача: реализовать bin/chats — единый Go бинарник для sync/import/index/facts/apply
личных чатов из Telegram, WhatsApp, LinkedIn с последующей записью фактов в OnlyOffice CRM.
Правила:
1. TDD first — workflow use-case как тест. Реальные данные, без моков.
2. Go, всё в один бинарник bin/chats.
3. Source interface — каждая платформа плагином.
4. var/chats/telegram/ — полные имена платформ.
5. Начни с Telegram (session string активна).
6. После реализации — создай/обнови тесты.
7. Сохрани прогресс в docs/chat-import-plan.md.
8. Запроси разрешение перед apply в OO CRM.
Ключевые пути:
- /mnt/8TB/projects/ai/2dph/ — корень проекта
- /mnt/8TB/projects/eslider/mcp-servers/telegram-mcp/ — Telegram MCP
- /mnt/8TB/projects/eslider/mcp-servers/telegram.env — API ID/Hash + session
- /mnt/8TB/projects/eslider/go-onlyoffice/ — go-onlyoffice библиотека
- /home/ano/go/bin/oo — OO CLI
Готов начать.
=======
1. Находки / Discoveries
Доступные платформы и данные
| Platform | Status | Credentials (path, not values) | Go Library |
|---|---|---|---|
| Telegram | ✅ Active MCP server, session string exists | API creds in telegram.env (see §5). Session string in telegram-mcp/.env. |
MCP JSON-RPC (через telegram-mcp server) |
✅ MCP server exists + Go bridge. No messages.db yet (empty). Needs QR re-auth + sync first |
MCP: /mnt/8TB/projects/eslider/mcp-servers/whatsapp-mcp/. Go bridge uses tulir/whatsmeow |
tulir/whatsmeow (7k★, Go, multi-device API) |
|
✅ Connected via mcp-server-linkedin. Full browser profile + cookies |
Browser profile: ~/.linkedin-mcp/profile/. Active cookies: ~/.linkedin-mcp/storage-state.json. Cookie backup: ~/.linkedin-mcp/cookies.json.bak-agent. Script cookies: /mnt/8TB/projects/eslider/cv/bin/creds/linkedin.cookies.json. JobHunt session: /mnt/8TB/projects/eslider/JobHunt/sessions/linkedin.json. Env: /mnt/8TB/projects/eslider/cv/.env (LINKEDIN_AUTH_TOKEN). |
swiftlysingh/lnk (Go CLI, Voyager API) |
|
| Gmail | ✅ Already working pipeline (bin/mail/sync.go + bin/mail/import) |
OAuth at ~/.gmail-mcp/ |
Already in 2dph |
| Twitter/X.com | ⚠️ Password only, no MCP, no session. Not needed now. | /mnt/8TB/projects/eslider/scratches/Accounts/twitter-pass.txt |
benoitpetit/xsh (Go CLI, cookie auth) |
| Google Calendar | ❌ Not connected yet. Gmail OAuth could extend | None | Нужен Google Calendar API |
Telegram session (проверен, активен)
- API credentials in:
/mnt/8TB/projects/eslider/mcp-servers/telegram.envTELEGRAM_API_ID,TELEGRAM_API_HASH,TELEGRAM_PHONE— загружаются из envTELEGRAM_SESSION_STRING— активная Telethon session (в env)
- MCP server launcher:
/mnt/8TB/projects/eslider/mcp-servers/run-telegram-mcp.sh - Session generator:
/mnt/8TB/projects/eslider/mcp-servers/telegram-mcp/session_string_generator.py - Regenerator:
/mnt/8TB/projects/eslider/mcp-servers/regen-telegram-session.py
LinkedIn authentication (работает)
- Запускается через Cursor MCP:
uvx mcp-server-linkedin@latest --user-data-dir ~/.linkedin-mcp/profile --no-auto-import - Cookie файлы:
~/.linkedin-mcp/storage-state.json— Playwright storage state (активные cookies)~/.linkedin-mcp/cookies.json.bak-agent— резерв~/.linkedin-mcp/cookies.json.bak-webtop-20260728T143535Z— резерв/mnt/8TB/projects/eslider/cv/bin/creds/linkedin.cookies.json— для скриптов/mnt/8TB/projects/eslider/JobHunt/sessions/linkedin.json— JobHunt
li_attoken: вstorage-state.json(см. §5)- Для Go подхода: можно читать cookie из
storage-state.jsonи использовать LinkedIn Voyager API напрямую
WhatsApp bridge (не синхронизирован)
- Go bridge at:
/mnt/8TB/projects/eslider/mcp-servers/whatsapp-mcp/whatsapp-bridge/ - Использует
tulir/whatsmeowGo library (уже вgo.mod) - SQLite store:
whatsapp-bridge/store/messages.db— не существует (0 байт), нужна первая авторизация по QR - Launcher:
/mnt/8TB/projects/eslider/mcp-servers/run-whatsapp-bridge-lharries.sh - QR images готовились:
/mnt/8TB/projects/produktor/work/data/export/whatsapp-qr.png - Пароль: в
.envOnlyOffice
OnlyOffice доступ
.envв корне 2dph:ONLYOFFICE_URL,ONLYOFFICE_USER,ONLYOFFICE_PASSooCLI установлен:/home/ano/go/bin/oo(go-onlyoffice)- go-onlyoffice repo:
/mnt/8TB/projects/eslider/go-onlyoffice/(main, public) - oo-workspace (каталог, private):
/mnt/8TB/projects/eslider/oo-workspace/
Gitea
- Instance:
https://git.produktor.io(черезgitea-apiwrapper) - Credentials:
~/.config/gitea/produktor.env - User:
eSlider, admin - Repos: 30+ приватных репозиториев
eSlider/2dphне существует на Gitea — проект только на GitHub- Для задачи: создать issue в существующем репо (например
eSlider/JobHunt) или создать новый репо
Rambox
Не используется. IndexedDB база не существует.
2. Design Decisions
One binary: bin/chats
// Source interface — каждая платформа реализует
type Source interface {
Name() string // "telegram", "whatsapp", "linkedin"
Sync(ctx context.Context, out string) error
}
// CLI subcommands
chats sync telegram [--limit N] [--since DATE]
chats sync whatsapp [--qr] [--limit N]
chats sync linkedin [--limit N]
chats import // JSONL → markdown (all sources)
chats index // rebuild var/kb.lbug
chats facts // extract + cross-check
chats apply // push to OO CRM [--dry-run]
Directory layout (полные имена платформ)
||||||| Stash base
What this document is for
This file captures the full context, research findings, design decisions, and
execution plan for implementing a single Go binary bin/chats that syncs
personal 1:1/group chats from Telegram, WhatsApp, and LinkedIn, converts them
to markdown, indexes them into the brain (var/kb.lbug), extracts contact
facts (phones, social links, projects, deals, associations), cross-checks
against ≥2 independent sources (detective method), and applies verified facts
to OnlyOffice CRM (update persons, contacts, opportunities, projects).
Save this file in context for the next agent session.
1. Находки / Discoveries
Доступные платформы и данные
| Platform | Status | Credentials (path, not values) | Go Library |
|---|---|---|---|
| Telegram | ✅ Active MCP server, session string exists | API creds in telegram.env (see §5). Session string in telegram-mcp/.env. |
MCP JSON-RPC (через telegram-mcp server) |
✅ MCP server exists + Go bridge. No messages.db yet (empty). Needs QR re-auth + sync first |
MCP: /mnt/8TB/projects/eslider/mcp-servers/whatsapp-mcp/. Go bridge uses tulir/whatsmeow |
tulir/whatsmeow (7k★, Go, multi-device API) |
|
✅ Connected via mcp-server-linkedin. Full browser profile + cookies |
Browser profile: ~/.linkedin-mcp/profile/. Active cookies: ~/.linkedin-mcp/storage-state.json. Cookie backup: ~/.linkedin-mcp/cookies.json.bak-agent. Script cookies: /mnt/8TB/projects/eslider/cv/bin/creds/linkedin.cookies.json. JobHunt session: /mnt/8TB/projects/eslider/JobHunt/sessions/linkedin.json. Env: /mnt/8TB/projects/eslider/cv/.env (LINKEDIN_AUTH_TOKEN). |
swiftlysingh/lnk (Go CLI, Voyager API) |
|
| Gmail | ✅ Already working pipeline (bin/mail/sync.go + bin/mail/import) |
OAuth at ~/.gmail-mcp/ |
Already in 2dph |
| Twitter/X.com | ⚠️ Password only, no MCP, no session. Not needed now. | /mnt/8TB/projects/eslider/scratches/Accounts/twitter-pass.txt |
benoitpetit/xsh (Go CLI, cookie auth) |
| Google Calendar | ❌ Not connected yet. Gmail OAuth could extend | None | Нужен Google Calendar API |
Telegram session (проверен, активен)
- API credentials in:
/mnt/8TB/projects/eslider/mcp-servers/telegram.envTELEGRAM_API_ID,TELEGRAM_API_HASH,TELEGRAM_PHONE— загружаются из envTELEGRAM_SESSION_STRING— активная Telethon session (в env)
- MCP server launcher:
/mnt/8TB/projects/eslider/mcp-servers/run-telegram-mcp.sh - Session generator:
/mnt/8TB/projects/eslider/mcp-servers/telegram-mcp/session_string_generator.py - Regenerator:
/mnt/8TB/projects/eslider/mcp-servers/regen-telegram-session.py
LinkedIn authentication (работает)
- Запускается через Cursor MCP:
uvx mcp-server-linkedin@latest --user-data-dir ~/.linkedin-mcp/profile --no-auto-import - Cookie файлы:
~/.linkedin-mcp/storage-state.json— Playwright storage state (активные cookies)~/.linkedin-mcp/cookies.json.bak-agent— резерв~/.linkedin-mcp/cookies.json.bak-webtop-20260728T143535Z— резерв/mnt/8TB/projects/eslider/cv/bin/creds/linkedin.cookies.json— для скриптов/mnt/8TB/projects/eslider/JobHunt/sessions/linkedin.json— JobHunt
li_attoken: вstorage-state.json(см. §5)- Для Go подхода: можно читать cookie из
storage-state.jsonи использовать LinkedIn Voyager API напрямую
WhatsApp bridge (не синхронизирован)
- Go bridge at:
/mnt/8TB/projects/eslider/mcp-servers/whatsapp-mcp/whatsapp-bridge/ - Использует
tulir/whatsmeowGo library (уже вgo.mod) - SQLite store:
whatsapp-bridge/store/messages.db— не существует (0 байт), нужна первая авторизация по QR - Launcher:
/mnt/8TB/projects/eslider/mcp-servers/run-whatsapp-bridge-lharries.sh - QR images готовились:
/mnt/8TB/projects/produktor/work/data/export/whatsapp-qr.png - Пароль: в
.envOnlyOffice
OnlyOffice доступ
.envв корне 2dph:ONLYOFFICE_URL,ONLYOFFICE_USER,ONLYOFFICE_PASSooCLI установлен:/home/ano/go/bin/oo(go-onlyoffice)- go-onlyoffice repo:
/mnt/8TB/projects/eslider/go-onlyoffice/(main, public) - oo-workspace (каталог, private):
/mnt/8TB/projects/eslider/oo-workspace/
Gitea
- Instance:
https://git.produktor.io(черезgitea-apiwrapper) - Credentials:
~/.config/gitea/produktor.env - User:
eSlider, admin - Repos: 30+ приватных репозиториев
eSlider/2dphне существует на Gitea — проект только на GitHub- Для задачи: создать issue в существующем репо (например
eSlider/JobHunt) или создать новый репо
Rambox
Не используется. IndexedDB база не существует.
2. Design Decisions
One binary: bin/chats
// Source interface — каждая платформа реализует
type Source interface {
Name() string // "telegram", "whatsapp", "linkedin"
Sync(ctx context.Context, out string) error
}
// CLI subcommands
chats sync telegram [--limit N] [--since DATE]
chats sync whatsapp [--qr] [--limit N]
chats sync linkedin [--limit N]
chats import // JSONL → markdown (all sources)
chats index // rebuild var/kb.lbug
chats facts // extract + cross-check
chats apply // push to OO CRM [--dry-run]
Directory layout (полные имена платформ)
=======
Key env vars (set in shell, never committed)
Stashed changes
TELEGRAM_MCP_DIR telegram-mcp directory
TELEGRAM_API_ID from telegram.env
TELEGRAM_API_HASH from telegram.env
TELEGRAM_PHONE from telegram.env
TELEGRAM_SESSION_STRING from telegram-mcp/.env
ONLYOFFICE_URL from .env
ONLYOFFICE_USER from .env
ONLYOFFICE_PASS from .env
KNOWLEDGE_MESH_SEED path to knowledge-mesh-seed.yaml (for facts/crm)
OO_CLI path to oo binary (default: $HOME/go/bin/oo)
Quick reference
./bin/chat sync telegram --limit 100
./bin/chat import
./bin/chat index # delegates to bin/kb/index
./bin/chat facts
./bin/chat apply --dry-run
<<<<<<< Updated upstream
MD format (YAML frontmatter)
---
id: tg_12345
platform: telegram
chat_id: "-100123456"
chat_name: "John Doe"
participants: ["me", "John Doe"]
message_count: 1500
type: personal
---
# Чат с John Doe
**2026-01-15 10:30** — me: Hello!
Фильтр "личный чат"
- ≤3 участников
- Боты не считаются (Telegram:
user.is_bot == false) - Не канал, не публичная группа
- Telegram:
dialog.Type == "user"или супергруппа сparticipants_count <= 3(исключая ботов) - WhatsApp:
@s.whatsapp.net(не@g.us) - LinkedIn: 1:1 conversation
Очередность реализации
- Telegram — самый простой (session string + API ID/Hash активны)
- Import — конвертер JSONL → MD
- Index — интеграция с brain
- WhatsApp — после первого QR
- Facts — извлечение контактных данных
- LinkedIn — после проверки cookie
- Apply — запись в OO CRM
Тестирование (TDD, system tests only)
- Никаких unit-тестов, никаких моков
- Тесты используют синтетические данные (слепки)
- Workflow use-case как тест:
- Написать тест с реальным сценарием (sync → import → index → search)
- Проверить что файлы созданы
- Проверить что поиск возвращает ожидаемые результаты
- A/B тест: сравнить два последовательных sync на идентичность
- Integration: тест через
ooCLI с--dry-run
Cross-check (detective method)
Перед записью в OO CRM — минимум 2 независимых источника:
- S1: Чат (текст сообщения, автор, дата)
- S2: OO CRM (существующий контакт/компания/deal) через
oo persons list/oo persons get - S3 (опционально): Corpus SoT (
knowledge-mesh-seed.yaml) или web-search - Факты с ≥2 источниками →
root=factsв brain +approve=trueдля CRM - Факты с 1 источником → предложение на review (catalog-паттерн)
Apply в OO CRM
Через oo CLI:
oo persons update <id> --about ... --job-title ...oo contacts info-add <id> --type Phone|LinkedIn --value ...oo opportunities create --contact-id ... --title ... --stage ...oo persons update <id> --company-id ...(ассоциация)oo projects contacts <project-id>(связь с проектом)
3. Implementation Plan
Phase 1: Telegram sync + import (MVP)
- Create
bin/chats/directory structure (nested Go module likebin/kbsearch/) - Implement
Sourceinterface - Implement
TelegramSource— MCP JSON-RPC клиент к telegram-mcp - Write JSONL output to
var/chats/telegram/<id>/messages.jsonl - Implement
chats import— reads all JSONL, writes MD - Write system test: sync → import → verify output
Phase 2: Brain indexing
- Implement
chats index— rebuildvar/kb.lbugwith corpus + chats - Write system test: sync → import → index →
bin/kb/search "query"→ verify recall
Phase 3: WhatsApp
- Implement
WhatsAppSourceusingtulir/whatsmeow - First run requires QR auth (save session for later reuse)
- Write sync output to
var/chats/whatsapp/<jid>/messages.jsonl
Phase 4: Facts extraction + cross-check
- Implement
chats facts:- Phone regex:
\+?\d{7,15}+ validation (exclude dates/amounts/cards) - LinkedIn URL regex:
linkedin\.com/in/[\w-]+ - Cross-check: match extracted values against OO CRM API
- Phone regex:
- Write facts to brain as
root=facts
Phase 5: LinkedIn + Apply
- Implement
LinkedInSourceusing Voyager API + cookies fromstorage-state.json - Implement
chats apply:- Build YAML catalog (as
oo-workspacedoes) - Run
oo catalog match→ review →oo catalog apply
- Build YAML catalog (as
4. Existing code references
| Code | Path | Purpose |
|---|---|---|
| Mail sync | bin/mail/sync.go + bin/mail/sync/ |
Pattern for chat sync (Go subprocess pattern) |
| Mail import | bin/mail/import |
Pattern for JSONL → MD conversion |
| Mail index | bin/mail/index_mail |
Pattern for brain rebuild with new corpus |
| kbsearch | bin/kbsearch/ |
Go module pattern (nested, system_ladybug tag) |
| kb/index | bin/kb/index |
Python brain index (upsert_leaf, init_schema) |
| kblib | bin/tools/kblib.py |
Python brain core (connect, upsert_leaf, hybrid_search) |
| facts/crm | bin/facts/crm |
Cross-check CRM facts pattern |
| facts/extract | bin/facts/extract |
2-source fact extraction pattern |
| oo-workspace catalog | /mnt/8TB/projects/eslider/oo-workspace/catalog/ |
Catalog scan/match/apply pattern (VCF, Thunderbird, projects) |
| WhatsApp bridge | /mnt/8TB/projects/eslider/mcp-servers/whatsapp-mcp/whatsapp-bridge/ |
Existing whatsmeow Go bridge |
| go-onlyoffice | /mnt/8TB/projects/eslider/go-onlyoffice/ |
OO CRM API library |
| oo CLI | /home/ano/go/bin/oo |
Built go-onlyoffice CLI |
5. Critical files (paths only, no secrets)
| File | Content |
|---|---|
~/.config/gitea/produktor.env |
Gitea URL + token |
/mnt/8TB/projects/eslider/mcp-servers/telegram.env |
Telegram API ID/Hash + phone + session |
/mnt/8TB/projects/eslider/mcp-servers/telegram-mcp/.env |
Telegram session string |
/mnt/8TB/projects/ai/2dph/.env |
ONLYOFFICE URL/USER/PASS |
/mnt/8TB/projects/eslider/cv/.env |
LinkedIn auth token |
~/.linkedin-mcp/storage-state.json |
LinkedIn active cookies |
/mnt/8TB/projects/eslider/go-onlyoffice/.env |
OO creds for oo CLI |
/mnt/8TB/projects/eslider/go-onlyoffice/go.mod |
Deps for go-onlyoffice |
/mnt/8TB/projects/eslider/oo-workspace/go.mod |
Deps for oo-workspace |
6. Agent prompt (для запуска новой сессии)
Скопируйте этот промпт при старте новой сессии:
Ты — ассистент для разработки chat import pipeline в проекте 2dph (eSlider/2dph).
Прочитай docs/chat-import-plan.md полностью. Это план, находки и дизайн.
Задача: реализовать bin/chats — единый Go бинарник для sync/import/index/facts/apply
личных чатов из Telegram, WhatsApp, LinkedIn с последующей записью фактов в OnlyOffice CRM.
Правила:
1. TDD first — workflow use-case как тест. Синтетические данные (Alice, Bob).
2. Go, всё в один бинарник bin/chats.
3. Source interface — каждая платформа плагином.
4. var/chats/telegram/ — полные имена платформ.
5. Начни с Telegram (session string активна, через MCP server).
6. После реализации — создай/обнови тесты.
7. Сохрани прогресс в docs/chat-import-plan.md.
8. Запроси разрешение перед apply в OO CRM.
9. НИКАКИХ реальных имён, телефонов, email в коммитах — только ссылки на env файлы.
Ключевые пути:
- /mnt/8TB/projects/ai/2dph/ — корень проекта
- /mnt/8TB/projects/eslider/mcp-servers/telegram-mcp/ — Telegram MCP
- /mnt/8TB/projects/eslider/mcp-servers/telegram.env — API ID/Hash + session (не коммитить!)
- /mnt/8TB/projects/eslider/go-onlyoffice/ — go-onlyoffice библиотека
- /home/ano/go/bin/oo — OO CLI
Готов начать.
7. Implementation Progress
Session: 2026-08-12 — Phase 1 complete, sync проверен с реальными данными
Результаты тестового синка (--limit=100, 31 личный чат):
- Подключение к Telegram MCP server: 1.5с
- Получен 31 личный чат (отфильтровано боты + Telegram service)
- Синк всех чатов: 7.7с (1 flood wait на 3с, обработан MCP сервером)
- Записано 922 сообщения в JSONL
- Import: 30 чатов в MD (1 пустой — Saved Messages)
- Факты: 14 phone + 2 email после фильтрации
Ключевое изменение: gotd/td → Telegram MCP Server
- Вместо прямого gotd/td подключения (FLOOD_WAIT из-за 5 уже запущенных MCP серверов)
- Используется MCP JSON-RPC (JSONL,
\n-delimited, не Content-Length headers) - Переиспользует существующий Telethon session string (без phone auth)
- Стартует транзиентный MCP сервер на время синка, убивает после
- Инструменты:
list_chats+get_historyчерез MCP protocol v1.8+
Файлы:
| Файл | Роль |
|---|---|
bin/chats/mcpclient.go |
MCP JSON-RPC client + TelegramMCPSource |
bin/chats/sync_cmd.go |
CLI: chats sync telegram --limit N |
bin/chats/import_cmd.go |
JSONL → MD с YAML frontmatter |
bin/chats/index_cmd.go |
Делегирует bin/kb/index --corpus |
bin/chats/facts_cmd.go |
Regex extraction (phone/email/linkedin) с валидацией |
bin/chats/apply_cmd.go |
OO CRM cross-check + apply через oo CLI + --dry-run |
bin/chat |
build+exec wrapper (как bin/kb/search) |
Phone regex улучшен:
- Фильтр: исключает даты (
2026-06-14), суммы (2 500 000), номера карт (16 digits), инвойсы (25-002332001) - Валидация: >=7 digits, <=15 digits, без
000pattern, не дата - Результат: 37 → 16 фактов (14 phone + 2 email)
Cross-check + Apply в OO CRM (без персональных данных в файлах):
- Найден существующий контакт через first name: добавлен phone + email
- Создан новый контакт: phone добавлен
- Apply через
oo contacts info-add <id> --type Phone|Email --value ...
Brain: 132 leafs (120 info + 12 facts), чаты заиндексены
Безопасность:
var/в.gitignore— сырые чат-данные не коммитятся- credentials в env файлах, не в коде
- Тесты используют синтетические данные (Alice, Bob, Charlie, Diana)
- Этот документ не содержит реальных значений API ключей, токенов, паролей или персональных данных третьих лиц
Что дальше (следующая сессия):
- WhatsApp source (
tulir/whatsmeow) — после первого QR - LinkedIn source (Voyager API через cookies)
- Full history sync (без --limit) для всех чатов
- Telegram session reuse через MCP server (уже работает)
- Apply через
bin/chats apply(уже работает, улучшен поиск контактов)
313599b (bin/chats: Phase 1 MVP — Telegram sync/import/index/facts/apply) ||||||| Stash base
MD format (YAML frontmatter)
---
id: tg_12345
platform: telegram
chat_id: "-100123456"
chat_name: "John Doe"
participants: ["me", "John Doe"]
message_count: 1500
type: personal
---
# Чат с John Doe
**2026-01-15 10:30** — me: Hello!
Фильтр "личный чат"
- ≤3 участников
- Боты не считаются (Telegram:
user.is_bot == false) - Не канал, не публичная группа
- Telegram:
dialog.Type == "user"или супергруппа сparticipants_count <= 3(исключая ботов) - WhatsApp:
@s.whatsapp.net(не@g.us) - LinkedIn: 1:1 conversation
Очередность реализации
- Telegram — самый простой (session string + API ID/Hash активны)
- Import — конвертер JSONL → MD
- Index — интеграция с brain
- WhatsApp — после первого QR
- Facts — извлечение контактных данных
- LinkedIn — после проверки cookie
- Apply — запись в OO CRM
Тестирование (TDD, system tests only)
- Никаких unit-тестов, никаких моков
- Тесты используют синтетические данные (слепки)
- Workflow use-case как тест:
- Написать тест с реальным сценарием (sync → import → index → search)
- Проверить что файлы созданы
- Проверить что поиск возвращает ожидаемые результаты
- A/B тест: сравнить два последовательных sync на идентичность
- Integration: тест через
ooCLI с--dry-run
Cross-check (detective method)
Перед записью в OO CRM — минимум 2 независимых источника:
- S1: Чат (текст сообщения, автор, дата)
- S2: OO CRM (существующий контакт/компания/deal) через
oo persons list/oo persons get - S3 (опционально): Corpus SoT (
knowledge-mesh-seed.yaml) или web-search - Факты с ≥2 источниками →
root=factsв brain +approve=trueдля CRM - Факты с 1 источником → предложение на review (catalog-паттерн)
Apply в OO CRM
Через oo CLI:
oo persons update <id> --about ... --job-title ...oo contacts info-add <id> --type Phone|LinkedIn --value ...oo opportunities create --contact-id ... --title ... --stage ...oo persons update <id> --company-id ...(ассоциация)oo projects contacts <project-id>(связь с проектом)
3. Implementation Plan
Phase 1: Telegram sync + import (MVP)
- Create
bin/chats/directory structure (nested Go module likebin/kbsearch/) - Implement
Sourceinterface - Implement
TelegramSource— MCP JSON-RPC клиент к telegram-mcp - Write JSONL output to
var/chats/telegram/<id>/messages.jsonl - Implement
chats import— reads all JSONL, writes MD - Write system test: sync → import → verify output
Phase 2: Brain indexing
- Implement
chats index— rebuildvar/kb.lbugwith corpus + chats - Write system test: sync → import → index →
bin/kb/search "query"→ verify recall
Phase 3: WhatsApp
- Implement
WhatsAppSourceusingtulir/whatsmeow - First run requires QR auth (save session for later reuse)
- Write sync output to
var/chats/whatsapp/<jid>/messages.jsonl
Phase 4: Facts extraction + cross-check
- Implement
chats facts:- Phone regex:
\+?\d{7,15}+ validation (exclude dates/amounts/cards) - LinkedIn URL regex:
linkedin\.com/in/[\w-]+ - Cross-check: match extracted values against OO CRM API
- Phone regex:
- Write facts to brain as
root=facts
Phase 5: LinkedIn + Apply
- Implement
LinkedInSourceusing Voyager API + cookies fromstorage-state.json - Implement
chats apply:- Build YAML catalog (as
oo-workspacedoes) - Run
oo catalog match→ review →oo catalog apply
- Build YAML catalog (as
4. Existing code references
| Code | Path | Purpose |
|---|---|---|
| Mail sync | bin/mail/sync.go + bin/mail/sync/ |
Pattern for chat sync (Go subprocess pattern) |
| Mail import | bin/mail/import |
Pattern for JSONL → MD conversion |
| Mail index | bin/mail/index_mail |
Pattern for brain rebuild with new corpus |
| kbsearch | bin/kbsearch/ |
Go module pattern (nested, system_ladybug tag) |
| kb/index | bin/kb/index |
Python brain index (upsert_leaf, init_schema) |
| kblib | bin/tools/kblib.py |
Python brain core (connect, upsert_leaf, hybrid_search) |
| facts/crm | bin/facts/crm |
Cross-check CRM facts pattern |
| facts/extract | bin/facts/extract |
2-source fact extraction pattern |
| oo-workspace catalog | /mnt/8TB/projects/eslider/oo-workspace/catalog/ |
Catalog scan/match/apply pattern (VCF, Thunderbird, projects) |
| WhatsApp bridge | /mnt/8TB/projects/eslider/mcp-servers/whatsapp-mcp/whatsapp-bridge/ |
Existing whatsmeow Go bridge |
| go-onlyoffice | /mnt/8TB/projects/eslider/go-onlyoffice/ |
OO CRM API library |
| oo CLI | /home/ano/go/bin/oo |
Built go-onlyoffice CLI |
5. Critical files (paths only, no secrets)
| File | Content |
|---|---|
~/.config/gitea/produktor.env |
Gitea URL + token |
/mnt/8TB/projects/eslider/mcp-servers/telegram.env |
Telegram API ID/Hash + phone + session |
/mnt/8TB/projects/eslider/mcp-servers/telegram-mcp/.env |
Telegram session string |
/mnt/8TB/projects/ai/2dph/.env |
ONLYOFFICE URL/USER/PASS |
/mnt/8TB/projects/eslider/cv/.env |
LinkedIn auth token |
~/.linkedin-mcp/storage-state.json |
LinkedIn active cookies |
/mnt/8TB/projects/eslider/go-onlyoffice/.env |
OO creds for oo CLI |
/mnt/8TB/projects/eslider/go-onlyoffice/go.mod |
Deps for go-onlyoffice |
/mnt/8TB/projects/eslider/oo-workspace/go.mod |
Deps for oo-workspace |
6. Agent prompt (для запуска новой сессии)
Скопируйте этот промпт при старте новой сессии:
Ты — ассистент для разработки chat import pipeline в проекте 2dph (eSlider/2dph).
Прочитай docs/chat-import-plan.md полностью. Это план, находки и дизайн.
Задача: реализовать bin/chats — единый Go бинарник для sync/import/index/facts/apply
личных чатов из Telegram, WhatsApp, LinkedIn с последующей записью фактов в OnlyOffice CRM.
Правила:
1. TDD first — workflow use-case как тест. Синтетические данные (Alice, Bob).
2. Go, всё в один бинарник bin/chats.
3. Source interface — каждая платформа плагином.
4. var/chats/telegram/ — полные имена платформ.
5. Начни с Telegram (session string активна, через MCP server).
6. После реализации — создай/обнови тесты.
7. Сохрани прогресс в docs/chat-import-plan.md.
8. Запроси разрешение перед apply в OO CRM.
9. НИКАКИХ реальных имён, телефонов, email в коммитах — только ссылки на env файлы.
Ключевые пути:
- /mnt/8TB/projects/ai/2dph/ — корень проекта
- /mnt/8TB/projects/eslider/mcp-servers/telegram-mcp/ — Telegram MCP
- /mnt/8TB/projects/eslider/mcp-servers/telegram.env — API ID/Hash + session (не коммитить!)
- /mnt/8TB/projects/eslider/go-onlyoffice/ — go-onlyoffice библиотека
- /home/ano/go/bin/oo — OO CLI
Готов начать.
7. Implementation Progress
Session: 2026-08-12 — Phase 1 complete, sync проверен с реальными данными
Результаты тестового синка (--limit=100, 31 личный чат):
- Подключение к Telegram MCP server: 1.5с
- Получен 31 личный чат (отфильтровано боты + Telegram service)
- Синк всех чатов: 7.7с (1 flood wait на 3с, обработан MCP сервером)
- Записано 922 сообщения в JSONL
- Import: 30 чатов в MD (1 пустой — Saved Messages)
- Факты: 14 phone + 2 email после фильтрации
Ключевое изменение: gotd/td → Telegram MCP Server
- Вместо прямого gotd/td подключения (FLOOD_WAIT из-за 5 уже запущенных MCP серверов)
- Используется MCP JSON-RPC (JSONL,
\n-delimited, не Content-Length headers) - Переиспользует существующий Telethon session string (без phone auth)
- Стартует транзиентный MCP сервер на время синка, убивает после
- Инструменты:
list_chats+get_historyчерез MCP protocol v1.8+
Файлы:
| Файл | Роль |
|---|---|
bin/chats/mcpclient.go |
MCP JSON-RPC client + TelegramMCPSource |
bin/chats/sync_cmd.go |
CLI: chats sync telegram --limit N |
bin/chats/import_cmd.go |
JSONL → MD с YAML frontmatter |
bin/chats/index_cmd.go |
Делегирует bin/kb/index --corpus |
bin/chats/facts_cmd.go |
Regex extraction (phone/email/linkedin) с валидацией |
bin/chats/apply_cmd.go |
OO CRM cross-check + apply через oo CLI + --dry-run |
bin/chat |
build+exec wrapper (как bin/kb/search) |
Phone regex улучшен:
- Фильтр: исключает даты (
2026-06-14), суммы (2 500 000), номера карт (16 digits), инвойсы (25-002332001) - Валидация: >=7 digits, <=15 digits, без
000pattern, не дата - Результат: 37 → 16 фактов (14 phone + 2 email)
Cross-check + Apply в OO CRM (без персональных данных в файлах):
- Найден существующий контакт через first name: добавлен phone + email
- Создан новый контакт: phone добавлен
- Apply через
oo contacts info-add <id> --type Phone|Email --value ...
Brain: 132 leafs (120 info + 12 facts), чаты заиндексены
Безопасность:
var/в.gitignore— сырые чат-данные не коммитятся- credentials в env файлах, не в коде
- Тесты используют синтетические данные (Alice, Bob, Charlie, Diana)
- Этот документ не содержит реальных значений API ключей, токенов, паролей или персональных данных третьих лиц
Что дальше (следующая сессия):
- WhatsApp source (
tulir/whatsmeow) — после первого QR - LinkedIn source (Voyager API через cookies)
- Full history sync (без --limit) для всех чатов
- Telegram session reuse через MCP server (уже работает)
- Apply через
bin/chats apply(уже работает, улучшен поиск контактов) =======
Stashed changes