Files
zeropost-engine/src/services/ai.js
T
Alexey Pavlov 612053b93d feat: initial zeropost-engine structure
- AI service with Anthropic claude-sonnet-4-6
- Bull queue for async generation jobs
- Routes: /api/generate, /api/channels, /api/posts
- PostgreSQL schema: users, channels, posts, generation_jobs
- Supports: post, article, topics generation types
2026-05-30 21:29:04 +03:00

81 lines
3.3 KiB
JavaScript

const axios = require('axios');
const config = require('../config');
const ANTHROPIC_URL = 'https://api.anthropic.com/v1/messages';
const MODEL = 'claude-sonnet-4-6';
/**
* Generate text via Anthropic API
* @param {string} systemPrompt
* @param {string} userPrompt
* @param {object} options - { maxTokens, temperature }
*/
const generate = async (systemPrompt, userPrompt, options = {}) => {
const { maxTokens = 2000 } = options;
const res = await axios.post(ANTHROPIC_URL, {
model: MODEL,
max_tokens: maxTokens,
system: systemPrompt,
messages: [{ role: 'user', content: userPrompt }],
}, {
headers: {
'x-api-key': config.anthropicApiKey,
'anthropic-version': '2023-06-01',
'Content-Type': 'application/json',
},
});
const text = res.data.content?.[0]?.text;
if (!text) throw new Error('Empty response from Anthropic');
return text;
};
/**
* Generate a Telegram post
*/
const generatePost = async ({ topic, tone = 'neutral', language = 'ru', channelContext = '' }) => {
const system = `Ты — профессиональный автор Telegram-каналов. Пишешь посты на ${language === 'ru' ? 'русском' : 'английском'} языке.
Тон: ${tone}.
${channelContext ? `Контекст канала: ${channelContext}` : ''}
Правила:
- Пост 150-400 слов
- Используй эмодзи уместно
- Не используй markdown заголовки (##, **), только текст и эмодзи
- В конце добавь 2-4 релевантных хэштега`;
const user = `Напиши пост на тему: "${topic}"`;
return generate(system, user, { maxTokens: 1000 });
};
/**
* Generate a blog article
*/
const generateArticle = async ({ topic, language = 'ru', keywords = [] }) => {
const system = `Ты — эксперт по искусственному интеллекту, пишешь SEO-оптимизированные статьи на ${language === 'ru' ? 'русском' : 'английском'} языке.
Правила:
- Статья 800-1500 слов
- Структура: заголовок H1, введение, 3-5 разделов H2, заключение
- Используй ключевые слова органично
- Простой и понятный язык`;
const user = `Напиши статью на тему: "${topic}"${keywords.length ? `\nКлючевые слова: ${keywords.join(', ')}` : ''}`;
return generate(system, user, { maxTokens: 3000 });
};
/**
* Generate topic ideas for a channel
*/
const generateTopics = async ({ channelContext, count = 10, language = 'ru' }) => {
const system = `Генерируй идеи для постов в Telegram-канале. Отвечай только JSON массивом строк, без пояснений.`;
const user = `Придумай ${count} идей для постов. Контекст канала: "${channelContext}". Язык: ${language}. Формат: ["тема1","тема2",...]`;
const raw = await generate(system, user, { maxTokens: 800 });
try {
return JSON.parse(raw.replace(/```json|```/g, '').trim());
} catch {
return raw.split('\n').filter(Boolean).slice(0, count);
}
};
module.exports = { generate, generatePost, generateArticle, generateTopics };