@areumtecnologia/wasockets 2.3.1 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,8 +19,14 @@ class MediaObject {
19
19
  this.mimetype = this.mediaNode.mimetype || this._defaultMimetype(this.mediaType)
20
20
  this.fileLength = Number(this.mediaNode.fileLength || 0)
21
21
  this.fileName = this.mediaNode.fileName || ''
22
+ this.caption = this.mediaNode.caption || ''
22
23
  this.seconds = Number(this.mediaNode.seconds || 0)
24
+ this.duration = this.seconds || null
25
+
23
26
  this.isVoice = Boolean(this.mediaNode.ptt)
27
+ this.isPtt = this.isVoice
28
+ this.isGif = Boolean(this.mediaNode.gifPlayback)
29
+ this.isViewOnce = Boolean(this.mediaNode.viewOnce)
24
30
  this.isAnimated = Boolean(this.mediaNode.gifPlayback || this.mediaNode.isAnimated)
25
31
  this.extension = this._inferExtension()
26
32
 
@@ -26,11 +26,13 @@ class MessageContext {
26
26
 
27
27
  const effectiveMessage = editedMsg || rawMessage?.message || null
28
28
 
29
- // 2. Identity and Routing
29
+ // 2. Single-pass message unwrapping (eliminates repeated while-loops)
30
+ const unwrapped = MessageNormalizer.unwrapMessage(effectiveMessage)
31
+
32
+ // 3. Identity and Routing
30
33
  this.id = effectiveKey.id || rawMessage?.key?.id || ''
31
34
  this.chatId = effectiveKey.remoteJid || rawMessage?.key?.remoteJid || ''
32
35
  this.fromMe = Boolean(effectiveKey.fromMe)
33
- this.isFromMe = this.fromMe
34
36
 
35
37
  this.isGroup = JidNormalizer.isGroup(this.chatId)
36
38
  this.isChannel = JidNormalizer.isNewsletter(this.chatId)
@@ -54,10 +56,7 @@ class MessageContext {
54
56
  this.fromPushName = rawMessage?.pushName || JidNormalizer.toPhoneNumber(this.from) || 'Desconhecido'
55
57
  }
56
58
 
57
- this.sender = this.from
58
59
  this.fromNumber = JidNormalizer.toPhoneNumber(this.from)
59
- this.senderNumber = this.fromNumber
60
- this.senderName = this.fromPushName
61
60
 
62
61
  // Timestamps
63
62
  const rawTs = Number(rawMessage?.messageTimestamp || Math.floor(Date.now() / 1000))
@@ -66,25 +65,22 @@ class MessageContext {
66
65
  ? new Date(Number(rawMessage.message.protocolMessage.timestampMs || Date.now()))
67
66
  : null
68
67
 
69
- // 3. Content Decoupling & Typed Parsers
70
- this.type = MessageNormalizer.extractType(effectiveMessage)
71
- this.body = MessageNormalizer.extractBody(effectiveMessage)
72
- this.interactiveReply = MessageNormalizer.extractInteractiveReply(effectiveMessage)
73
- this.contacts = MessageNormalizer.extractContacts(effectiveMessage)
74
- this.location = MessageNormalizer.extractLocation(effectiveMessage)
75
- this.reaction = MessageNormalizer.extractReaction(effectiveMessage)
76
- this.poll = MessageNormalizer.extractPollCreation(effectiveMessage, rawMessage)
77
-
78
- // 4. Media Normalization
79
- this.mediaNode = MessageNormalizer.extractMediaNode(effectiveMessage)
80
- this.hasMedia = Boolean(this.mediaNode)
81
- this.media = this.hasMedia ? new MediaObject(this.mediaNode, this.type) : null
82
- this.mediaDetails = MessageNormalizer.extractMediaDetails(effectiveMessage)
83
-
84
- // 5. Context Info, Mentions & Forwarding
85
- this.contextInfo = MessageNormalizer.extractContextInfo(effectiveMessage)
68
+ // 4. Content Decoupling & Typed Parsers (Single-pass unwrapped nodes)
69
+ this.type = MessageNormalizer.extractType(unwrapped)
70
+ this.body = MessageNormalizer.extractBody(unwrapped)
71
+ this.interactiveReply = MessageNormalizer.extractInteractiveReply(unwrapped)
72
+ this.contacts = MessageNormalizer.extractContacts(unwrapped)
73
+ this.location = MessageNormalizer.extractLocation(unwrapped)
74
+ this.reaction = MessageNormalizer.extractReaction(unwrapped)
75
+ this.poll = MessageNormalizer.extractPollCreation(unwrapped, rawMessage)
76
+
77
+ // 5. Media Normalization (Centralized directly into MediaObject)
78
+ this.mediaNode = MessageNormalizer.extractMediaNode(unwrapped)
79
+ this.media = this.mediaNode ? new MediaObject(this.mediaNode, this.type) : null
80
+
81
+ // 6. Context Info, Mentions & Forwarding
82
+ this.contextInfo = MessageNormalizer.extractContextInfo(unwrapped)
86
83
  this.mentions = this.contextInfo?.mentionedJid || []
87
- this.mentionedJids = this.mentions
88
84
  this.isForwarded = Boolean(this.contextInfo?.isForwarded)
89
85
  this.forwardingScore = Number(this.contextInfo?.forwardingScore || 0)
90
86
 
@@ -94,7 +90,7 @@ class MessageContext {
94
90
  (clientLid && this.mentions.includes(clientLid))
95
91
  )
96
92
 
97
- // 6. Quoted Message Parsing (Recursion with depth limit 1)
93
+ // 7. Quoted Message Parsing (Recursion with depth limit 1)
98
94
  this.isReply = Boolean(this.contextInfo?.quotedMessage)
99
95
  this.quoted = null
100
96
 
@@ -125,6 +121,58 @@ class MessageContext {
125
121
  }
126
122
  }
127
123
 
124
+ // ==========================================
125
+ // Zero-Cost Memory Aliases & Compatibility Getters
126
+ // ==========================================
127
+
128
+ /** Alias for this.fromMe */
129
+ get isFromMe() {
130
+ return this.fromMe
131
+ }
132
+
133
+ /** Alias for this.from */
134
+ get sender() {
135
+ return this.from
136
+ }
137
+
138
+ /** Alias for this.fromNumber */
139
+ get senderNumber() {
140
+ return this.fromNumber
141
+ }
142
+
143
+ /** Alias for this.fromPushName */
144
+ get senderName() {
145
+ return this.fromPushName
146
+ }
147
+
148
+ /** Alias for this.mentions */
149
+ get mentionedJids() {
150
+ return this.mentions
151
+ }
152
+
153
+ /** Boolean check whether message contains media */
154
+ get hasMedia() {
155
+ return Boolean(this.media)
156
+ }
157
+
158
+ /** Backward-compatible media details accessor backed by MediaObject */
159
+ get mediaDetails() {
160
+ if (!this.media) return null
161
+ return {
162
+ mimetype: this.media.mimetype,
163
+ fileName: this.media.fileName,
164
+ caption: this.media.caption,
165
+ duration: this.media.duration,
166
+ isPtt: this.media.isPtt,
167
+ isGif: this.media.isGif,
168
+ isViewOnce: this.media.isViewOnce
169
+ }
170
+ }
171
+
172
+ // ==========================================
173
+ // Context Action Methods
174
+ // ==========================================
175
+
128
176
  /**
129
177
  * Responde citando esta mensagem automaticamente
130
178
  * @param {string|Object} content - Texto ou payload de mensagem
@@ -23,12 +23,13 @@ class EventNormalizer {
23
23
  // Ignore stub or protocol messages if completely empty
24
24
  if (!rawMsg.message && !rawMsg.messageStubType) continue
25
25
 
26
- // Handle protocol revoke messages explicitly
26
+ // Handle protocol revoke messages explicitly (delete for everyone)
27
27
  const isRevoke = rawMsg.message?.protocolMessage?.type === 0
28
28
  if (isRevoke) {
29
29
  client.emit(Events.MESSAGE_DELETE, {
30
30
  keys: [rawMsg.message.protocolMessage.key || rawMsg.key]
31
31
  })
32
+ continue // Do not emit as a new received/sent message
32
33
  }
33
34
 
34
35
  const ctx = new MessageContext(client, rawMsg)
@@ -58,8 +58,13 @@ export declare class MediaObject {
58
58
  mimetype: string
59
59
  fileLength: number
60
60
  fileName: string
61
+ caption: string
61
62
  seconds: number
63
+ duration: number | null
62
64
  isVoice: boolean
65
+ isPtt: boolean
66
+ isGif: boolean
67
+ isViewOnce: boolean
63
68
  isAnimated: boolean
64
69
  extension: string
65
70
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@areumtecnologia/wasockets",
3
- "version": "2.3.1",
3
+ "version": "2.3.2",
4
4
  "whatsappVersion": "2.3000.1053049953",
5
5
  "description": "Communication Library By areumtecnologia",
6
6
  "keywords": [],