Feat: Sincronizar contactos y grupos, mejorar nombres en MCP
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m8s
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m8s
- Agregar listeners contacts.upsert y contacts.update - Agregar listeners groups.upsert y groups.update - Guardar contactos del historial en messaging-history.set - Modificar MCP para hacer JOIN con contacts y group_metadata - Ahora los chats muestran nombres reales en lugar de números/IDs
This commit is contained in:
@@ -407,6 +407,121 @@ class BaileysManager extends EventEmitter {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Contacts upsert - save/update contacts
|
||||||
|
socket.ev.on('contacts.upsert', async (contacts) => {
|
||||||
|
console.log(`[BaileysManager] contacts.upsert: ${contacts.length} contacts`)
|
||||||
|
for (const contact of contacts) {
|
||||||
|
try {
|
||||||
|
await query(
|
||||||
|
`INSERT INTO contacts (instance_id, jid, name, push_name)
|
||||||
|
VALUES ($1, $2, $3, $4)
|
||||||
|
ON CONFLICT (instance_id, jid) DO UPDATE SET
|
||||||
|
name = COALESCE(NULLIF(EXCLUDED.name, ''), contacts.name),
|
||||||
|
push_name = COALESCE(NULLIF(EXCLUDED.push_name, ''), contacts.push_name),
|
||||||
|
updated_at = NOW()`,
|
||||||
|
[instanceId, contact.id, contact.name || null, contact.notify || null]
|
||||||
|
)
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`[BaileysManager] Error saving contact:`, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Contacts update - partial updates
|
||||||
|
socket.ev.on('contacts.update', async (updates) => {
|
||||||
|
console.log(`[BaileysManager] contacts.update: ${updates.length} updates`)
|
||||||
|
for (const update of updates) {
|
||||||
|
try {
|
||||||
|
const fields: string[] = []
|
||||||
|
const values: any[] = [instanceId, update.id]
|
||||||
|
let paramIndex = 3
|
||||||
|
|
||||||
|
if (update.name !== undefined) {
|
||||||
|
fields.push(`name = $${paramIndex}`)
|
||||||
|
values.push(update.name)
|
||||||
|
paramIndex++
|
||||||
|
}
|
||||||
|
if (update.notify !== undefined) {
|
||||||
|
fields.push(`push_name = $${paramIndex}`)
|
||||||
|
values.push(update.notify)
|
||||||
|
paramIndex++
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields.length > 0) {
|
||||||
|
fields.push('updated_at = NOW()')
|
||||||
|
await query(
|
||||||
|
`UPDATE contacts SET ${fields.join(', ')} WHERE instance_id = $1 AND jid = $2`,
|
||||||
|
values
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`[BaileysManager] Error updating contact:`, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Groups upsert - save/update group metadata
|
||||||
|
socket.ev.on('groups.upsert', async (groups) => {
|
||||||
|
console.log(`[BaileysManager] groups.upsert: ${groups.length} groups`)
|
||||||
|
for (const group of groups) {
|
||||||
|
try {
|
||||||
|
await query(
|
||||||
|
`INSERT INTO group_metadata (instance_id, jid, subject, description, owner_jid, participants)
|
||||||
|
VALUES ($1, $2, $3, $4, $5, $6)
|
||||||
|
ON CONFLICT (instance_id, jid) DO UPDATE SET
|
||||||
|
subject = COALESCE(NULLIF(EXCLUDED.subject, ''), group_metadata.subject),
|
||||||
|
description = COALESCE(EXCLUDED.description, group_metadata.description),
|
||||||
|
owner_jid = COALESCE(EXCLUDED.owner_jid, group_metadata.owner_jid),
|
||||||
|
participants = COALESCE(EXCLUDED.participants, group_metadata.participants),
|
||||||
|
updated_at = NOW()`,
|
||||||
|
[
|
||||||
|
instanceId,
|
||||||
|
group.id,
|
||||||
|
group.subject || null,
|
||||||
|
group.desc || null,
|
||||||
|
group.owner || null,
|
||||||
|
JSON.stringify(group.participants || [])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`[BaileysManager] Error saving group:`, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Groups update - partial updates
|
||||||
|
socket.ev.on('groups.update', async (updates) => {
|
||||||
|
console.log(`[BaileysManager] groups.update: ${updates.length} updates`)
|
||||||
|
for (const update of updates) {
|
||||||
|
try {
|
||||||
|
const fields: string[] = []
|
||||||
|
const values: any[] = [instanceId, update.id]
|
||||||
|
let paramIndex = 3
|
||||||
|
|
||||||
|
if (update.subject !== undefined) {
|
||||||
|
fields.push(`subject = $${paramIndex}`)
|
||||||
|
values.push(update.subject)
|
||||||
|
paramIndex++
|
||||||
|
}
|
||||||
|
if (update.desc !== undefined) {
|
||||||
|
fields.push(`description = $${paramIndex}`)
|
||||||
|
values.push(update.desc)
|
||||||
|
paramIndex++
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields.length > 0) {
|
||||||
|
fields.push('updated_at = NOW()')
|
||||||
|
await query(
|
||||||
|
`UPDATE group_metadata SET ${fields.join(', ')} WHERE instance_id = $1 AND jid = $2`,
|
||||||
|
values
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`[BaileysManager] Error updating group:`, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// Message reactions
|
// Message reactions
|
||||||
socket.ev.on('messages.reaction', async (reactions) => {
|
socket.ev.on('messages.reaction', async (reactions) => {
|
||||||
for (const reaction of reactions) {
|
for (const reaction of reactions) {
|
||||||
@@ -467,6 +582,26 @@ class BaileysManager extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save contacts from history
|
||||||
|
if (contacts?.length) {
|
||||||
|
console.log(`[BaileysManager] Saving ${contacts.length} contacts from history`)
|
||||||
|
for (const contact of contacts) {
|
||||||
|
try {
|
||||||
|
await query(
|
||||||
|
`INSERT INTO contacts (instance_id, jid, name, push_name)
|
||||||
|
VALUES ($1, $2, $3, $4)
|
||||||
|
ON CONFLICT (instance_id, jid) DO UPDATE SET
|
||||||
|
name = COALESCE(NULLIF(EXCLUDED.name, ''), contacts.name),
|
||||||
|
push_name = COALESCE(NULLIF(EXCLUDED.push_name, ''), contacts.push_name),
|
||||||
|
updated_at = NOW()`,
|
||||||
|
[instanceId, contact.id, contact.name || null, contact.notify || null]
|
||||||
|
)
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`[BaileysManager] Error saving contact from history:`, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Save messages
|
// Save messages
|
||||||
if (messages?.length) {
|
if (messages?.length) {
|
||||||
for (const msg of messages) {
|
for (const msg of messages) {
|
||||||
|
|||||||
@@ -687,10 +687,17 @@ export async function handleToolCall(toolName: string, args: Record<string, any>
|
|||||||
}
|
}
|
||||||
|
|
||||||
const result = await query(
|
const result = await query(
|
||||||
`SELECT id, jid, name, is_group, unread_count, last_message_at, last_message_type
|
`SELECT
|
||||||
FROM chats
|
c.id, c.jid, c.is_group, c.unread_count, c.last_message_at, c.last_message_type,
|
||||||
WHERE instance_id = $1
|
CASE
|
||||||
ORDER BY last_message_at DESC NULLS LAST
|
WHEN c.is_group THEN COALESCE(gm.subject, c.name, c.jid)
|
||||||
|
ELSE COALESCE(ct.name, ct.push_name, c.name, SPLIT_PART(c.jid, '@', 1))
|
||||||
|
END as name
|
||||||
|
FROM chats c
|
||||||
|
LEFT JOIN contacts ct ON c.instance_id = ct.instance_id AND c.jid = ct.jid
|
||||||
|
LEFT JOIN group_metadata gm ON c.instance_id = gm.instance_id AND c.jid = gm.jid
|
||||||
|
WHERE c.instance_id = $1
|
||||||
|
ORDER BY c.last_message_at DESC NULLS LAST
|
||||||
LIMIT $2`,
|
LIMIT $2`,
|
||||||
[instanceId, Math.min(limit, 100)]
|
[instanceId, Math.min(limit, 100)]
|
||||||
)
|
)
|
||||||
@@ -717,9 +724,17 @@ export async function handleToolCall(toolName: string, args: Record<string, any>
|
|||||||
}
|
}
|
||||||
|
|
||||||
const result = await query(
|
const result = await query(
|
||||||
`SELECT id, jid, name, is_group, unread_count, last_message_at, last_message_type
|
`SELECT
|
||||||
FROM chats
|
c.id, c.jid, c.is_group, c.unread_count, c.last_message_at, c.last_message_type,
|
||||||
WHERE id = $1 AND instance_id = $2`,
|
CASE
|
||||||
|
WHEN c.is_group THEN COALESCE(gm.subject, c.name, c.jid)
|
||||||
|
ELSE COALESCE(ct.name, ct.push_name, c.name, SPLIT_PART(c.jid, '@', 1))
|
||||||
|
END as name,
|
||||||
|
gm.participants as group_participants
|
||||||
|
FROM chats c
|
||||||
|
LEFT JOIN contacts ct ON c.instance_id = ct.instance_id AND c.jid = ct.jid
|
||||||
|
LEFT JOIN group_metadata gm ON c.instance_id = gm.instance_id AND c.jid = gm.jid
|
||||||
|
WHERE c.id = $1 AND c.instance_id = $2`,
|
||||||
[chatId, instanceId]
|
[chatId, instanceId]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -728,9 +743,7 @@ export async function handleToolCall(toolName: string, args: Record<string, any>
|
|||||||
}
|
}
|
||||||
|
|
||||||
const chat = result.rows[0]
|
const chat = result.rows[0]
|
||||||
return mcpSuccess({
|
const response: any = {
|
||||||
ok: true,
|
|
||||||
chat: {
|
|
||||||
id: chat.id,
|
id: chat.id,
|
||||||
jid: chat.jid,
|
jid: chat.jid,
|
||||||
name: chat.name,
|
name: chat.name,
|
||||||
@@ -739,6 +752,15 @@ export async function handleToolCall(toolName: string, args: Record<string, any>
|
|||||||
lastMessageAt: chat.last_message_at,
|
lastMessageAt: chat.last_message_at,
|
||||||
lastMessageType: chat.last_message_type
|
lastMessageType: chat.last_message_type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Include participants for groups
|
||||||
|
if (chat.is_group && chat.group_participants) {
|
||||||
|
response.participants = chat.group_participants
|
||||||
|
}
|
||||||
|
|
||||||
|
return mcpSuccess({
|
||||||
|
ok: true,
|
||||||
|
chat: response
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -750,11 +772,18 @@ export async function handleToolCall(toolName: string, args: Record<string, any>
|
|||||||
}
|
}
|
||||||
|
|
||||||
const result = await query(
|
const result = await query(
|
||||||
`SELECT id, jid, name, is_group, unread_count, last_message_at
|
`SELECT
|
||||||
FROM chats
|
c.id, c.jid, c.is_group, c.unread_count, c.last_message_at,
|
||||||
WHERE instance_id = $1
|
CASE
|
||||||
AND (name ILIKE $2 OR jid ILIKE $2)
|
WHEN c.is_group THEN COALESCE(gm.subject, c.name, c.jid)
|
||||||
ORDER BY last_message_at DESC NULLS LAST
|
ELSE COALESCE(ct.name, ct.push_name, c.name, SPLIT_PART(c.jid, '@', 1))
|
||||||
|
END as name
|
||||||
|
FROM chats c
|
||||||
|
LEFT JOIN contacts ct ON c.instance_id = ct.instance_id AND c.jid = ct.jid
|
||||||
|
LEFT JOIN group_metadata gm ON c.instance_id = gm.instance_id AND c.jid = gm.jid
|
||||||
|
WHERE c.instance_id = $1
|
||||||
|
AND (c.name ILIKE $2 OR c.jid ILIKE $2 OR ct.name ILIKE $2 OR ct.push_name ILIKE $2 OR gm.subject ILIKE $2)
|
||||||
|
ORDER BY c.last_message_at DESC NULLS LAST
|
||||||
LIMIT $3`,
|
LIMIT $3`,
|
||||||
[instanceId, `%${searchQuery}%`, Math.min(limit, 50)]
|
[instanceId, `%${searchQuery}%`, Math.min(limit, 50)]
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user