5 Telegram каналов на Казахстан с автопостингом. RSS парсинг → DeepSeek AI рерайт → OG-image overlay → Telegram. Монетизация: Pin-Up Partners.
/home/app/kz-channels/
| Ключ | Канал | Тип | Контент |
|---|---|---|---|
| almaty-news | @almaty_segodnya1 | news | Новости Алматы |
| astana-news | @astana_segodnya | news | Новости Астаны |
| typical-kz | @typical_kz1 | humor | Казахский юмор (AI-генерация) |
| dengi-kz | @dengi_kz1 | earnings | Заработок в KZ (AI-генерация) |
| kz-champions | @kz_champions | sports | Спорт KZ |
| Файл | Назначение |
|---|---|
bot.js |
Точка входа: Grammy бот + node-cron + dashboard |
config.js |
Каналы, крон расписание, AI конфиг, реклама |
scheduler.js |
Обработка слотов, отправка постов, реклама, модерация |
database.js |
SQLite: посты, статистика, источники, очередь |
error-log.js |
Ring buffer ошибок + persist data/errors.json |
services/news-parser.js |
RSS парсинг (rss-parser) |
services/content-generator.js |
DeepSeek V4 Pro рерайт через OpenRouter |
services/image-handler.js |
OG-image загрузка + overlay (sharp) |
dashboard/server.js |
Express дашборд (Basic Auth) |
| Слот | Время | Тип |
|---|---|---|
| morning | 08:15 | digest |
| mid1 | 10:30 | content |
| lunch | 12:15 | content |
| afternoon | 14:30 | content |
| evening_ad | 16:00 | content/ad |
| evening | 18:30 | content/ad |
| night | 21:15 | interactive |
Cron с { timezone: 'Asia/Almaty' } в node-cron.
| Параметр | Описание |
|---|---|
| BOT_TOKEN | Grammy Telegram бот токен |
| OPENROUTER_API_KEY | OpenRouter для DeepSeek |
| ALMATY_CHANNEL_ID | Chat ID @almaty_segodnya1 |
| ASTANA_CHANNEL_ID | Chat ID @astana_segodnya |
| TYPICAL_KZ_CHANNEL_ID | Chat ID @typical_kz1 |
| DENGI_KZ_CHANNEL_ID | Chat ID @dengi_kz1 |
| KZ_CHAMPIONS_CHANNEL_ID | Chat ID @kz_champions |
| PINUP_LINK | Партнёрская ссылка Pin-Up |
| DASHBOARD_USER / DASHBOARD_PASS | Basic Auth дашборда |
AI модель: deepseek/deepseek-v4-pro, maxTokens: 800, temperature: 0.8.
# PM2
pm2 restart kz-channels
pm2 logs kz-channels --lines 30
# Дашборд
https://arb.szhub.space (Basic Auth admin/kz2026secure)
# Бот-команды (PM от админа)
/status — посты и реклама за сегодня
/stats — статистика за 7 дней
/test <channel> — тестовый пост
SQLite: /home/app/kz-channels/data/kz-channels.db
Таблицы: posts, stats, sources, post_queue
16 источников (все approved, 18 мая 2026):
Управление через дашборд: модалка добавления, одобрение/отклонение.
{ timezone: 'Asia/Almaty' } — сервер UTC, крон в Алматы{ override: true } — .bashrc экспортирует старые ключиЧерез дашборд → "Добавить источник" (модалка). Или напрямую в БД:
INSERT INTO sources (channel_id, name, url, type, status) VALUES ('almaty-news', 'Name', 'https://...rss', 'rss', 'approved');
Через дашборд → выбрать канал → ввести текст (+опционально картинка URL).
Дашборд → Очередь модерации → Approve/Reject.
typical-kz ОСТАНОВЛЕН (config.js enabled:false + гард в bot.js cron-цикле if(enabled===false)continue). Конфиг НЕ удалён — вернуть = убрать флаг. Осталось 4 активных: almaty-news, astana-news, dengi-kz, kz-champions.
🔑 АРХИТЕКТУРА (грабли, важно):
channel.type, НЕ по источникам. news→RSS-путь (generateContent), humor/earnings→generateOriginalContent (AI без новости).db.getApprovedSources(channelKey), НЕ из config.js. migrateSources() сидит config→БД ТОЛЬКО при пустой таблице sources (один раз). Правки config.js sources = no-op в рантайме. Новые источники добавлять INSERT в таблицу sources (status='approved', added_by='system'). config.js менять только для документации.fetchNews обрабатывает только type==='rss'; scrape-источники (Kolesa/HH.kz у dengi) НЕ реализованы — были мёртвые.Анти-мета фильтр усилен (services/content-generator.js): уже был isMetaRefusal (был норм — из 1020 постов реальных утечек 3, 2 до фильтра от 19 May). Добавлено: (1) END_META_PATTERNS — хвостовая болтовня в последних 150 симв («если нужно — могу переписать»); (2) callAIValidated() — 1 ретрай со строгим RETRY_REINFORCEMENT system-месседжем перед фолбэком (news→formatRawNews, original→null).
B1 Живые промпты (config.js, 4 канала): хук с эмодзи в ПЕРВОЙ строке, эмоция/мнение, вопрос аудитории в конце. Было «кратко, по делу, информативный» = сухо.
B2 Ротация источников (news-parser.js shuffle() Fisher-Yates) — лента не на 90% из Tengrinews (fetchNews возвращал первый источник по порядку).
B4 Гибрид dengi-kz (scheduler.js): useOriginal = type==='humor' || (type==='earnings' && Math.random()<0.5) → ~50% реальные финновости RSS (добавил в БД Kursiv/Nur Бизнес к Banker/Inbusiness/LS), ~50% AI-идеи.
B3 Рубрика «Курс валют» (services/special-content.js getCurrencyPost()): Нацбанк РК https://nationalbank.kz/rss/rates_all.xml (39 валют, бери USD/EUR/RUB/CNY + change-стрелки). Слот morning для almaty/astana/dengi (CURRENCY_CHANNELS в scheduler). db.getKZDate() экспортирован.
Опрос дня (getPoll() + блок в scheduler night-слот, POLL_CHANNELS=все 4): AI генерит ВОПРОС:/ВАРИАНТ: формат → парс+валидация (2-4 уник опции) → bot.api.sendPoll(chatId,q,opts,{is_anonymous:true}). Статичный FALLBACK_POLLS по типу канала (AI-формат часто срывается → фолбэк надёжен). grammY 1.25 sendPoll принимает строки и {text}.
Рабочие RSS КЗ (проверены live): Nur.kz all/sport/business nur.kz/rss/{all,sport,business}.rss, Total.kz total.kz/rss, Kursiv kz.kursiv.media/feed/, Profit.kz profit.kz/rss/, Tengrinews, Sports.kz, Inbusiness inbusiness.kz/ru/rss, Banker banker.kz/news/rss/. Мёртвые: Zakon (404), Informburo (403), Vlast/Orda/Liter (404), Forbes (битый XML).
День канала: 🌅 утро=курс валют → ☀️ день=живые новости (ротация) → 🌆 вечер=реклама-слоты + опрос. Коммиты afebbfa/b0f1494/ef1a257/08548e3/28ca823/ecd6693/31dcfdf (master, pushed).
TODO: PINUP_LINK ещё пустой (ad_posts_count=0, монетизация спит); набор подписчиков; опц. рубрика «Знаете ли вы».