const axios = require('axios');
const sharp = require('sharp');
function log(msg) {
const ts = new Date().toLocaleString('en-CA', { timeZone: 'America/Vancouver' });
console.log(`[${ts}] ${msg}`);
}
// Скачать OG-image и наложить overlay (затемнение + лого канала)
async function prepareImage(imageUrl, channel) {
// Скачать картинку
const { data } = await axios.get(imageUrl, {
responseType: 'arraybuffer',
timeout: 10000,
headers: { 'User-Agent': 'Mozilla/5.0 (compatible; KZBot/1.0)' }
});
const buffer = Buffer.from(data);
// Получить размеры оригинала
const metadata = await sharp(buffer).metadata();
const width = Math.min(metadata.width || 1200, 1200);
const height = Math.min(metadata.height || 630, 800);
// Создать overlay с названием канала
const channelName = channel.name || '';
const svgOverlay = `
<svg width="${width}" height="${height}">
<defs>
<linearGradient id="grad" x1="0" y1="1" x2="0" y2="0">
<stop offset="0%" style="stop-color:rgba(0,0,0,0.7)"/>
<stop offset="40%" style="stop-color:rgba(0,0,0,0)"/>
</linearGradient>
</defs>
<rect width="${width}" height="${height}" fill="url(#grad)"/>
<text x="20" y="${height - 20}" font-family="Arial, sans-serif" font-size="22" font-weight="bold" fill="white" opacity="0.8">
${escapeXml(channelName)}
</text>
</svg>
`;
// Композит: оригинал + затемнение + текст
const result = await sharp(buffer)
.resize(width, height, { fit: 'cover' })
.composite([{
input: Buffer.from(svgOverlay),
blend: 'over'
}])
.jpeg({ quality: 85 })
.toBuffer();
log(`🖼️ Картинка: ${(result.length / 1024).toFixed(0)}KB (${width}x${height})`);
return result;
}
// Escape XML спецсимволов для SVG
function escapeXml(str) {
return str
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
module.exports = { prepareImage };
📜 Git History
2757087init: KZ Channels bot — 5 Telegram channels for Kazakhstan7 weeks ago
Show last diff
Loading...