127 lines
3.6 KiB
JavaScript
127 lines
3.6 KiB
JavaScript
const axios = require('axios');
|
||
const User = require('../models/User');
|
||
const config = require('../config');
|
||
const { log } = require('../middleware/logger');
|
||
|
||
const DAY_MS = 24 * 60 * 60 * 1000;
|
||
|
||
async function fetchLatestAvatar(telegramId) {
|
||
if (!config.telegramBotToken) {
|
||
return null;
|
||
}
|
||
|
||
try {
|
||
const apiBase = `https://api.telegram.org/bot${config.telegramBotToken}`;
|
||
|
||
const photosResponse = await axios.get(`${apiBase}/getUserProfilePhotos`, {
|
||
params: {
|
||
user_id: telegramId,
|
||
limit: 1
|
||
},
|
||
timeout: 15000
|
||
});
|
||
|
||
if (!photosResponse.data?.ok || photosResponse.data.result.total_count === 0) {
|
||
return null;
|
||
}
|
||
|
||
const photoSizes = photosResponse.data.result.photos?.[0];
|
||
if (!Array.isArray(photoSizes) || photoSizes.length === 0) {
|
||
return null;
|
||
}
|
||
|
||
const highestQualityPhoto = photoSizes[photoSizes.length - 1];
|
||
if (!highestQualityPhoto?.file_id) {
|
||
return null;
|
||
}
|
||
|
||
const fileResponse = await axios.get(`${apiBase}/getFile`, {
|
||
params: {
|
||
file_id: highestQualityPhoto.file_id
|
||
},
|
||
timeout: 15000
|
||
});
|
||
|
||
if (!fileResponse.data?.ok || !fileResponse.data.result?.file_path) {
|
||
return null;
|
||
}
|
||
|
||
const filePath = fileResponse.data.result.file_path;
|
||
return `https://api.telegram.org/file/bot${config.telegramBotToken}/${filePath}`;
|
||
} catch (error) {
|
||
log('error', 'Ошибка получения аватарки из Telegram', {
|
||
telegramId,
|
||
error: error.message
|
||
});
|
||
return null;
|
||
}
|
||
}
|
||
|
||
async function updateAllUserAvatars() {
|
||
if (!config.telegramBotToken) {
|
||
log('warn', 'Обновление аватарок отключено: TELEGRAM_BOT_TOKEN не установлен');
|
||
return;
|
||
}
|
||
|
||
const users = await User.find({ telegramId: { $exists: true } });
|
||
log('info', 'Начато обновление аватарок пользователей', { count: users.length });
|
||
|
||
for (const user of users) {
|
||
try {
|
||
const latestAvatar = await fetchLatestAvatar(user.telegramId);
|
||
if (latestAvatar && latestAvatar !== user.photoUrl) {
|
||
user.photoUrl = latestAvatar;
|
||
await user.save();
|
||
log('info', 'Аватарка обновлена', { userId: user._id, telegramId: user.telegramId });
|
||
}
|
||
} catch (error) {
|
||
log('error', 'Не удалось обновить аватарку пользователя', {
|
||
userId: user._id,
|
||
telegramId: user.telegramId,
|
||
error: error.message
|
||
});
|
||
}
|
||
}
|
||
|
||
log('info', 'Обновление аватарок завершено');
|
||
}
|
||
|
||
function msUntilNextRun(hour = 3) {
|
||
const now = new Date();
|
||
const nextRun = new Date(now);
|
||
nextRun.setHours(hour, 0, 0, 0);
|
||
if (nextRun <= now) {
|
||
nextRun.setDate(nextRun.getDate() + 1);
|
||
}
|
||
return nextRun.getTime() - now.getTime();
|
||
}
|
||
|
||
function scheduleAvatarUpdates() {
|
||
if (!config.telegramBotToken) {
|
||
log('warn', 'Расписание обновления аватарок отключено: TELEGRAM_BOT_TOKEN не установлен');
|
||
return;
|
||
}
|
||
|
||
const initialDelay = msUntilNextRun();
|
||
|
||
setTimeout(() => {
|
||
updateAllUserAvatars().catch((error) => {
|
||
log('error', 'Ошибка при запуске обновления аватарок', { error: error.message });
|
||
});
|
||
|
||
setInterval(() => {
|
||
updateAllUserAvatars().catch((error) => {
|
||
log('error', 'Ошибка при плановом обновлении аватарок', { error: error.message });
|
||
});
|
||
}, DAY_MS);
|
||
}, initialDelay);
|
||
}
|
||
|
||
module.exports = {
|
||
scheduleAvatarUpdates,
|
||
updateAllUserAvatars,
|
||
fetchLatestAvatar
|
||
};
|
||
|
||
|