Files
postcast-engine/scripts/send-zero-welcome.js
T
Nik (Claude) a370b8f7d8 feat: Зеро-персонаж, auto-publish, auto-series, channel-stats, fallback covers
- Персонаж Зеро: 23 позы (zeroCharacter.js), скрипты генерации
- Auto-publish статей в TG: multipart upload, кнопки, режим alternating Zero/cover
- Fallback цепочка обложек: aiprimetech gpt-5.5 → Pollinations → local SVG (6 палитр)
- Auto-series: Claude haiku определяет серию для каждой статьи автоматически
- Channel stats: подписчики, история, delta 24h/7d
- Photo-search: Yandex API, профили доменов, Redis лимиты
- Scheduled posts runner: backfill, preview, queue, cancel
- promptBuilder: author_persona Зеро, голос от первого лица
- Fixes: dollar-placeholder bugs в PATCH channels/autogen, listArticles фильтры
- AI model: gpt-5.5 для image generation
2026-06-07 14:03:56 +03:00

64 lines
2.7 KiB
JavaScript

// Welcome-пост от имени Зеро.
// Использует готовый zero-avatar.webp.
const fs = require('fs');
const path = require('path');
const axios = require('axios');
const FormData = require('form-data');
process.chdir('/var/www/zeropost-engine');
require('dotenv').config({ path: '/var/www/zeropost-engine/.env' });
const settings = require('/var/www/zeropost-engine/src/services/settings');
const { query } = require('/var/www/zeropost-engine/src/config/db');
const TEXT = `Привет! Я Зеро 👋
Веду этот канал — пишу про ИИ, кибербезопасность, автоматизацию и разработку. Каждый день — короткая заметка про что-то, что я попробовал.
Что внутри:
🤖 ИИ-инструменты, которые реально работают
💻 Разработка с ИИ-помощниками
⚡ Автоматизация без боли
🔒 Безопасность для обычных людей
Без хайпа, без «революционных открытий», без картинок с роботами. Только то, что заходит в работе.
🌐 Полная версия каждой заметки — на сайте
📌 Закрепи этот пост, чтобы не потерять`;
(async () => {
try {
const { rows: chs } = await query(`SELECT * FROM channels WHERE id=1`);
const channel = chs[0];
const tgBase = await settings.get('TELEGRAM_API_BASE', 'https://api.telegram.org');
const localPath = '/var/www/zeropost-uploads/zero-avatar.webp';
if (!fs.existsSync(localPath)) throw new Error('zero-avatar.webp not found');
const form = new FormData();
form.append('chat_id', String(channel.tg_channel_id));
form.append('caption', TEXT.slice(0, 1024));
form.append('parse_mode', 'Markdown');
form.append('reply_markup', JSON.stringify({
inline_keyboard: [[{ text: '🌐 Открыть сайт', url: 'https://zeropost.ru' }]],
}));
form.append('photo', fs.createReadStream(localPath));
const res = await axios.post(`${tgBase}/bot${channel.bot_token}/sendPhoto`, form, {
headers: form.getHeaders(),
timeout: 60000, maxContentLength: Infinity, maxBodyLength: Infinity,
});
const messageId = res.data?.result?.message_id;
console.log(`sent message_id=${messageId}, длина caption=${TEXT.length}`);
await query(
`INSERT INTO posts (channel_id, content, status, published_at, tg_message_id)
VALUES ($1,$2,'published',NOW(),$3)`,
[channel.id, TEXT, messageId]
);
} catch (err) {
console.error('FAIL:', err.response?.data || err.message);
process.exit(1);
}
})();