118 lines
3.4 KiB
TypeScript
118 lines
3.4 KiB
TypeScript
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<string, unknown> = {};
|
|
|
|
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<MediaRow>(
|
|
`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<MediaRow>(
|
|
`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;
|
|
}
|
|
|