@areumtecnologia/wasockets 2.2.3 → 2.3.1
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.
- package/README.md +98 -25
- package/lib/Client/Builders/Buttons.js +127 -0
- package/lib/Client/Builders/EventBuilder.js +122 -0
- package/lib/Client/Builders/InteractiveMessage.js +150 -0
- package/lib/Client/Builders/Lists.js +78 -0
- package/lib/Client/Builders/PollBuilder.js +84 -0
- package/lib/Client/Builders/index.js +21 -0
- package/lib/Client/Constants.js +54 -0
- package/lib/Client/Context/CallContext.js +96 -0
- package/lib/Client/Context/MediaObject.js +155 -0
- package/lib/Client/Context/MessageContext.js +213 -0
- package/lib/Client/Modules/BusinessManager.js +155 -0
- package/lib/Client/Modules/ChannelManager.js +144 -0
- package/lib/Client/Modules/ChatManager.js +113 -0
- package/lib/Client/Modules/CommunityManager.js +136 -0
- package/lib/Client/Modules/GroupManager.js +194 -0
- package/lib/Client/Modules/LabelManager.js +123 -0
- package/lib/Client/Modules/MessageManager.js +198 -0
- package/lib/Client/Modules/PresenceManager.js +68 -0
- package/lib/Client/Modules/PrivacyManager.js +98 -0
- package/lib/Client/Modules/ProfileManager.js +92 -0
- package/lib/Client/Modules/UserManager.js +92 -0
- package/lib/Client/Modules/VoipManager.js +117 -0
- package/lib/Client/Modules/index.js +29 -0
- package/lib/Client/Normalizers/EventNormalizer.js +99 -0
- package/lib/Client/Normalizers/JidNormalizer.js +96 -0
- package/lib/Client/Normalizers/MessageNormalizer.js +422 -0
- package/lib/Client/WaClient.js +438 -0
- package/lib/Client/index.d.ts +547 -0
- package/lib/Client/index.js +76 -0
- package/package.json +29 -23
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
|
+
|
|
5
|
+
const { JidNormalizer } = require("../Normalizers/JidNormalizer")
|
|
6
|
+
|
|
7
|
+
class ProfileManager {
|
|
8
|
+
/**
|
|
9
|
+
* @param {import('../WaClient').WaClient} client
|
|
10
|
+
*/
|
|
11
|
+
constructor(client) {
|
|
12
|
+
this.client = client
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
_getSock() {
|
|
16
|
+
if (!this.client.sock) {
|
|
17
|
+
throw new Error('Socket is not connected.')
|
|
18
|
+
}
|
|
19
|
+
return this.client.sock
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Atualiza o nome de exibição (pushName) do bot
|
|
24
|
+
* @param {string} name
|
|
25
|
+
*/
|
|
26
|
+
async updateName(name) {
|
|
27
|
+
const sock = this._getSock()
|
|
28
|
+
return sock.updateProfileName(name)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Atualiza o recado / status de texto da conta
|
|
33
|
+
* @param {string} aboutText
|
|
34
|
+
*/
|
|
35
|
+
async updateAbout(aboutText) {
|
|
36
|
+
const sock = this._getSock()
|
|
37
|
+
return sock.updateProfileStatus(aboutText)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Obtém o recado de um contato ou da própria conta
|
|
42
|
+
* @param {string} [jid]
|
|
43
|
+
*/
|
|
44
|
+
async getAbout(jid) {
|
|
45
|
+
const sock = this._getSock()
|
|
46
|
+
const targetJid = jid ? JidNormalizer.toJid(jid) : sock.user?.id
|
|
47
|
+
return sock.fetchStatus(targetJid)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Atualiza a foto de perfil da conta ou de um grupo
|
|
52
|
+
* @param {string} jidOrSelf - 'me' ou JID
|
|
53
|
+
* @param {string|Buffer|Object} imageSource
|
|
54
|
+
*/
|
|
55
|
+
async updatePicture(jidOrSelf, imageSource) {
|
|
56
|
+
const sock = this._getSock()
|
|
57
|
+
const isSelf = !jidOrSelf || jidOrSelf === 'me'
|
|
58
|
+
const targetJid = isSelf ? sock.user?.id : JidNormalizer.toJid(jidOrSelf)
|
|
59
|
+
const content = typeof imageSource === 'string' ? { url: imageSource } : imageSource
|
|
60
|
+
return sock.updateProfilePicture(targetJid, content)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Remove a foto de perfil
|
|
65
|
+
* @param {string} [jidOrSelf]
|
|
66
|
+
*/
|
|
67
|
+
async removePicture(jidOrSelf) {
|
|
68
|
+
const sock = this._getSock()
|
|
69
|
+
const isSelf = !jidOrSelf || jidOrSelf === 'me'
|
|
70
|
+
const targetJid = isSelf ? sock.user?.id : JidNormalizer.toJid(jidOrSelf)
|
|
71
|
+
return sock.removeProfilePicture(targetJid)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Obtém a URL da foto de perfil
|
|
76
|
+
* @param {string} jid
|
|
77
|
+
* @param {boolean} [highRes=true] - Se true, busca imagem em alta resolução
|
|
78
|
+
* @returns {Promise<string|null>}
|
|
79
|
+
*/
|
|
80
|
+
async getPictureUrl(jid, highRes = true) {
|
|
81
|
+
const sock = this._getSock()
|
|
82
|
+
const targetJid = JidNormalizer.toJid(jid)
|
|
83
|
+
try {
|
|
84
|
+
return await sock.profilePictureUrl(targetJid, highRes ? 'image' : 'preview')
|
|
85
|
+
} catch {
|
|
86
|
+
return null
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
exports.ProfileManager = ProfileManager
|
|
92
|
+
exports.default = ProfileManager
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
|
+
|
|
5
|
+
const { JidNormalizer } = require("../Normalizers/JidNormalizer")
|
|
6
|
+
|
|
7
|
+
class UserManager {
|
|
8
|
+
/**
|
|
9
|
+
* @param {import('../WaClient').WaClient} client
|
|
10
|
+
*/
|
|
11
|
+
constructor(client) {
|
|
12
|
+
this.client = client
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
_getSock() {
|
|
16
|
+
if (!this.client.sock) {
|
|
17
|
+
throw new Error('Socket is not connected.')
|
|
18
|
+
}
|
|
19
|
+
return this.client.sock
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Verifica se um número ou JID existe no WhatsApp
|
|
24
|
+
* @param {string} phoneOrJid
|
|
25
|
+
* @returns {Promise<{ exists: boolean, jid: string } | null>}
|
|
26
|
+
*/
|
|
27
|
+
async isOnWhatsApp(phoneOrJid) {
|
|
28
|
+
return this.client.isOnWhatsApp(phoneOrJid)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Resolve um JID de forma transparente para PN ou LID
|
|
33
|
+
* @param {string} jidOrPhone
|
|
34
|
+
* @param {boolean} [fetchIfMissing=false]
|
|
35
|
+
* @returns {Promise<string>} JID canônico resolvido
|
|
36
|
+
*/
|
|
37
|
+
async resolveJid(jidOrPhone, fetchIfMissing = false) {
|
|
38
|
+
const sock = this._getSock()
|
|
39
|
+
if (sock.resolveJid) {
|
|
40
|
+
return sock.resolveJid(jidOrPhone, fetchIfMissing)
|
|
41
|
+
}
|
|
42
|
+
return JidNormalizer.toJid(jidOrPhone)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Converte um identificador LID (@lid) para o número de telefone (@s.whatsapp.net)
|
|
47
|
+
* @param {string} lidJid
|
|
48
|
+
* @param {boolean} [fetchIfMissing=false]
|
|
49
|
+
* @returns {Promise<string|null>} Telefone no formato JID
|
|
50
|
+
*/
|
|
51
|
+
async getPnForLid(lidJid, fetchIfMissing = false) {
|
|
52
|
+
const sock = this._getSock()
|
|
53
|
+
if (sock.toPn) {
|
|
54
|
+
return sock.toPn(lidJid, fetchIfMissing)
|
|
55
|
+
}
|
|
56
|
+
return null
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Converte um telefone (@s.whatsapp.net) para seu LID (@lid) correspondente
|
|
61
|
+
* @param {string} pnJid
|
|
62
|
+
* @param {boolean} [fetchIfMissing=false]
|
|
63
|
+
* @returns {Promise<string|null>} LID no formato JID
|
|
64
|
+
*/
|
|
65
|
+
async getLidForPn(pnJid, fetchIfMissing = false) {
|
|
66
|
+
const sock = this._getSock()
|
|
67
|
+
if (sock.toLid) {
|
|
68
|
+
return sock.toLid(pnJid, fetchIfMissing)
|
|
69
|
+
}
|
|
70
|
+
return null
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Obtém o perfil comercial de uma conta WhatsApp Business
|
|
75
|
+
* @param {string} jid
|
|
76
|
+
*/
|
|
77
|
+
async getBusinessProfile(jid) {
|
|
78
|
+
const sock = this._getSock()
|
|
79
|
+
const targetJid = JidNormalizer.toJid(jid)
|
|
80
|
+
if (!sock.getBusinessProfile) {
|
|
81
|
+
return null
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
return await sock.getBusinessProfile(targetJid)
|
|
85
|
+
} catch {
|
|
86
|
+
return null
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
exports.UserManager = UserManager
|
|
92
|
+
exports.default = UserManager
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
|
+
|
|
5
|
+
const { JidNormalizer } = require("../Normalizers/JidNormalizer")
|
|
6
|
+
const { CallContext } = require("../Context/CallContext")
|
|
7
|
+
|
|
8
|
+
class VoipManager {
|
|
9
|
+
/**
|
|
10
|
+
* @param {import('../WaClient').WaClient} client
|
|
11
|
+
*/
|
|
12
|
+
constructor(client) {
|
|
13
|
+
this.client = client
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
_getSock() {
|
|
17
|
+
if (!this.client.sock) {
|
|
18
|
+
throw new Error('Socket is not connected.')
|
|
19
|
+
}
|
|
20
|
+
return this.client.sock
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Realiza uma chamada de voz WhatsApp via WebAssembly
|
|
25
|
+
* @param {string} phoneNumber - Telefone ou JID de destino
|
|
26
|
+
* @param {Object} [options={}]
|
|
27
|
+
* @returns {Promise<CallContext>}
|
|
28
|
+
*/
|
|
29
|
+
async call(phoneNumber, options = {}) {
|
|
30
|
+
const sock = this._getSock()
|
|
31
|
+
if (!sock.call) {
|
|
32
|
+
throw new Error('VoIP engine is not enabled in this WaSockets build.')
|
|
33
|
+
}
|
|
34
|
+
const cleanNumber = JidNormalizer.toPhoneNumber(phoneNumber) || phoneNumber
|
|
35
|
+
const activeCall = await sock.call(cleanNumber, { ...options, isVideo: false })
|
|
36
|
+
return new CallContext(this.client, {
|
|
37
|
+
id: activeCall.callId,
|
|
38
|
+
from: cleanNumber,
|
|
39
|
+
isVideo: false,
|
|
40
|
+
status: 'calling'
|
|
41
|
+
}, activeCall)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Realiza uma chamada de vídeo WhatsApp
|
|
46
|
+
* @param {string} phoneNumber
|
|
47
|
+
* @param {Object} [options={}]
|
|
48
|
+
* @returns {Promise<CallContext>}
|
|
49
|
+
*/
|
|
50
|
+
async callVideo(phoneNumber, options = {}) {
|
|
51
|
+
const sock = this._getSock()
|
|
52
|
+
if (!sock.callVideo && !sock.call) {
|
|
53
|
+
throw new Error('VoIP engine is not enabled in this WaSockets build.')
|
|
54
|
+
}
|
|
55
|
+
const cleanNumber = JidNormalizer.toPhoneNumber(phoneNumber) || phoneNumber
|
|
56
|
+
const fn = sock.callVideo ? sock.callVideo.bind(sock) : (num, opts) => sock.call(num, { ...opts, isVideo: true })
|
|
57
|
+
const activeCall = await fn(cleanNumber, options)
|
|
58
|
+
return new CallContext(this.client, {
|
|
59
|
+
id: activeCall.callId,
|
|
60
|
+
from: cleanNumber,
|
|
61
|
+
isVideo: true,
|
|
62
|
+
status: 'calling'
|
|
63
|
+
}, activeCall)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Retorna a chamada ativa no momento ou null
|
|
68
|
+
* @returns {CallContext|null}
|
|
69
|
+
*/
|
|
70
|
+
get activeCall() {
|
|
71
|
+
const sock = this.client.sock
|
|
72
|
+
const rawCall = sock?.activeCall
|
|
73
|
+
if (!rawCall) return null
|
|
74
|
+
|
|
75
|
+
return new CallContext(this.client, {
|
|
76
|
+
id: rawCall.callId,
|
|
77
|
+
from: rawCall.target,
|
|
78
|
+
isVideo: Boolean(rawCall.isVideo),
|
|
79
|
+
status: rawCall.state || 'active'
|
|
80
|
+
}, rawCall.instance || rawCall)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Limpa o estado da chamada ativa atual
|
|
85
|
+
*/
|
|
86
|
+
clearActiveCall() {
|
|
87
|
+
const sock = this.client.sock
|
|
88
|
+
if (sock?.clearActiveCall) {
|
|
89
|
+
sock.clearActiveCall()
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Atende uma chamada recebida diretamente pelo ID
|
|
95
|
+
* @param {string} callId
|
|
96
|
+
* @param {string} from
|
|
97
|
+
* @param {Object} [options={}]
|
|
98
|
+
*/
|
|
99
|
+
async acceptCall(callId, from, options = {}) {
|
|
100
|
+
const ctx = new CallContext(this.client, { id: callId, from, isVideo: options.isVideo })
|
|
101
|
+
return ctx.accept(options)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Rejeita uma chamada recebida
|
|
106
|
+
* @param {string} callId
|
|
107
|
+
* @param {string} from
|
|
108
|
+
* @param {number|string} [reason=0]
|
|
109
|
+
*/
|
|
110
|
+
async rejectCall(callId, from, reason = 0) {
|
|
111
|
+
const ctx = new CallContext(this.client, { id: callId, from })
|
|
112
|
+
return ctx.reject(reason)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
exports.VoipManager = VoipManager
|
|
117
|
+
exports.default = VoipManager
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
|
+
|
|
5
|
+
const { MessageManager } = require("./MessageManager")
|
|
6
|
+
const { GroupManager } = require("./GroupManager")
|
|
7
|
+
const { ChannelManager } = require("./ChannelManager")
|
|
8
|
+
const { PresenceManager } = require("./PresenceManager")
|
|
9
|
+
const { ProfileManager } = require("./ProfileManager")
|
|
10
|
+
const { PrivacyManager } = require("./PrivacyManager")
|
|
11
|
+
const { UserManager } = require("./UserManager")
|
|
12
|
+
const { ChatManager } = require("./ChatManager")
|
|
13
|
+
const { VoipManager } = require("./VoipManager")
|
|
14
|
+
const { BusinessManager } = require("./BusinessManager")
|
|
15
|
+
const { CommunityManager } = require("./CommunityManager")
|
|
16
|
+
const { LabelManager } = require("./LabelManager")
|
|
17
|
+
|
|
18
|
+
exports.MessageManager = MessageManager
|
|
19
|
+
exports.GroupManager = GroupManager
|
|
20
|
+
exports.ChannelManager = ChannelManager
|
|
21
|
+
exports.PresenceManager = PresenceManager
|
|
22
|
+
exports.ProfileManager = ProfileManager
|
|
23
|
+
exports.PrivacyManager = PrivacyManager
|
|
24
|
+
exports.UserManager = UserManager
|
|
25
|
+
exports.ChatManager = ChatManager
|
|
26
|
+
exports.VoipManager = VoipManager
|
|
27
|
+
exports.BusinessManager = BusinessManager
|
|
28
|
+
exports.CommunityManager = CommunityManager
|
|
29
|
+
exports.LabelManager = LabelManager
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
|
+
|
|
5
|
+
const { Events } = require("../Constants")
|
|
6
|
+
const { MessageContext } = require("../Context/MessageContext")
|
|
7
|
+
const { CallContext } = require("../Context/CallContext")
|
|
8
|
+
|
|
9
|
+
class EventNormalizer {
|
|
10
|
+
/**
|
|
11
|
+
* Binds low-level socket events and maps them to semantic WaClient events
|
|
12
|
+
* @param {import('../WaClient').WaClient} client
|
|
13
|
+
*/
|
|
14
|
+
static bindSocketEvents(client) {
|
|
15
|
+
const sock = client.sock
|
|
16
|
+
if (!sock || !sock.ev) return
|
|
17
|
+
|
|
18
|
+
// 1. Message reception and outgoing events
|
|
19
|
+
sock.ev.on('messages.upsert', async ({ messages, type }) => {
|
|
20
|
+
if (!Array.isArray(messages)) return
|
|
21
|
+
|
|
22
|
+
for (const rawMsg of messages) {
|
|
23
|
+
// Ignore stub or protocol messages if completely empty
|
|
24
|
+
if (!rawMsg.message && !rawMsg.messageStubType) continue
|
|
25
|
+
|
|
26
|
+
// Handle protocol revoke messages explicitly
|
|
27
|
+
const isRevoke = rawMsg.message?.protocolMessage?.type === 0
|
|
28
|
+
if (isRevoke) {
|
|
29
|
+
client.emit(Events.MESSAGE_DELETE, {
|
|
30
|
+
keys: [rawMsg.message.protocolMessage.key || rawMsg.key]
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const ctx = new MessageContext(client, rawMsg)
|
|
35
|
+
|
|
36
|
+
if (ctx.isFromMe) {
|
|
37
|
+
client.emit(Events.MESSAGE_SENT, ctx, rawMsg)
|
|
38
|
+
} else {
|
|
39
|
+
client.emit(Events.MESSAGE_RECEIVED, ctx, rawMsg)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// If message is an edit, also notify on MESSAGE_UPDATE
|
|
43
|
+
if (ctx.isEdited) {
|
|
44
|
+
client.emit(Events.MESSAGE_UPDATE, [{
|
|
45
|
+
key: ctx.raw.key,
|
|
46
|
+
update: { message: ctx.raw.message },
|
|
47
|
+
ctx
|
|
48
|
+
}])
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
// 2. Message updates (reactions, poll updates, edits, delivery/read receipts)
|
|
54
|
+
sock.ev.on('messages.update', (updates) => {
|
|
55
|
+
client.emit(Events.MESSAGE_UPDATE, updates)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
// 3. Message deletion (revoke)
|
|
59
|
+
sock.ev.on('messages.delete', (item) => {
|
|
60
|
+
client.emit(Events.MESSAGE_DELETE, item)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
// 4. Presence updates (typing, online, offline)
|
|
64
|
+
sock.ev.on('presence.update', (presence) => {
|
|
65
|
+
client.emit(Events.PRESENCE_UPDATE, presence)
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
// 5. Contacts upsert
|
|
69
|
+
sock.ev.on('contacts.upsert', (contacts) => {
|
|
70
|
+
client.emit(Events.CONTACTS_UPSERT, contacts)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
// 6. Group participants updates (join, leave, promote, demote)
|
|
74
|
+
sock.ev.on('group-participants.update', (update) => {
|
|
75
|
+
client.emit(Events.GROUP_PARTICIPANTS_UPDATE, update)
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
// 7. VoIP incoming calls & status
|
|
79
|
+
sock.ev.on('call.received', (incomingCall) => {
|
|
80
|
+
const callCtx = new CallContext(client, incomingCall)
|
|
81
|
+
client.emit(Events.CALL_INCOMING, callCtx)
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
sock.ev.on('call', (calls) => {
|
|
85
|
+
client.emit(Events.CALL_STATUS, calls)
|
|
86
|
+
if (Array.isArray(calls)) {
|
|
87
|
+
for (const call of calls) {
|
|
88
|
+
if (call.status === 'offer') {
|
|
89
|
+
const callCtx = new CallContext(client, call)
|
|
90
|
+
client.emit(Events.CALL_INCOMING, callCtx)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
exports.EventNormalizer = EventNormalizer
|
|
99
|
+
exports.default = EventNormalizer
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
|
+
|
|
5
|
+
class JidNormalizer {
|
|
6
|
+
/**
|
|
7
|
+
* Sanitizes and normalizes any phone number or JID string into a canonical JID,
|
|
8
|
+
* stripping device specifiers (e.g., ":1@s.whatsapp.net" -> "@s.whatsapp.net")
|
|
9
|
+
* @param {string} input - Phone number (e.g., "+55 (11) 99999-9999") or existing JID
|
|
10
|
+
* @returns {string} Normalized JID (e.g., "5511999999999@s.whatsapp.net")
|
|
11
|
+
*/
|
|
12
|
+
static toJid(input) {
|
|
13
|
+
if (!input || typeof input !== 'string') return ''
|
|
14
|
+
const cleaned = input.trim()
|
|
15
|
+
|
|
16
|
+
if (cleaned.includes('@')) {
|
|
17
|
+
const [userPart, server] = cleaned.split('@')
|
|
18
|
+
const cleanUser = userPart.split(':')[0]
|
|
19
|
+
return `${cleanUser}@${server}`
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const digits = cleaned.replace(/\D/g, '')
|
|
23
|
+
if (!digits) return ''
|
|
24
|
+
|
|
25
|
+
return `${digits}@s.whatsapp.net`
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Extracts pure numeric phone number from a JID
|
|
30
|
+
* @param {string} jid - WhatsApp JID
|
|
31
|
+
* @returns {string} Extracted phone number or empty string
|
|
32
|
+
*/
|
|
33
|
+
static toPhoneNumber(jid) {
|
|
34
|
+
if (!jid || typeof jid !== 'string') return ''
|
|
35
|
+
const base = jid.split('@')[0]
|
|
36
|
+
const withoutDevice = base.split(':')[0]
|
|
37
|
+
return withoutDevice.replace(/\D/g, '')
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Checks if JID represents a WhatsApp Group
|
|
42
|
+
* @param {string} jid
|
|
43
|
+
* @returns {boolean}
|
|
44
|
+
*/
|
|
45
|
+
static isGroup(jid) {
|
|
46
|
+
return typeof jid === 'string' && jid.endsWith('@g.us')
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Checks if JID represents a WhatsApp Channel / Newsletter
|
|
51
|
+
* @param {string} jid
|
|
52
|
+
* @returns {boolean}
|
|
53
|
+
*/
|
|
54
|
+
static isNewsletter(jid) {
|
|
55
|
+
return typeof jid === 'string' && jid.endsWith('@newsletter')
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Checks if JID is an internal LID (Linked Identity)
|
|
60
|
+
* @param {string} jid
|
|
61
|
+
* @returns {boolean}
|
|
62
|
+
*/
|
|
63
|
+
static isLid(jid) {
|
|
64
|
+
return typeof jid === 'string' && jid.endsWith('@lid')
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Checks if JID is a regular user chat (Phone Number based)
|
|
69
|
+
* @param {string} jid
|
|
70
|
+
* @returns {boolean}
|
|
71
|
+
*/
|
|
72
|
+
static isUser(jid) {
|
|
73
|
+
return typeof jid === 'string' && jid.endsWith('@s.whatsapp.net')
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Checks if JID represents WhatsApp Status Broadcast
|
|
78
|
+
* @param {string} jid
|
|
79
|
+
* @returns {boolean}
|
|
80
|
+
*/
|
|
81
|
+
static isStatusBroadcast(jid) {
|
|
82
|
+
return typeof jid === 'string' && jid === 'status@broadcast'
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Checks if JID represents any Broadcast list
|
|
87
|
+
* @param {string} jid
|
|
88
|
+
* @returns {boolean}
|
|
89
|
+
*/
|
|
90
|
+
static isBroadcast(jid) {
|
|
91
|
+
return typeof jid === 'string' && jid.endsWith('@broadcast')
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
exports.JidNormalizer = JidNormalizer
|
|
96
|
+
exports.default = JidNormalizer
|