Repository navigation
fix(baileys): do not resend deleted messages on retry receipts #2751
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -656,6 +656,16 @@ export class BaileysStartupService extends ChannelStartupService { | |
| if (full) { | ||
| return webMessageInfo[0]; | ||
| } | ||
|
|
||
| // Baileys answers retry receipts with whatever getMessage returns. A message revoked with | ||
| // "delete for everyone" keeps its content in the Message table, so returning it here makes | ||
| // the deleted text reappear for the members whose devices ask for a retry. | ||
| if (await this.isMessageDeleted(key.id, webMessageInfo[0])) { | ||
| this.logger.verbose(`getMessage: message ${key.id} was deleted, skipping retry resend`); | ||
|
|
||
| return undefined; | ||
| } | ||
|
|
||
| if (webMessageInfo[0].message?.pollCreationMessage) { | ||
| const messageSecretBase64 = webMessageInfo[0].message?.messageContextInfo?.messageSecret; | ||
|
|
||
|
|
@@ -677,6 +687,27 @@ export class BaileysStartupService extends ChannelStartupService { | |
| } | ||
| } | ||
|
|
||
| // deleteMessage marks the row (status/key.deleted); both it and the messages.update revoke record a | ||
| // 'DELETED' MessageUpdate. The row lookup in deleteMessage is not scoped to the instance, so in a group | ||
| // shared by several instances the mark can land on another instance's copy; matching the MessageUpdate | ||
| // by instance + key id still finds it. | ||
| private async isMessageDeleted(keyId: string, row: any): Promise<boolean> { | ||
| if (!row) { | ||
| return false; | ||
| } | ||
|
|
||
| if (row.status === 'DELETED' || row.key?.deleted === true) { | ||
| return true; | ||
| } | ||
|
|
||
| const deletion = await this.prismaRepository.messageUpdate.findFirst({ | ||
| where: { instanceId: this.instanceId, keyId, status: 'DELETED' }, | ||
| select: { id: true }, | ||
| }); | ||
|
Comment on lines
+703
to
+706
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Medium · Deletion checks scan update history When an instance has accumulated many Add an index that supports the deletion lookup’s filter fields. Prompt for AI agentsIn `src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts` at lines 703-706:
**Deletion checks scan update history**
When an instance has accumulated many `MessageUpdate` rows, the lookup filters by `instanceId`, `keyId`, and `status` without a matching index, so retry checks scan the instance’s update rows and add increasing database work.
Add an index that supports the deletion lookup’s filter fields. |
||
|
|
||
| return !!deletion; | ||
| } | ||
|
|
||
| private async defineAuthState() { | ||
| const db = this.configService.get<Database>('DATABASE'); | ||
| const cache = this.configService.get<CacheConf>('CACHE'); | ||
|
|
@@ -1889,8 +1920,9 @@ export class BaileysStartupService extends ChannelStartupService { | |
| if (update.message === null && update.status === undefined) { | ||
| this.sendDataWebhook(Events.MESSAGES_DELETE, { ...key, status: 'DELETED' }); | ||
|
|
||
| // Recorded as DELETED (not the SERVER_ACK fallback) so getMessage can refuse to resend it. | ||
| if (this.configService.get<Database>('DATABASE').SAVE_DATA.MESSAGE_UPDATE) | ||
| await this.prismaRepository.messageUpdate.create({ data: message }); | ||
| await this.prismaRepository.messageUpdate.create({ data: { ...message, status: 'DELETED' } }); | ||
|
|
||
| if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) { | ||
| this.chatwootService.eventWhatsapp( | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟠 High · Another instance’s message is deleted
When a shared-group deletion selects a different instance’s copy,
deleteMessagemarks the wrong instance’s row, leaving the requesting instance’s row live. Its deletion marker is absent or is later removed with the other row, soisMessageDeletedfinds no deletion and a retry returns the content.Scope the
deleteMessagelookup to the current instance so it marks that instance’s message row.Also at
src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts:1893-1925.Prompt for AI agents