Files
mcp-vultr/services/loggingService.js

128 lines
4.7 KiB
JavaScript

const db = require('../db_config');
class LoggingService {
async logMessage(source, target, content, direction, hasMedia = false, status = 'SENT', errorLog = null) {
try {
console.log(`[LoggingService] Logging ${direction} message from ${source} to ${target}`);
const query = `
INSERT INTO messages_log (source_number, target_number, message_content, direction, has_media, status, error_log)
VALUES (?, ?, ?, ?, ?, ?, ?)
`;
const params = [source, target, content, direction, hasMedia, status, errorLog];
await db.execute(query, params);
} catch (error) {
console.error('[LoggingService] Failed to log message:', error);
}
}
async saveContact(phone, name, savedName, isMyContact) {
try {
const query = `
INSERT INTO contacts (phone, name, saved_name, is_my_contact)
VALUES (?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
name = VALUES(name),
saved_name = VALUES(saved_name),
is_my_contact = VALUES(is_my_contact),
updated_at = CURRENT_TIMESTAMP
`;
await db.execute(query, [phone, name, savedName, isMyContact]);
} catch (error) {
console.error('[LoggingService] Failed to save contact:', error);
}
}
async getMessages(fromFilter = null, limit = 100) {
try {
let query = `
SELECT m.*, c.name, c.saved_name
FROM messages_log m
LEFT JOIN contacts c ON m.source_number = c.phone
`;
const params = [];
if (fromFilter) {
// Optimization: Remove leading % effectively uses the index.
// Assuming user searches "852..." or full number.
// If they search "52", it won't match "0852", which is acceptable for performance.
query += " WHERE m.source_number LIKE ? ";
params.push(`${fromFilter}%`);
}
query += " ORDER BY m.timestamp DESC LIMIT ?";
params.push(limit);
const [rows] = await db.execute(query, params);
return rows;
} catch (error) {
console.error('[LoggingService] Failed to get messages:', error);
throw error;
}
}
async queueMessage(target, message) {
try {
const query = `INSERT INTO message_queue (target_number, message) VALUES (?, ?)`;
const [result] = await db.execute(query, [target, message]);
return result.insertId;
} catch (error) {
console.error('[LoggingService] Failed to queue message:', error);
throw error;
}
}
async getPendingQueue() {
try {
const [rows] = await db.execute("SELECT * FROM message_queue WHERE status = 'pending' ORDER BY id ASC LIMIT 1");
return rows[0];
} catch (error) {
console.error('[LoggingService] Failed to get pending queue:', error);
return null;
}
}
async updateQueueStatus(id, status) {
try {
await db.execute("UPDATE message_queue SET status = ? WHERE id = ?", [status, id]);
} catch (error) {
console.error('[LoggingService] Failed to update queue:', error);
}
}
async getQueue() {
try {
const [rows] = await db.execute("SELECT * FROM message_queue ORDER BY id DESC LIMIT 100");
return rows;
} catch (error) {
console.error('[LoggingService] Failed to get queue:', error);
throw error;
}
}
// New Method for Contextual Chat History
async getConversationHistory(userPhone, botPhone, limit = 10) {
try {
// Get last N messages between user and bot
const query = `
SELECT source_number, message_content, direction, timestamp
FROM messages_log
WHERE (source_number = ? AND target_number = ?)
OR (source_number = ? AND target_number = ?)
ORDER BY timestamp DESC LIMIT ?
`;
const [rows] = await db.execute(query, [userPhone, botPhone, botPhone, userPhone, limit]);
// Return reversed (oldest first) for proper context flow
return rows.reverse().map(r => ({
role: r.source_number === userPhone ? 'user' : 'model',
message: r.message_content
}));
} catch (error) {
console.error('[LoggingService] Failed to get history:', error);
return []; // Fail gracefully with empty history
}
}
}
module.exports = new LoggingService();