{"id":27180243,"url":"https://github.com/kotru21/cat-api-telegraf","last_synced_at":"2026-04-30T14:36:30.509Z","repository":{"id":104006797,"uuid":"606449947","full_name":"kotru21/cat-api-telegraf","owner":"kotru21","description":"Telegram bot including web panel with updates in real time (using websockets), based on Cat API.","archived":false,"fork":false,"pushed_at":"2025-04-02T17:30:50.000Z","size":360,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-02T17:36:36.256Z","etag":null,"topics":["api","bot","cat","cat-api","cats","expressjs","telegraf","telegram-api","telegram-bot","telegrambot","websockets"],"latest_commit_sha":null,"homepage":"https://catbotbykotikov-9bb8beb0f01f.herokuapp.com","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kotru21.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-25T14:31:06.000Z","updated_at":"2025-04-02T17:30:54.000Z","dependencies_parsed_at":null,"dependency_job_id":"29a80a88-5102-41b6-8cd4-6da84074f00c","html_url":"https://github.com/kotru21/cat-api-telegraf","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kotru21%2Fcat-api-telegraf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kotru21%2Fcat-api-telegraf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kotru21%2Fcat-api-telegraf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kotru21%2Fcat-api-telegraf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kotru21","download_url":"https://codeload.github.com/kotru21/cat-api-telegraf/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248054565,"owners_count":21040025,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","bot","cat","cat-api","cats","expressjs","telegraf","telegram-api","telegram-bot","telegrambot","websockets"],"created_at":"2025-04-09T14:26:02.049Z","updated_at":"2026-04-30T14:36:30.503Z","avatar_url":"https://github.com/kotru21.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🐱 Cat API Telegram Bot \u0026 Web Platform\n\nСовременное приложение с Telegram ботом и веб-интерфейсом для просмотра и взаимодействия с фотографиями котов через The Cat API.\n\n## 📋 Содержание\n\n- [🚀 Особенности](#-особенности)\n- [💻 Технологический стек](#-технологический-стек)\n- [🔧 Установка](#-установка)\n- [⚙️ Конфигурация](#️-конфигурация)\n- [🗄️ База данных](#️-база-данных)\n- [📊 API Документация](#-api-документация)\n- [🤖 Telegram Bot](#-telegram-bot)\n- [🚀 Развертывание](#-развертывание)\n\n## 🚀 Особенности\n\n- 🎲 **Случайные коты** с детальной информацией о породах\n- ❤️ **Система лайков** с персонализацией для пользователей\n- 🏆 **Лидерборд** самых популярных пород\n- 🔍 **Умный поиск** по характеристикам породы\n- 📱 **Dual Interface**: Telegram бот + веб-интерфейс\n- 🔄 **Real-time обновления** через WebSocket\n- 👤 **Telegram авторизация** в веб-интерфейсе\n\n## 🧱 Технологический стек\n\n**Backend:**\n\n- Bun v1.0+ - JavaScript runtime с встроенным WebSocket\n- Hono v4 - лёгкий веб-фреймворк\n- Telegraf.js v4.11.2 - Telegram Bot Framework\n- Prisma ORM v6.16.2 - типобезопасная работа с БД\n- Awilix v12.0.0 - Dependency Injection\n\n**База данных:**\n\n- PostgreSQL (продакшен) / SQLite (dev) через Prisma\n- Redis v5.8.2 - сессии и rate limiting (опционально)\n\n**Безопасность:**\n\n- Web Crypto API - криптография (HMAC, nonce)\n- CSRF защита с timing-safe сравнением\n- Rate limiting с Redis/in-memory fallback\n- CSP, CORS, Security Headers\n\n**Frontend:**\n\n- Tailwind CSS (local build) - стилизация (ранее использовался CDN, теперь компилируется локально). Для Tailwind v4 рекомендуется установить плагин Vite:\n\n  ```bash\n  bun install -d tailwindcss @tailwindcss/vite\n  ```\n\n- Vanilla JavaScript - интерактивность\n- WebSocket - real-time обновления\n\n## 🔧 Установка\n\n### Требования\n\n- [Bun](https://bun.sh/) v1.0.0 или выше\n\n### Локальная установка\n\n1. **Клонируйте репозиторий:**\n\n   ```bash\n   git clone https://github.com/kotru21/cat-api-telegraf.git\n   cd cat-api-telegraf\n   ```\n\n2. **Установите зависимости:**\n\n   ```bash\n   bun install\n   ```\n\n3. **Настройте переменные окружения:**\n\n   Скопируйте `.env.example` в `.env` и заполните:\n\n   ```env\n   # Обязательные\n   CATAPI_KEY=your-cat-api-key-from-thecatapi.com\n   SESSION_SECRET=your-strong-random-secret-min-10-chars\n\n   # Опциональные (значения по умолчанию)\n   PORT=5200\n   WEBSITE_URL=http://localhost\n   WEB_ENABLED=true\n   BOT_ENABLED=false\n   BOT_TOKEN=your-telegram-bot-token\n   NODE_ENV=development\n   DATABASE_URL=file:./prisma/main.db\n\n   # Redis (опционально)\n   REDIS_ENABLED=false\n   # REDIS_URL=redis://localhost:6379\n   ```\n\n4. **Настройте базу данных:**\n\n   ```bash\n   bun run prisma:generate\n   bun run prisma:migrate:dev\n   ```\n\n5. **Запустите приложение:**\n\n   ```bash\n   bun start\n   ```\n\nДополнительно: локально можно запускать только сбор CSS (при разработке):\n\n```bash\nbun run css:watch   # слежение и сбор tailwind.css\nbun run css:build   # один раз собрать minified tailwind.css\n```\n\n### Получение API ключей\n\n1. **The Cat API ключ:**\n   - Зарегистрируйтесь на [thecatapi.com](https://thecatapi.com/)\n   - Получите бесплатный API ключ\n   - Добавьте в `.env` как `CATAPI_KEY`\n\n2. **Telegram Bot Token:**\n   - Напишите [@BotFather](https://t.me/botfather) в Telegram\n   - Создайте нового бота командой `/newbot`\n   - Получите токен и добавьте в `.env` как `BOT_TOKEN`\n\n## ⚙️ Конфигурация\n\n### Переменные окружения\n\n| Переменная       | Тип     | По умолчанию            | Описание                    |\n| ---------------- | ------- | ----------------------- | --------------------------- |\n| `CATAPI_KEY`     | string  | **обязательно**         | API ключ The Cat API        |\n| `PORT`           | number  | `5200`                  | Порт HTTP/WebSocket сервера |\n| `WEBSITE_URL`    | string  | `http://localhost`      | Базовый URL приложения      |\n| `WEB_ENABLED`    | boolean | `true`                  | Включить веб-сервер         |\n| `BOT_ENABLED`    | boolean | `true`                  | Включить Telegram бота      |\n| `BOT_TOKEN`      | string  | опционально\\*           | Токен Telegram бота         |\n| `SESSION_SECRET` | string  | `your-secret-key-here`  | Секрет для сессий           |\n| `NODE_ENV`       | enum    | `development`           | Окружение                   |\n| `DATABASE_URL`   | string  | `file:./prisma/main.db` | Строка подключения к БД     |\n| `REDIS_URL`      | string  | опционально\\*\\*         | URL Redis для сессий        |\n\n\\* Обязательно, если `BOT_ENABLED=true`  \n\\*\\* Обязательно в продакшене\n\n## 🗄️ База данных\n\nПриложение использует **Prisma ORM** с PostgreSQL в продакшене и SQLite для разработки.\n\n### Автоматическая инициализация таблиц\n\nПри запуске `npm start` или `bun start` приложение **автоматически**:\n\n**Development (SQLite):**\n\n- Копирует `schema.sqlite.prisma` → `schema.prisma`\n- Генерирует Prisma Client\n- **Создаёт таблицы напрямую через SQL** (если их нет)\n\n**Production (PostgreSQL):**\n\n- Копирует `schema.postgres.prisma` → `schema.prisma`\n- Генерирует Prisma Client\n- **Применяет миграции из `prisma/migrations/`** через `prisma migrate deploy`\n\n\u003e ⚠️ **Важно для Production**: Перед деплоем убедитесь, что миграции для PostgreSQL созданы и закоммичены в репозиторий.\n\n### Команды Prisma\n\n````bash\n# Генерация клиента после изменения схемы\nnpm run prisma:generate\n\n# Создание и применение миграций\nnpm run prisma:migrate:dev\n\n# Запуск Prisma Studio (GUI для БД)\nnpm run prisma:studio\n\nЕсли вы запускаете локально в режиме `development` с SQLite (значение `DATABASE_URL=file:./prisma/main.db` в `.env`), можно использовать удобные dev-скрипты:\n\n```bash\n# Генерация клиента для sqlite (использует prisma/schema.sqlite.prisma)\nnpm run prisma:generate:dev\n\n# Создание / применение миграций локально в sqlite (внутри prisma/main.db)\nnpm run prisma:migrate:dev:sqlite\n````\n\n````\n\n## 📊 API Документация\n\n### Основные endpoints\n\n```http\nGET /api/cat/:id              # Получить кота по ID\nGET /api/leaderboard          # Лидерборд популярных пород\nGET /api/similar              # Поиск по характеристикам\nPOST /api/like                # Поставить лайк (требует авторизации)\nDELETE /api/like              # Убрать лайк (требует авторизации)\nGET /api/profile              # Профиль пользователя (требует авторизации)\nPOST /api/auth/telegram       # Telegram авторизация\n````\n\n### Health checks\n\n```http\nGET /healthz                  # Проверка состояния\nGET /readyz                   # Проверка готовности\n```\n\n## 🤖 Telegram Bot\n\n### Доступные команды\n\n| Команда    | Описание                    |\n| ---------- | --------------------------- |\n| `/start`   | Приветствие и главное меню  |\n| `/fact`    | Случайный кот с информацией |\n| `/mylikes` | Список лайкнутых котов      |\n| `/top`     | Лидерборд популярных пород  |\n\n### Интерактивные действия\n\n- ❤️ **Лайк** - поставить/убрать лайк коту\n- 🔍 **Похожие** - найти котов с похожими характеристиками\n- 📊 **Лидерборд** - посмотреть популярные породы\n- 🎲 **Еще кот** - получить еще одного случайного кота\n\n## 🚀 Развертывание\n\n### Production Requirements\n\n````env\n# Обязательные для продакшена\nNODE_ENV=production\nCATAPI_KEY=your-cat-api-key\nSESSION_SECRET=complex-random-string-min-32-chars\nDATABASE_URL=postgresql://user:pass@host:5432/db\n\n# Redis (рекомендуется в production)\nREDIS_ENABLED=true\nREDIS_URL=redis://localhost:6379\n\n# Telegram (если нужен бот)\nBOT_ENABLED=true\nBOT_TOKEN=your-production-bot-token\n\n# Безопасность\nWEBSITE_URL=https://yourdomain.com\n\n## 🧩 Frontend Architecture (2025 Refactor)\n\nФронтенд разделён на прозрачные слои (Clean-ish layering):\n\n```\nsrc/web/public/js/\n   api.js                // HTTP helper + caching\n   utils.js              // Утилиты и константы (PLACEHOLDER, sanitize, preloadImages)\n   core/\n      state/\n         store.js          // Pub/sub store + event bus\n         lifecycle.js      // registerCleanup / runCleanups\n      services/           // ONLY: fetch -\u003e normalize -\u003e update store (+ TTL кэш)\n         LeaderboardService.js\n         LikesService.js\n         ProfileService.js\n         CatDetailsService.js\n      ui/                 // Чистый DOM (render / create... без fetch)\n         leaderboard.js\n         likes.js\n         catDetails.js\n         skeleton.js\n      errors/\n         errorMapper.js\n         notify.js         // notifyError / notifySuccess (toast + dedupe)\n   components/           // Отдельные переиспользуемые \"виджеты\"\n      searchAndSort.js\n      heroAvatars.js\n   pages/                // Оркестрация: подписка + вызов сервисов + lifecycle\n      indexPage.js\n      profilePage.js\n      catDetailsPage.js\n```\n\nGuidelines / Правила слоя:\n1. pages → orchestration only (никакой логики трансформации данных, минимум DOM).\n2. services → обращение к `api.js`, нормализация формата, TTL-кэш (Map / timestamps), обновление store.\n3. ui → функции create*/render* без сетевых запросов; получают уже нормализованные данные.\n4. errors → централизованный mapping + уведомления; исключает дублирование try/catch.\n5. a11y → `aria-busy` на контейнерах, `role=list/listitem`, скрытие skeleton через `aria-hidden` (частично внедрено).\n6. Никаких inline event handlers в HTML (CSP friendly) — см. раздел Security/CSP.\n\n### Data Model (кратко)\nПолное описание: `docs/data-model.md` (создано для синхронизации фронт/бэк). Ниже краткая выжимка:\n\n| Entity            | Поля (нормализованные)                                                                                  |\n|-------------------|----------------------------------------------------------------------------------------------------------|\n| LeaderboardRow    | `position`, `catId`, `breedName`, `likes`, `change` (резерв), `imageUrl`                                 |\n| Like              | `catId`, `breedName`, `imageUrl`, `likes`                                                                |\n| CatDetails        | `id`, `breedName`, `description`, `likes`, `wikipediaUrl`, `origin`, `temperament`, `lifeSpan`, `weightMetric`, `weightImperial`, `imageUrl` |\n| Profile           | Телеграм данные пользователя (`first_name`, `last_name`, `username`, `photo_url`)                       |\n\n`catId` — единый публичный идентификатор. В переходный период сервис `normalizeRow` имеет fallback цепочку `id || breed_id || cat_id` и выводит предупреждение в dev, если идентификатора нет. План: удалить fallback после выравнивания схемы БД.\n\n### Кэширование (TTL)\n- Leaderboard: 15s\n- Likes: 10s + отдельный fetch count\n- Profile: 30s (см. ProfileService — если будет добавлен TTL)\n- CatDetails: 30s (Map cache)\n\n### Тестирование\n`jest` + `jsdom` для юнитов (store, нормализация, UI компонентов). Запуск:\n```\nnpm test\n```\nПокрытие можно расширить тестами на optimistic update (удаление лайка) и поведение skeleton.\n\n### Security / CSP\n- Убраны inline обработчики (`onerror`, `onclick`) — заменены на JS привязку.\n- Используется Helmet + строгий `script-src-attr 'none'`.\n- Fallback изображений через `data-fallback` + JS `error` listener.\n\n### Roadmap / Next\n- [ ] Удалить fallback цепочку `breed_id` / `cat_id` → оставить только `id`.\n- [ ] Дополнить a11y: скрывать skeleton через `aria-hidden=\"true\"`, live region для обновления лайков.\n- [ ] Интегрировать реальный POST лайка на странице деталей (сейчас кнопка локально инкрементирует число).\n- [ ] Расширить тесты (optimistic rollback, WebSocket stats stub).\n- [ ] Вынести image preloading в общий модуль с абстракцией cancellation.\n\n````\n\n### Heroku Deployment\n\n```bash\n# Подготовка\nheroku create your-app-name\n# Использовать MongoDB Atlas (или другой MongoDB add-on) и Heroku Redis\nheroku addons:create mongodbatlas    # или другой MongoDB add-on (mongolab/mongoDB Atlas)\nheroku addons:create heroku-redis:mini\n\n# Переменные окружения\nheroku config:set NODE_ENV=production\nheroku config:set CATAPI_KEY=your-key\nheroku config:set SESSION_SECRET=your-secret\nheroku config:set BOT_TOKEN=your-bot-token\nheroku config:set REDIS_ENABLED=true\n\n# Если Mongo add-on устанавливает MONGODB_URI, можно скопировать его в DATABASE_URL:\nheroku config:set DATABASE_URL=$(heroku config:get MONGODB_URI -a your-app-name)\n\n# Деплой\ngit push heroku main\n```\n\n---\n\n## 🔗 Links\n\n- **GitHub Repository**: [kotru21/cat-api-telegraf](https://github.com/kotru21/cat-api-telegraf)\n- **The Cat API**: [thecatapi.com](https://thecatapi.com/)\n- **Telegram Bot API**: [core.telegram.org/bots](https://core.telegram.org/bots)\n\n---\n\n⭐ **Если проект был полезен, поставьте звездочку на GitHub!** ⭐\n\n---\n\n### Changelog (Frontend Refactor Summary)\n\n2025-12: **Bun Migration** - Миграция с Node.js/Express на Bun/Hono. Redis теперь опционален (REDIS_ENABLED), Web Crypto API вместо Node.js crypto, SESSION_SECRET обязателен.\n\n2025-09: Полный рефактор фронтенда (слои services/state/ui, удалены legacy компоненты, введены тесты, устранены inline handlers, консолидация идентификатора `catId`).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkotru21%2Fcat-api-telegraf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkotru21%2Fcat-api-telegraf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkotru21%2Fcat-api-telegraf/lists"}