Files
InfiniteAPI/src/Types/Chat.ts
T
Paulo Victor Lund ae0cb89714 Session recreation and improved message retry (#1735)
* Add message retry manager for session recreation and caching

Introduces a MessageRetryManager to cache recent sent messages and manage automatic Signal session recreation for failed message retries. Adds new config options to enable these features, integrates retry manager into message send/receive logic, and provides periodic cache cleanup. Improves reliability of message delivery and retry handling.

* Add buffer timeout and cache limit to event-buffer

Introduces a buffer timeout to auto-flush events after 30 seconds and limits the history cache size to prevent memory bloat in event-buffer.ts.

* Add session validation to SignalRepository

Introduces a validateSession method to SignalRepository for checking session existence and state. Updates message retry logic to use the new validation, improving session recreation handling and retry management.

* Improve message retry management and tracking

Refactored message retry manager to use LRU caches for recent messages and session history, added retry counters and statistics tracking, and implemented phone request scheduling. Updated message receive and send logic to mark retry success and pass max retry count. Removed periodic cleanup logic in favor of cache TTLs for better resource management.

* lint fix

* Use validateSession for session checks in message send

Replaces direct session existence checks with the improved validateSession method, which also checks for session staleness. Adds debug logging for failed session validations to aid troubleshooting.

* Delete src/Utils/message-retry.ts

---------

Co-authored-by: Rajeh Taher <rajeh@reforward.dev>
2025-09-07 20:20:51 +03:00

139 lines
4.0 KiB
TypeScript

import type { proto } from '../../WAProto/index.js'
import type { AccountSettings } from './Auth'
import type { QuickReplyAction } from './Bussines.js'
import type { BufferedEventData } from './Events'
import type { LabelActionBody } from './Label'
import type { ChatLabelAssociationActionBody } from './LabelAssociation'
import type { MessageLabelAssociationActionBody } from './LabelAssociation'
import type { MinimalMessage, WAMessageKey } from './Message'
/** privacy settings in WhatsApp Web */
export type WAPrivacyValue = 'all' | 'contacts' | 'contact_blacklist' | 'none'
export type WAPrivacyOnlineValue = 'all' | 'match_last_seen'
export type WAPrivacyGroupAddValue = 'all' | 'contacts' | 'contact_blacklist'
export type WAReadReceiptsValue = 'all' | 'none'
export type WAPrivacyCallValue = 'all' | 'known'
export type WAPrivacyMessagesValue = 'all' | 'contacts'
/** set of statuses visible to other people; see updatePresence() in WhatsAppWeb.Send */
export type WAPresence = 'unavailable' | 'available' | 'composing' | 'recording' | 'paused'
export const ALL_WA_PATCH_NAMES = [
'critical_block',
'critical_unblock_low',
'regular_high',
'regular_low',
'regular'
] as const
export type WAPatchName = (typeof ALL_WA_PATCH_NAMES)[number]
export interface PresenceData {
lastKnownPresence: WAPresence
lastSeen?: number
}
export type BotListInfo = {
jid: string
personaId: string
}
export type ChatMutation = {
syncAction: proto.ISyncActionData
index: string[]
}
export type WAPatchCreate = {
syncAction: proto.ISyncActionValue
index: string[]
type: WAPatchName
apiVersion: number
operation: proto.SyncdMutation.SyncdOperation
}
export type Chat = proto.IConversation & {
/** unix timestamp of when the last message was received in the chat */
lastMessageRecvTimestamp?: number
}
export type ChatUpdate = Partial<
Chat & {
/**
* if specified in the update,
* the EV buffer will check if the condition gets fulfilled before applying the update
* Right now, used to determine when to release an app state sync event
*
* @returns true, if the update should be applied;
* false if it can be discarded;
* undefined if the condition is not yet fulfilled
* */
conditional: (bufferedData: BufferedEventData) => boolean | undefined
/** last update time */
timestamp?: number
}
>
/**
* the last messages in a chat, sorted reverse-chronologically. That is, the latest message should be first in the chat
* for MD modifications, the last message in the array (i.e. the earlist message) must be the last message recv in the chat
* */
export type LastMessageList = MinimalMessage[] | proto.SyncActionValue.ISyncActionMessageRange
export type ChatModification =
| {
archive: boolean
lastMessages: LastMessageList
}
| { pushNameSetting: string }
| { pin: boolean }
| {
/** mute for duration, or provide timestamp of mute to remove*/
mute: number | null
}
| {
clear: boolean
lastMessages: LastMessageList
}
| {
deleteForMe: { deleteMedia: boolean; key: WAMessageKey; timestamp: number }
}
| {
star: {
messages: { id: string; fromMe?: boolean }[]
star: boolean
}
}
| {
markRead: boolean
lastMessages: LastMessageList
}
| { delete: true; lastMessages: LastMessageList }
| { contact: proto.SyncActionValue.IContactAction | null }
| { disableLinkPreviews: proto.SyncActionValue.IPrivacySettingDisableLinkPreviewsAction }
// Label
| { addLabel: LabelActionBody }
// Label assosiation
| { addChatLabel: ChatLabelAssociationActionBody }
| { removeChatLabel: ChatLabelAssociationActionBody }
| { addMessageLabel: MessageLabelAssociationActionBody }
| { removeMessageLabel: MessageLabelAssociationActionBody }
| { quickReply: QuickReplyAction }
export type InitialReceivedChatsState = {
[jid: string]: {
/** the last message received from the other party */
lastMsgRecvTimestamp?: number
/** the absolute last message in the chat */
lastMsgTimestamp: number
}
}
export type InitialAppStateSyncOptions = {
accountSettings: AccountSettings
}