отправка фотографии прям в сообщении удаленок

This commit is contained in:
2026-08-10 00:43:30 +03:00
parent 0e19c84a6d
commit eed828ec58
+37 -7
View File
@@ -78,7 +78,7 @@ async function renderItem(ctx, id) {
const item = getCapture(id, ctx.from.id);
if (!item) return edit(ctx, 'Запись не найдена (возможно, удалена по сроку хранения).', backTo('home'));
const caption = formatCapture(item);
const caption = clampCaption(formatCapture(item));
const back = backTo(`feed:${item.kind}:0`);
if (item.media_path) {
@@ -117,11 +117,14 @@ function formatCapture(item) {
}
function fileName(item) {
const ext = { photo: 'jpg', video: 'mp4', voice: 'ogg', gif: 'mp4', audio: 'mp3' }[item.media_kind] ?? 'bin';
const mediaKind = item.media_kind ?? item.mediaKind; // строка БД — snake, объект перехвата — camel
const ext = { photo: 'jpg', video: 'mp4', voice: 'ogg', gif: 'mp4', audio: 'mp3' }[mediaKind] ?? 'bin';
return `${item.kind}_${item.id}.${ext}`;
}
const truncate = (s, n) => (s.length > n ? s.slice(0, n - 1) + '…' : s);
// Подпись к медиа у Telegram ограничена 1024 символами — режем с запасом.
const clampCaption = (s) => truncate(s, 1000);
async function edit(ctx, text, keyboard) {
try {
@@ -138,19 +141,46 @@ async function edit(ctx, text, keyboard) {
/**
* Уведомляет ВЛАДЕЛЬЦА подключения о свежем перехвате — в его личку с ботом.
* item.ownerChatId — куда слать (owner_chat_id из бизнес-подключения).
* Дёргается из модулей через контекст (ctx.capture → notifyCapture).
*
* Если медиа закэшировано, шлём его прямо в уведомлении ДОКУМЕНТОМ (не фото):
* документ Telegram не пережимает, поэтому картинка приходит в исходном качестве
* и её видно сразу — превью в чате, полный размер по тапу. Дёргается из модулей
* через контекст (ctx.capture → notifyCapture). item — объект перехвата (camelCase).
*/
export async function notifyCapture(bot, item) {
if (!item.ownerChatId) {
logger.warn(`bot: некому отправить уведомление о перехвате ${item.id} (нет ownerChatId)`);
return;
}
const kb = new InlineKeyboard().text('Открыть', `item:${item.id}`);
const head = '🗑 Удалённое сообщение';
const text = `${head} от ${item.sender || 'неизвестно'}\n${item.media_kind ? `[${item.media_kind}] ` : ''}${truncate(item.text ?? '', 60)}`;
const kb = new InlineKeyboard().text('Открыть в панели', `item:${item.id}`);
const caption = notifyCaption(item);
if (item.mediaPath) {
try {
const buffer = decrypt(await readMedia(item.mediaPath));
await bot.api.sendDocument(item.ownerChatId, new InputFile(buffer, fileName(item)), {
caption,
reply_markup: kb,
});
return;
} catch (err) {
logger.warn('bot: медиа для уведомления не отдалось, шлю текстом', err.message);
// ниже — запасной текстовый вариант
}
}
try {
await bot.api.sendMessage(item.ownerChatId, text, { reply_markup: kb });
await bot.api.sendMessage(item.ownerChatId, caption, { reply_markup: kb });
} catch (err) {
logger.warn('bot: не удалось уведомить владельца', err.message);
}
}
/** Подпись к уведомлению: кто, тип медиа и текст — в пределах лимита подписи. */
function notifyCaption(item) {
const mediaKind = item.media_kind ?? item.mediaKind;
const lines = [`🗑 Удалённое сообщение от ${item.sender || 'неизвестно'}`];
if (mediaKind) lines.push(`[${mediaKind}]`);
if (item.text) lines.push('', item.text);
return clampCaption(lines.join('\n'));
}