import { existsSync } from 'node:fs'; import db from './sqlite'; interface MediaRow { id: number; chat_id: number; message_id: number; user_id: number; username: null | string; display_name: null | string; file_type: string; file_id: string; file_unique_id: null | string; caption: null | string; file_name: null | string; file_path: string; file_size: null | number; mime_type: null | string; duration: null | number; width: null | number; height: null | number; forwarded_to: null | number; created_at: string; updated_at: string; } export interface MediaMessage { id: number; chatId: number; messageId: number; userId: number; username?: string; displayName?: string; fileType: string; fileId: string; fileUniqueId?: string; caption?: string; fileName?: string; filePath: string; fileSize?: number; mimeType?: string; duration?: number; width?: number; height?: number; forwardedTo?: number; createdAt: string; updatedAt: string; available: boolean; downloadUrl: string | null; } function mapMediaRow(row: MediaRow): MediaMessage { const fileExists = existsSync(row.file_path); return { id: row.id, chatId: row.chat_id, messageId: row.message_id, userId: row.user_id, username: row.username ?? undefined, displayName: row.display_name ?? undefined, fileType: row.file_type, fileId: row.file_id, fileUniqueId: row.file_unique_id ?? undefined, caption: row.caption ?? undefined, fileName: row.file_name ?? undefined, filePath: row.file_path, fileSize: row.file_size ?? undefined, mimeType: row.mime_type ?? undefined, duration: row.duration ?? undefined, width: row.width ?? undefined, height: row.height ?? undefined, forwardedTo: row.forwarded_to ?? undefined, createdAt: row.created_at, updatedAt: row.updated_at, available: fileExists, downloadUrl: fileExists ? `/finance/media/${row.id}/download` : null, }; } export function fetchMediaMessages(params: { limit?: number; fileTypes?: string[]; } = {}) { const clauses: string[] = []; const bindParams: Record = {}; if (params.fileTypes && params.fileTypes.length > 0) { clauses.push( `file_type IN (${params.fileTypes.map((_, index) => `@type${index}`).join(', ')})`, ); params.fileTypes.forEach((type, index) => { bindParams[`type${index}`] = type; }); } const where = clauses.length > 0 ? `WHERE ${clauses.join(' AND ')}` : ''; const limitClause = params.limit && params.limit > 0 ? `LIMIT ${Number(params.limit)}` : ''; const stmt = db.prepare( `SELECT id, chat_id, message_id, user_id, username, display_name, file_type, file_id, file_unique_id, caption, file_name, file_path, file_size, mime_type, duration, width, height, forwarded_to, created_at, updated_at FROM finance_media_messages ${where} ORDER BY datetime(created_at) DESC, id DESC ${limitClause}`, ); return stmt.all(bindParams).map(mapMediaRow); } export function getMediaMessageById(id: number) { const stmt = db.prepare( `SELECT id, chat_id, message_id, user_id, username, display_name, file_type, file_id, file_unique_id, caption, file_name, file_path, file_size, mime_type, duration, width, height, forwarded_to, created_at, updated_at FROM finance_media_messages WHERE id = ?`, ); const row = stmt.get(id); return row ? mapMediaRow(row) : null; }