350 lines
15 KiB
Python
Executable File
350 lines
15 KiB
Python
Executable File
#!/usr/bin/env python3
|
||
"""
|
||
Telegram Collector - Configuration Script
|
||
----------------------------------------
|
||
This script helps set up and configure the Telegram Collector skill
|
||
for monitoring and extracting knowledge from Telegram groups and channels.
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
import json
|
||
import re
|
||
from pathlib import Path
|
||
import subprocess
|
||
import shutil
|
||
|
||
# Директории
|
||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||
SCRIPTS_DIR = os.path.join(SCRIPT_DIR, "scripts")
|
||
REFERENCES_DIR = os.path.join(SCRIPT_DIR, "references")
|
||
DATA_DIR = os.path.join(SCRIPT_DIR, "data")
|
||
|
||
# Убедитесь, что все необходимые директории существуют
|
||
os.makedirs(SCRIPTS_DIR, exist_ok=True)
|
||
os.makedirs(REFERENCES_DIR, exist_ok=True)
|
||
os.makedirs(DATA_DIR, exist_ok=True)
|
||
os.makedirs(os.path.join(DATA_DIR, "raw"), exist_ok=True)
|
||
os.makedirs(os.path.join(DATA_DIR, "topics"), exist_ok=True)
|
||
os.makedirs(os.path.join(DATA_DIR, "summaries"), exist_ok=True)
|
||
|
||
# Файл конфигурации
|
||
CONFIG_FILE = os.path.join(SCRIPT_DIR, "config.json")
|
||
|
||
def print_banner():
|
||
"""Выводит баннер приветствия"""
|
||
print("\n" + "=" * 60)
|
||
print(" TELEGRAM COLLECTOR - КОНФИГУРАЦИЯ ".center(60))
|
||
print("=" * 60)
|
||
print("\nЭтот мастер поможет вам настроить сбор данных из Telegram.")
|
||
print("Для работы вам понадобятся учетные данные Telegram API.\n")
|
||
|
||
def check_dependencies():
|
||
"""Проверяет наличие необходимых зависимостей"""
|
||
print("Проверка зависимостей...")
|
||
|
||
# Проверка Python
|
||
try:
|
||
python_version = subprocess.check_output(["python3", "--version"], universal_newlines=True)
|
||
print(f"✅ {python_version.strip()}")
|
||
except:
|
||
print("❌ Python3 не найден. Пожалуйста, установите Python3.")
|
||
return False
|
||
|
||
# Проверка pip
|
||
try:
|
||
pip_version = subprocess.check_output(["pip3", "--version"], universal_newlines=True)
|
||
print(f"✅ pip установлен: {pip_version.split()[1]}")
|
||
except:
|
||
print("❌ pip не найден. Пожалуйста, установите pip.")
|
||
return False
|
||
|
||
# Установка необходимых пакетов
|
||
print("\nУстановка необходимых пакетов...")
|
||
try:
|
||
subprocess.check_call(["pip3", "install", "telethon", "python-dotenv", "nltk"])
|
||
print("✅ Все пакеты установлены успешно")
|
||
except:
|
||
print("❌ Ошибка при установке пакетов")
|
||
return False
|
||
|
||
# Проверка NLTK данных
|
||
try:
|
||
import nltk
|
||
nltk.download('punkt', quiet=True)
|
||
nltk.download('stopwords', quiet=True)
|
||
print("✅ NLTK данные загружены")
|
||
except:
|
||
print("❌ Ошибка при загрузке NLTK данных")
|
||
|
||
return True
|
||
|
||
def get_telegram_api_credentials():
|
||
"""Получает учетные данные Telegram API от пользователя"""
|
||
print("\n" + "=" * 60)
|
||
print("НАСТРОЙКА TELEGRAM API".center(60))
|
||
print("=" * 60)
|
||
|
||
print("\nДля использования API Telegram вам необходимы API ID и API Hash.")
|
||
print("Их можно получить на сайте https://my.telegram.org/apps\n")
|
||
|
||
api_id = input("Введите API ID: ").strip()
|
||
while not api_id.isdigit():
|
||
print("❌ API ID должен быть числом")
|
||
api_id = input("Введите API ID: ").strip()
|
||
|
||
api_hash = input("Введите API Hash: ").strip()
|
||
while not re.match(r'^[a-f0-9]{32}$', api_hash, re.I):
|
||
print("❌ API Hash должен быть 32-символьной строкой")
|
||
api_hash = input("Введите API Hash: ").strip()
|
||
|
||
phone = input("Введите номер телефона (в международном формате, например +79123456789): ").strip()
|
||
while not re.match(r'^\+[0-9]{7,15}$', phone):
|
||
print("❌ Неверный формат номера телефона")
|
||
phone = input("Введите номер телефона (например +79123456789): ").strip()
|
||
|
||
return {
|
||
"api_id": api_id,
|
||
"api_hash": api_hash,
|
||
"phone": phone
|
||
}
|
||
|
||
def create_env_file(credentials):
|
||
"""Создает файл .env с учетными данными"""
|
||
env_file = os.path.expanduser("~/.openclaw/.env")
|
||
|
||
with open(env_file, 'w', encoding='utf-8') as f:
|
||
f.write(f"# Telegram API credentials\n")
|
||
f.write(f"TELEGRAM_API_ID={credentials['api_id']}\n")
|
||
f.write(f"TELEGRAM_API_HASH={credentials['api_hash']}\n")
|
||
f.write(f"TELEGRAM_PHONE={credentials['phone']}\n")
|
||
f.write(f"TELEGRAM_SESSION=telegram_collector\n\n")
|
||
f.write(f"# Output directory\n")
|
||
f.write(f"OUTPUT_DIR={DATA_DIR}\n")
|
||
|
||
print(f"\n✅ Ключи добавлены в: {env_file}")
|
||
|
||
# Сохраняем конфигурацию (credentials хранятся только в .env, не в config.json)
|
||
config = {
|
||
"credentials_configured": True, # Флаг, что credentials настроены (хранятся в .env)
|
||
"data_dir": DATA_DIR,
|
||
"initialized": False,
|
||
"cron_setup": False,
|
||
"openclaw_integration": False
|
||
}
|
||
|
||
with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
|
||
json.dump(config, f, indent=2)
|
||
|
||
return True
|
||
|
||
def configure_cron():
|
||
"""Настраивает cron-задания для автоматического запуска"""
|
||
print("\n" + "=" * 60)
|
||
print("НАСТРОЙКА АВТОМАТИЗАЦИИ".center(60))
|
||
print("=" * 60)
|
||
|
||
print("\nВыберите частоту сбора данных из Telegram:")
|
||
print("1. Каждый час")
|
||
print("2. Каждые 6 часов (рекомендуется)")
|
||
print("3. Каждые 12 часов")
|
||
print("4. Раз в день")
|
||
print("5. Не настраивать автоматизацию")
|
||
|
||
choice = input("\nВаш выбор (1-5): ").strip()
|
||
while choice not in ["1", "2", "3", "4", "5"]:
|
||
choice = input("Пожалуйста, выберите 1-5: ").strip()
|
||
|
||
if choice == "5":
|
||
print("\n✅ Автоматизация не настроена. Вы можете запускать сбор данных вручную.")
|
||
return False
|
||
|
||
# Преобразуем выбор в выражение cron
|
||
cron_expr = ""
|
||
if choice == "1":
|
||
cron_expr = "0 * * * *" # Каждый час
|
||
elif choice == "2":
|
||
cron_expr = "0 */6 * * *" # Каждые 6 часов
|
||
elif choice == "3":
|
||
cron_expr = "0 */12 * * *" # Каждые 12 часов
|
||
elif choice == "4":
|
||
cron_expr = "0 0 * * *" # В полночь каждый день
|
||
|
||
# Подготавливаем задание cron в формате OpenClaw
|
||
run_script = os.path.join(SCRIPTS_DIR, "run.sh")
|
||
|
||
# Создаем файл запуска
|
||
with open(run_script, 'w', encoding='utf-8') as f:
|
||
f.write('#!/bin/bash\n')
|
||
f.write(f'cd "{SCRIPT_DIR}"\n')
|
||
f.write(f'python3 {SCRIPTS_DIR}/collector.py collect-all\n')
|
||
f.write(f'python3 {SCRIPTS_DIR}/analyzer.py analyze-all\n')
|
||
f.write(f'python3 {SCRIPTS_DIR}/analyzer.py update-kb\n')
|
||
|
||
# Устанавливаем права на выполнение
|
||
os.chmod(run_script, 0o755)
|
||
|
||
print(f"\n✅ Создан скрипт запуска: {run_script}")
|
||
|
||
# Настраиваем задание cron через OpenClaw
|
||
print("\nНастройка cron-задания через OpenClaw...")
|
||
try:
|
||
subprocess.run(["openclaw", "cron", "add", "--job", json.dumps({
|
||
"name": "telegram-collector:run",
|
||
"schedule": {
|
||
"kind": "cron",
|
||
"expr": cron_expr,
|
||
"tz": "UTC"
|
||
},
|
||
"payload": {
|
||
"kind": "systemEvent",
|
||
"text": f"Запуск сбора данных из Telegram: {run_script}"
|
||
},
|
||
"sessionTarget": "main",
|
||
"enabled": True
|
||
})], check=True)
|
||
|
||
print("\n✅ Cron-задание успешно настроено")
|
||
|
||
# Обновляем конфигурацию
|
||
if os.path.exists(CONFIG_FILE):
|
||
with open(CONFIG_FILE, 'r', encoding='utf-8') as f:
|
||
config = json.load(f)
|
||
|
||
config["cron_setup"] = True
|
||
config["cron_expr"] = cron_expr
|
||
|
||
with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
|
||
json.dump(config, f, indent=2)
|
||
|
||
return True
|
||
except:
|
||
print("\n❌ Ошибка при настройке cron-задания")
|
||
print("Вы можете настроить его позже вручную.")
|
||
return False
|
||
|
||
def configure_openclaw_integration():
|
||
"""Настраивает интеграцию с памятью OpenClaw"""
|
||
print("\n" + "=" * 60)
|
||
print("ИНТЕГРАЦИЯ С OPENCLAW".center(60))
|
||
print("=" * 60)
|
||
|
||
print("\nХотите ли вы интегрировать собранные данные с памятью OpenClaw?")
|
||
print("Это позволит автоматически обновлять MEMORY.md с информацией из Telegram.")
|
||
|
||
choice = input("\nИнтегрировать с памятью OpenClaw? (y/n): ").strip().lower()
|
||
if choice != "y":
|
||
print("\n✅ Интеграция с памятью OpenClaw не настроена.")
|
||
return False
|
||
|
||
print("\nНастройка интеграции с памятью OpenClaw...")
|
||
|
||
# Подготавливаем задание cron для обновления памяти
|
||
try:
|
||
subprocess.run(["openclaw", "cron", "add", "--job", json.dumps({
|
||
"name": "telegram-collector:memory-update",
|
||
"schedule": {
|
||
"kind": "cron",
|
||
"expr": "30 */8 * * *", # Через 30 минут после каждых 8 часов
|
||
"tz": "UTC"
|
||
},
|
||
"payload": {
|
||
"kind": "agentTurn",
|
||
"message": f"Обнови знания из Telegram. Изучи новые данные в директории {DATA_DIR} и обнови MEMORY.md добавив туда важную информацию из базы знаний knowledge_base.md. Также проверь, появились ли новые темы и категоризируй их.",
|
||
"timeoutSeconds": 300 # 5 минут на выполнение
|
||
},
|
||
"sessionTarget": "isolated",
|
||
"delivery": {
|
||
"mode": "announce",
|
||
"bestEffort": True
|
||
},
|
||
"enabled": True
|
||
})], check=True)
|
||
|
||
print("\n✅ Интеграция с памятью OpenClaw успешно настроена")
|
||
|
||
# Обновляем конфигурацию
|
||
if os.path.exists(CONFIG_FILE):
|
||
with open(CONFIG_FILE, 'r', encoding='utf-8') as f:
|
||
config = json.load(f)
|
||
|
||
config["openclaw_integration"] = True
|
||
|
||
with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
|
||
json.dump(config, f, indent=2)
|
||
|
||
return True
|
||
except:
|
||
print("\n❌ Ошибка при настройке интеграции с OpenClaw")
|
||
print("Вы можете настроить её позже вручную.")
|
||
return False
|
||
|
||
def main():
|
||
"""Основная функция настройки"""
|
||
print_banner()
|
||
|
||
# Проверяем зависимости
|
||
if not check_dependencies():
|
||
print("\n❌ Ошибка при проверке зависимостей. Пожалуйста, установите необходимые компоненты вручную.")
|
||
return 1
|
||
|
||
# Проверяем существование файла конфигурации
|
||
initialized = False
|
||
if os.path.exists(CONFIG_FILE):
|
||
with open(CONFIG_FILE, 'r', encoding='utf-8') as f:
|
||
config = json.load(f)
|
||
|
||
initialized = config.get("initialized", False)
|
||
|
||
if initialized:
|
||
print("\n✅ Telegram Collector уже настроен.")
|
||
print("Вы хотите изменить настройки?")
|
||
|
||
choice = input("\nИзменить настройки? (y/n): ").strip().lower()
|
||
if choice != "y":
|
||
print("\nНастройки не изменены.")
|
||
return 0
|
||
|
||
# Получаем учетные данные Telegram API
|
||
credentials = get_telegram_api_credentials()
|
||
|
||
# Создаем файл .env
|
||
if not create_env_file(credentials):
|
||
print("\n❌ Ошибка при создании файла .env")
|
||
return 1
|
||
|
||
# Настраиваем автоматизацию
|
||
configure_cron()
|
||
|
||
# Настраиваем интеграцию с OpenClaw
|
||
configure_openclaw_integration()
|
||
|
||
# Обновляем статус инициализации
|
||
if os.path.exists(CONFIG_FILE):
|
||
with open(CONFIG_FILE, 'r', encoding='utf-8') as f:
|
||
config = json.load(f)
|
||
|
||
config["initialized"] = True
|
||
|
||
with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
|
||
json.dump(config, f, indent=2)
|
||
|
||
print("\n" + "=" * 60)
|
||
print("НАСТРОЙКА ЗАВЕРШЕНА".center(60))
|
||
print("=" * 60)
|
||
|
||
print("\n✅ Telegram Collector успешно настроен!")
|
||
print("\nТеперь вы можете:")
|
||
print("1. Запустить просмотр доступных групп и каналов:")
|
||
print(f" python3 {SCRIPTS_DIR}/collector.py list")
|
||
print("2. Добавить группы и каналы для отслеживания:")
|
||
print(f" python3 {SCRIPTS_DIR}/collector.py add <group_id>")
|
||
print("3. Добавить темы для анализа:")
|
||
print(f" python3 {SCRIPTS_DIR}/analyzer.py add-topic \"Название темы\" \"ключевое_слово1,ключевое_слово2\"")
|
||
print("4. Запустить сбор данных вручную:")
|
||
print(f" {SCRIPTS_DIR}/run.sh\n")
|
||
|
||
return 0
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main()) |