Merge pull request #2025 from guispiller/main
Some checks failed
Check Code Quality / check-lint-and-build (push) Has been cancelled
Build Docker image / Build and Deploy (push) Has been cancelled
Security Scan / CodeQL Analysis (javascript) (push) Has been cancelled
Security Scan / Dependency Review (push) Has been cancelled

feat: convert LID to phoneNumber on GROUP_PARTICIPANTS_UPDATE webhook
This commit is contained in:
Davidson Gomes 2025-10-09 15:05:41 -03:00 committed by GitHub
commit 0976109d27
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -504,8 +504,8 @@ export class BaileysStartupService extends ChannelStartupService {
try { try {
// Use raw SQL to avoid JSON path issues // Use raw SQL to avoid JSON path issues
const webMessageInfo = (await this.prismaRepository.$queryRaw` const webMessageInfo = (await this.prismaRepository.$queryRaw`
SELECT * FROM "Message" SELECT * FROM "Message"
WHERE "instanceId" = ${this.instanceId} WHERE "instanceId" = ${this.instanceId}
AND "key"->>'id' = ${key.id} AND "key"->>'id' = ${key.id}
`) as proto.IWebMessageInfo[]; `) as proto.IWebMessageInfo[];
@ -1505,8 +1505,8 @@ export class BaileysStartupService extends ChannelStartupService {
if (configDatabaseData.HISTORIC || configDatabaseData.NEW_MESSAGE) { if (configDatabaseData.HISTORIC || configDatabaseData.NEW_MESSAGE) {
// Use raw SQL to avoid JSON path issues // Use raw SQL to avoid JSON path issues
const messages = (await this.prismaRepository.$queryRaw` const messages = (await this.prismaRepository.$queryRaw`
SELECT * FROM "Message" SELECT * FROM "Message"
WHERE "instanceId" = ${this.instanceId} WHERE "instanceId" = ${this.instanceId}
AND "key"->>'id' = ${key.id} AND "key"->>'id' = ${key.id}
LIMIT 1 LIMIT 1
`) as any[]; `) as any[];
@ -1623,12 +1623,66 @@ export class BaileysStartupService extends ChannelStartupService {
}); });
}, },
'group-participants.update': (participantsUpdate: { 'group-participants.update': async (participantsUpdate: {
id: string; id: string;
participants: string[]; participants: string[];
action: ParticipantAction; action: ParticipantAction;
}) => { }) => {
this.sendDataWebhook(Events.GROUP_PARTICIPANTS_UPDATE, participantsUpdate); // ENHANCEMENT: Adds participantsData field while maintaining backward compatibility
// MAINTAINS: participants: string[] (original JID strings)
// ADDS: participantsData: { jid: string, phoneNumber: string, name?: string, imgUrl?: string }[]
// This enables LID to phoneNumber conversion without breaking existing webhook consumers
// Helper to normalize participantId as phone number
const normalizePhoneNumber = (id: string): string => {
// Remove @lid, @s.whatsapp.net suffixes and extract just the number part
return id.split('@')[0];
};
try {
// Usa o mesmo método que o endpoint /group/participants
const groupParticipants = await this.findParticipants({ groupJid: participantsUpdate.id });
// Validação para garantir que temos dados válidos
if (!groupParticipants?.participants || !Array.isArray(groupParticipants.participants)) {
throw new Error('Invalid participant data received from findParticipants');
}
// Filtra apenas os participantes que estão no evento
const resolvedParticipants = participantsUpdate.participants.map((participantId) => {
const participantData = groupParticipants.participants.find((p) => p.id === participantId);
let phoneNumber: string;
if (participantData?.phoneNumber) {
phoneNumber = participantData.phoneNumber;
} else {
phoneNumber = normalizePhoneNumber(participantId);
}
return {
jid: participantId,
phoneNumber,
name: participantData?.name,
imgUrl: participantData?.imgUrl,
};
});
// Mantém formato original + adiciona dados resolvidos
const enhancedParticipantsUpdate = {
...participantsUpdate,
participants: participantsUpdate.participants, // Mantém array original de strings
// Adiciona dados resolvidos em campo separado
participantsData: resolvedParticipants,
};
this.sendDataWebhook(Events.GROUP_PARTICIPANTS_UPDATE, enhancedParticipantsUpdate);
} catch (error) {
this.logger.error(
`Failed to resolve participant data for GROUP_PARTICIPANTS_UPDATE webhook: ${error.message} | Group: ${participantsUpdate.id} | Participants: ${participantsUpdate.participants.length}`,
);
// Fallback - envia sem conversão
this.sendDataWebhook(Events.GROUP_PARTICIPANTS_UPDATE, participantsUpdate);
}
this.updateGroupMetadataCache(participantsUpdate.id); this.updateGroupMetadataCache(participantsUpdate.id);
}, },
@ -4493,7 +4547,7 @@ export class BaileysStartupService extends ChannelStartupService {
// Use raw SQL to avoid JSON path issues // Use raw SQL to avoid JSON path issues
const result = await this.prismaRepository.$executeRaw` const result = await this.prismaRepository.$executeRaw`
UPDATE "Message" UPDATE "Message"
SET "status" = ${status[4]} SET "status" = ${status[4]}
WHERE "instanceId" = ${this.instanceId} WHERE "instanceId" = ${this.instanceId}
AND "key"->>'remoteJid' = ${remoteJid} AND "key"->>'remoteJid' = ${remoteJid}
@ -4518,7 +4572,7 @@ export class BaileysStartupService extends ChannelStartupService {
this.prismaRepository.chat.findFirst({ where: { remoteJid } }), this.prismaRepository.chat.findFirst({ where: { remoteJid } }),
// Use raw SQL to avoid JSON path issues // Use raw SQL to avoid JSON path issues
this.prismaRepository.$queryRaw` this.prismaRepository.$queryRaw`
SELECT COUNT(*)::int as count FROM "Message" SELECT COUNT(*)::int as count FROM "Message"
WHERE "instanceId" = ${this.instanceId} WHERE "instanceId" = ${this.instanceId}
AND "key"->>'remoteJid' = ${remoteJid} AND "key"->>'remoteJid' = ${remoteJid}
AND ("key"->>'fromMe')::boolean = false AND ("key"->>'fromMe')::boolean = false