import { existsSync } from 'node:fs'; import { query } from './db'; 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: null | string; } 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 async function fetchMediaMessages( params: { fileTypes?: string[]; limit?: number; } = {}, ) { const whereClauses: string[] = []; const queryParams: any[] = []; if (params.fileTypes && params.fileTypes.length > 0) { const placeholders = params.fileTypes.map((type) => { queryParams.push(type); return `$${queryParams.length}`; }); whereClauses.push(`file_type IN (${placeholders.join(', ')})`); } const where = whereClauses.length > 0 ? `WHERE ${whereClauses.join(' AND ')}` : ''; const limitClause = params.limit && params.limit > 0 ? `LIMIT ${Number(params.limit)}` : ''; const { rows } = await query( `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 created_at DESC, id DESC ${limitClause}`, queryParams, ); return rows.map((row) => mapMediaRow(row)); } export async function getMediaMessageById(id: number) { const { rows } = await query( `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 = $1`, [id], ); const row = rows[0]; return row ? mapMediaRow(row) : null; }