@areumtecnologia/wasockets 2.0.0 → 2.3.0
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 +1987 -1649
- 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 +146 -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 +82 -0
- package/lib/Client/Normalizers/JidNormalizer.js +93 -0
- package/lib/Client/Normalizers/MessageNormalizer.js +134 -0
- package/lib/Client/WaClient.js +438 -0
- package/lib/Client/index.d.ts +464 -0
- package/lib/Client/index.js +76 -0
- package/lib/Defaults/baileys-version.json +1 -1
- package/lib/Defaults/connection.js +14 -1
- package/lib/Socket/index.js +51 -48
- package/lib/Socket/messages-recv.js +74 -13
- package/lib/Socket/messages-send.js +50 -25
- package/lib/Socket/socket.js +13 -0
- package/lib/Socket/voip.js +123 -0
- package/lib/Store/make-cache-manager-store.js +14 -5
- package/lib/Types/index.d.ts +4 -0
- package/lib/Utils/auth-utils.js +16 -1
- package/lib/Utils/browser-utils.js +6 -2
- package/lib/Utils/generics.js +47 -8
- package/lib/Utils/index.d.ts +1 -0
- package/lib/Utils/messages-media.js +44 -21
- package/lib/Utils/pre-key-manager.js +16 -1
- package/lib/Utils/validate-connection.js +10 -11
- package/lib/VoIP/VoIPCrypto.js +150 -0
- package/lib/VoIP/VoIPManager.js +469 -0
- package/lib/VoIP/VoIPMediaEngine.js +224 -0
- package/lib/VoIP/VoIPProtocol.js +354 -0
- package/lib/VoIP/VoIPRelayTransport.js +173 -0
- package/lib/VoIP/VoIPSession.js +314 -0
- package/lib/VoIP/assets/wasm/loader.js +5 -0
- package/lib/VoIP/assets/wasm/whatsapp.wasm +0 -0
- package/lib/VoIP/assets/wasm/worker-modules.js +305 -0
- package/lib/VoIP/engine/audio-feeder.d.mts +15 -0
- package/lib/VoIP/engine/audio-feeder.mjs +243 -0
- package/lib/VoIP/engine/index.d.mts +91 -0
- package/lib/VoIP/engine/index.mjs +1683 -0
- package/lib/VoIP/engine/relay-transport.d.mts +43 -0
- package/lib/VoIP/engine/relay-transport.mjs +607 -0
- package/lib/VoIP/engine/signaling.d.mts +44 -0
- package/lib/VoIP/engine/signaling.mjs +893 -0
- package/lib/VoIP/engine/types.d.mts +183 -0
- package/lib/VoIP/engine/types.mjs +17 -0
- package/lib/VoIP/engine/wasm-engine.d.mts +103 -0
- package/lib/VoIP/engine/wasm-engine.mjs +1397 -0
- package/lib/VoIP/engine/worker-bootstrap.mjs +1049 -0
- package/lib/VoIP/index.js +51 -0
- package/lib/VoIP/utils/audio.d.ts +28 -0
- package/lib/VoIP/utils/audio.js +148 -0
- package/lib/WABinary/generic-utils.js +22 -6
- package/lib/index.d.ts +382 -274
- package/lib/index.js +5 -0
- package/package.json +51 -49
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Quick Reply Button - user clicks and sends a predetermined text/id response
|
|
7
|
+
*/
|
|
8
|
+
class QuickReplyButton {
|
|
9
|
+
constructor(displayText, id) {
|
|
10
|
+
this.displayText = displayText || ''
|
|
11
|
+
this.id = id || displayText || 'quick_reply'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
build() {
|
|
15
|
+
return {
|
|
16
|
+
name: 'quick_reply',
|
|
17
|
+
buttonParamsJson: JSON.stringify({
|
|
18
|
+
display_text: this.displayText,
|
|
19
|
+
id: this.id
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* URL Button - user clicks and opens a webpage
|
|
27
|
+
*/
|
|
28
|
+
class UrlButton {
|
|
29
|
+
constructor(displayText, url, merchantUrl) {
|
|
30
|
+
this.displayText = displayText || ''
|
|
31
|
+
this.url = url || ''
|
|
32
|
+
this.merchantUrl = merchantUrl || url || ''
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
build() {
|
|
36
|
+
return {
|
|
37
|
+
name: 'cta_url',
|
|
38
|
+
buttonParamsJson: JSON.stringify({
|
|
39
|
+
display_text: this.displayText,
|
|
40
|
+
url: this.url,
|
|
41
|
+
merchant_url: this.merchantUrl
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Copy Code Button - user clicks to copy a coupon/token to clipboard
|
|
49
|
+
*/
|
|
50
|
+
class CopyCodeButton {
|
|
51
|
+
constructor(displayText, copyCode, id) {
|
|
52
|
+
this.displayText = displayText || ''
|
|
53
|
+
this.copyCode = copyCode || ''
|
|
54
|
+
this.id = id || 'copy_code'
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
build() {
|
|
58
|
+
return {
|
|
59
|
+
name: 'cta_copy',
|
|
60
|
+
buttonParamsJson: JSON.stringify({
|
|
61
|
+
display_text: this.displayText,
|
|
62
|
+
id: this.id,
|
|
63
|
+
copy_code: this.copyCode
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Call Button - user clicks to initiate a standard voice call
|
|
71
|
+
*/
|
|
72
|
+
class CallButton {
|
|
73
|
+
constructor(displayText, phoneNumber) {
|
|
74
|
+
this.displayText = displayText || ''
|
|
75
|
+
this.phoneNumber = phoneNumber || ''
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
build() {
|
|
79
|
+
return {
|
|
80
|
+
name: 'cta_call',
|
|
81
|
+
buttonParamsJson: JSON.stringify({
|
|
82
|
+
display_text: this.displayText,
|
|
83
|
+
phone_number: this.phoneNumber
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Native PIX Payment Button (WhatsApp Payment Info)
|
|
91
|
+
*/
|
|
92
|
+
class PixButton {
|
|
93
|
+
/**
|
|
94
|
+
* @param {string} displayText - Text displayed on button (e.g., 'Pagar com PIX')
|
|
95
|
+
* @param {string} pixKey - Chave PIX (CPF/CNPJ, Email, Telefone ou EVP)
|
|
96
|
+
* @param {string} [keyType='CPF'] - Tipo da chave: 'CPF', 'EMAIL', 'PHONE', 'EVP'
|
|
97
|
+
* @param {string} [merchantName='Comerciante'] - Nome do beneficiário exibido
|
|
98
|
+
*/
|
|
99
|
+
constructor(displayText, pixKey, keyType = 'CPF', merchantName = 'Comerciante') {
|
|
100
|
+
this.displayText = displayText || 'Pagar via PIX'
|
|
101
|
+
this.pixKey = pixKey || ''
|
|
102
|
+
this.keyType = (keyType || 'CPF').toUpperCase()
|
|
103
|
+
this.merchantName = merchantName || 'Comerciante'
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
build() {
|
|
107
|
+
return {
|
|
108
|
+
name: 'payment_info',
|
|
109
|
+
buttonParamsJson: JSON.stringify({
|
|
110
|
+
payment_settings: [{
|
|
111
|
+
type: 'pix_static_code',
|
|
112
|
+
pix_static_code: {
|
|
113
|
+
merchant_name: this.merchantName,
|
|
114
|
+
key: this.pixKey,
|
|
115
|
+
key_type: this.keyType
|
|
116
|
+
}
|
|
117
|
+
}]
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
exports.QuickReplyButton = QuickReplyButton
|
|
124
|
+
exports.UrlButton = UrlButton
|
|
125
|
+
exports.CopyCodeButton = CopyCodeButton
|
|
126
|
+
exports.CallButton = CallButton
|
|
127
|
+
exports.PixButton = PixButton
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Fluent builder for WhatsApp Calendar / Group Event Messages
|
|
7
|
+
*/
|
|
8
|
+
class EventBuilder {
|
|
9
|
+
constructor() {
|
|
10
|
+
this._name = ''
|
|
11
|
+
this._description = ''
|
|
12
|
+
this._startTime = null
|
|
13
|
+
this._endTime = null
|
|
14
|
+
this._location = null
|
|
15
|
+
this._call = null
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Sets event title
|
|
20
|
+
* @param {string} name
|
|
21
|
+
* @returns {this}
|
|
22
|
+
*/
|
|
23
|
+
setName(name) {
|
|
24
|
+
this._name = name || ''
|
|
25
|
+
return this
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Sets event description
|
|
30
|
+
* @param {string} description
|
|
31
|
+
* @returns {this}
|
|
32
|
+
*/
|
|
33
|
+
setDescription(description) {
|
|
34
|
+
this._description = description || ''
|
|
35
|
+
return this
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Sets start time as Date, timestamp in seconds or milliseconds
|
|
40
|
+
* @param {Date|number} date
|
|
41
|
+
* @returns {this}
|
|
42
|
+
*/
|
|
43
|
+
setStartDate(date) {
|
|
44
|
+
if (date instanceof Date) {
|
|
45
|
+
this._startTime = Math.floor(date.getTime() / 1000)
|
|
46
|
+
} else if (typeof date === 'number') {
|
|
47
|
+
this._startTime = date > 10000000000 ? Math.floor(date / 1000) : Math.floor(date)
|
|
48
|
+
}
|
|
49
|
+
return this
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Sets end time as Date, timestamp in seconds or milliseconds
|
|
54
|
+
* @param {Date|number} date
|
|
55
|
+
* @returns {this}
|
|
56
|
+
*/
|
|
57
|
+
setEndDate(date) {
|
|
58
|
+
if (date instanceof Date) {
|
|
59
|
+
this._endTime = Math.floor(date.getTime() / 1000)
|
|
60
|
+
} else if (typeof date === 'number') {
|
|
61
|
+
this._endTime = date > 10000000000 ? Math.floor(date / 1000) : Math.floor(date)
|
|
62
|
+
}
|
|
63
|
+
return this
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Sets event location
|
|
68
|
+
* @param {string} name - Location name
|
|
69
|
+
* @param {number} [degreesLatitude]
|
|
70
|
+
* @param {number} [degreesLongitude]
|
|
71
|
+
* @returns {this}
|
|
72
|
+
*/
|
|
73
|
+
setLocation(name, degreesLatitude, degreesLongitude) {
|
|
74
|
+
this._location = {
|
|
75
|
+
name: name || '',
|
|
76
|
+
degreesLatitude: degreesLatitude || 0,
|
|
77
|
+
degreesLongitude: degreesLongitude || 0
|
|
78
|
+
}
|
|
79
|
+
return this
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Sets WhatsApp voice or video call for the event
|
|
84
|
+
* @param {'voice'|'video'|1|2} callType
|
|
85
|
+
* @returns {this}
|
|
86
|
+
*/
|
|
87
|
+
setCall(callType = 'voice') {
|
|
88
|
+
this._call = {
|
|
89
|
+
callType: callType === 'video' || callType === 2 ? 2 : 1
|
|
90
|
+
}
|
|
91
|
+
return this
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Compiles event into a payload ready for sendMessage()
|
|
96
|
+
* @returns {Object}
|
|
97
|
+
*/
|
|
98
|
+
build() {
|
|
99
|
+
if (!this._name) {
|
|
100
|
+
throw new Error('EventBuilder requires an event title via setName().')
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const nowSec = Math.floor(Date.now() / 1000)
|
|
104
|
+
const startTime = this._startTime || (nowSec + 3600) // Default 1 hour from now
|
|
105
|
+
|
|
106
|
+
const eventPayload = {
|
|
107
|
+
name: this._name,
|
|
108
|
+
description: this._description || undefined,
|
|
109
|
+
startTime,
|
|
110
|
+
endTime: this._endTime || undefined,
|
|
111
|
+
location: this._location || undefined,
|
|
112
|
+
call: this._call || undefined
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
event: eventPayload
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
exports.EventBuilder = EventBuilder
|
|
122
|
+
exports.default = EventBuilder
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
|
+
|
|
5
|
+
const { ListButton } = require("./Lists")
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Fluent builder for Interactive WhatsApp Messages (Buttons, Cards, Menus, PIX)
|
|
9
|
+
*/
|
|
10
|
+
class InteractiveMessage {
|
|
11
|
+
constructor() {
|
|
12
|
+
this._title = ''
|
|
13
|
+
this._subtitle = ''
|
|
14
|
+
this._text = ''
|
|
15
|
+
this._footer = ''
|
|
16
|
+
this._header = null
|
|
17
|
+
this._buttons = []
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Sets card title
|
|
22
|
+
* @param {string} title
|
|
23
|
+
* @returns {this}
|
|
24
|
+
*/
|
|
25
|
+
setTitle(title) {
|
|
26
|
+
this._title = title || ''
|
|
27
|
+
return this
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Sets subtitle or secondary header
|
|
32
|
+
* @param {string} subtitle
|
|
33
|
+
* @returns {this}
|
|
34
|
+
*/
|
|
35
|
+
setSubtitle(subtitle) {
|
|
36
|
+
this._subtitle = subtitle || ''
|
|
37
|
+
return this
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Sets the main text body (required)
|
|
42
|
+
* @param {string} text
|
|
43
|
+
* @returns {this}
|
|
44
|
+
*/
|
|
45
|
+
setText(text) {
|
|
46
|
+
this._text = text || ''
|
|
47
|
+
return this
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Sets smaller footer text at the bottom
|
|
52
|
+
* @param {string} footer
|
|
53
|
+
* @returns {this}
|
|
54
|
+
*/
|
|
55
|
+
setFooter(footer) {
|
|
56
|
+
this._footer = footer || ''
|
|
57
|
+
return this
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Sets an image header for the interactive card
|
|
62
|
+
* @param {string|Buffer|{ url: string }} image
|
|
63
|
+
* @returns {this}
|
|
64
|
+
*/
|
|
65
|
+
setHeaderImage(image) {
|
|
66
|
+
this._header = {
|
|
67
|
+
image: typeof image === 'string' ? { url: image } : image
|
|
68
|
+
}
|
|
69
|
+
return this
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Sets a video header for the interactive card
|
|
74
|
+
* @param {string|Buffer|{ url: string }} video
|
|
75
|
+
* @returns {this}
|
|
76
|
+
*/
|
|
77
|
+
setHeaderVideo(video) {
|
|
78
|
+
this._header = {
|
|
79
|
+
video: typeof video === 'string' ? { url: video } : video
|
|
80
|
+
}
|
|
81
|
+
return this
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Adds an interactive button (QuickReply, Url, CopyCode, Call, Pix or ListButton)
|
|
86
|
+
* @param {Object} button
|
|
87
|
+
* @returns {this}
|
|
88
|
+
*/
|
|
89
|
+
addButton(button) {
|
|
90
|
+
if (button) {
|
|
91
|
+
this._buttons.push(button)
|
|
92
|
+
}
|
|
93
|
+
return this
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Adds multiple buttons at once
|
|
98
|
+
* @param {Array<Object>} buttons
|
|
99
|
+
* @returns {this}
|
|
100
|
+
*/
|
|
101
|
+
addButtons(buttons) {
|
|
102
|
+
if (Array.isArray(buttons)) {
|
|
103
|
+
for (const b of buttons) {
|
|
104
|
+
this.addButton(b)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return this
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Compiles the interactive message into a payload ready for sock.sendMessage()
|
|
112
|
+
* @returns {Object}
|
|
113
|
+
*/
|
|
114
|
+
build() {
|
|
115
|
+
if (!this._text && !this._title) {
|
|
116
|
+
throw new Error('InteractiveMessage requires at least a text or title.')
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Check if there is a ListButton
|
|
120
|
+
const listBtn = this._buttons.find(b => b instanceof ListButton || b.sections)
|
|
121
|
+
|
|
122
|
+
if (listBtn) {
|
|
123
|
+
const builtList = typeof listBtn.build === 'function' ? listBtn.build() : listBtn
|
|
124
|
+
return {
|
|
125
|
+
text: this._text,
|
|
126
|
+
title: this._title || undefined,
|
|
127
|
+
subtitle: this._subtitle || undefined,
|
|
128
|
+
footer: this._footer || undefined,
|
|
129
|
+
buttonText: builtList.buttonText,
|
|
130
|
+
sections: builtList.sections,
|
|
131
|
+
...(this._header || {})
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Standard interactive buttons
|
|
136
|
+
return {
|
|
137
|
+
text: this._text,
|
|
138
|
+
title: this._title || undefined,
|
|
139
|
+
subtitle: this._subtitle || undefined,
|
|
140
|
+
footer: this._footer || undefined,
|
|
141
|
+
...(this._header || {}),
|
|
142
|
+
interactiveButtons: this._buttons.map(btn => (
|
|
143
|
+
typeof btn.build === 'function' ? btn.build() : btn
|
|
144
|
+
))
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
exports.InteractiveMessage = InteractiveMessage
|
|
150
|
+
exports.default = InteractiveMessage
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Individual row in an interactive list section
|
|
7
|
+
*/
|
|
8
|
+
class ListRow {
|
|
9
|
+
constructor(title, description = '', rowId = '') {
|
|
10
|
+
this.title = title || ''
|
|
11
|
+
this.description = description || ''
|
|
12
|
+
this.rowId = rowId || title || 'row'
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
build() {
|
|
16
|
+
return {
|
|
17
|
+
title: this.title,
|
|
18
|
+
description: this.description,
|
|
19
|
+
rowId: this.rowId
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Categorized section containing multiple rows
|
|
26
|
+
*/
|
|
27
|
+
class ListSection {
|
|
28
|
+
constructor(title, rows = []) {
|
|
29
|
+
this.title = title || ''
|
|
30
|
+
this.rows = Array.isArray(rows) ? rows : []
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
addRow(titleOrRow, description, rowId) {
|
|
34
|
+
if (titleOrRow instanceof ListRow) {
|
|
35
|
+
this.rows.push(titleOrRow)
|
|
36
|
+
} else {
|
|
37
|
+
this.rows.push(new ListRow(titleOrRow, description, rowId))
|
|
38
|
+
}
|
|
39
|
+
return this
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
build() {
|
|
43
|
+
return {
|
|
44
|
+
title: this.title,
|
|
45
|
+
rows: this.rows.map(row => typeof row.build === 'function' ? row.build() : row)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* List Dropdown Button configuration
|
|
52
|
+
*/
|
|
53
|
+
class ListButton {
|
|
54
|
+
constructor(buttonText, sections = []) {
|
|
55
|
+
this.buttonText = buttonText || 'Ver Opções'
|
|
56
|
+
this.sections = Array.isArray(sections) ? sections : []
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
addSection(titleOrSection, rows) {
|
|
60
|
+
if (titleOrSection instanceof ListSection) {
|
|
61
|
+
this.sections.push(titleOrSection)
|
|
62
|
+
} else {
|
|
63
|
+
this.sections.push(new ListSection(titleOrSection, rows))
|
|
64
|
+
}
|
|
65
|
+
return this
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
build() {
|
|
69
|
+
return {
|
|
70
|
+
buttonText: this.buttonText,
|
|
71
|
+
sections: this.sections.map(sec => typeof sec.build === 'function' ? sec.build() : sec)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
exports.ListRow = ListRow
|
|
77
|
+
exports.ListSection = ListSection
|
|
78
|
+
exports.ListButton = ListButton
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Fluent builder for WhatsApp Polls
|
|
7
|
+
*/
|
|
8
|
+
class PollBuilder {
|
|
9
|
+
constructor() {
|
|
10
|
+
this._name = ''
|
|
11
|
+
this._options = []
|
|
12
|
+
this._selectableCount = 1
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Sets poll question / title
|
|
17
|
+
* @param {string} name
|
|
18
|
+
* @returns {this}
|
|
19
|
+
*/
|
|
20
|
+
setName(name) {
|
|
21
|
+
this._name = name || ''
|
|
22
|
+
return this
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Adds an option to the poll
|
|
27
|
+
* @param {string} option
|
|
28
|
+
* @returns {this}
|
|
29
|
+
*/
|
|
30
|
+
addOption(option) {
|
|
31
|
+
if (option && typeof option === 'string') {
|
|
32
|
+
this._options.push(option.trim())
|
|
33
|
+
}
|
|
34
|
+
return this
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Adds multiple options to the poll
|
|
39
|
+
* @param {Array<string>} options
|
|
40
|
+
* @returns {this}
|
|
41
|
+
*/
|
|
42
|
+
addOptions(options) {
|
|
43
|
+
if (Array.isArray(options)) {
|
|
44
|
+
for (const opt of options) {
|
|
45
|
+
this.addOption(opt)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return this
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Sets how many options can be selected (1 for single choice, > 1 for multiple choices)
|
|
53
|
+
* @param {number} count
|
|
54
|
+
* @returns {this}
|
|
55
|
+
*/
|
|
56
|
+
setSelectableCount(count) {
|
|
57
|
+
this._selectableCount = Math.max(1, Number(count) || 1)
|
|
58
|
+
return this
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Compiles poll into a payload for sendMessage()
|
|
63
|
+
* @returns {Object}
|
|
64
|
+
*/
|
|
65
|
+
build() {
|
|
66
|
+
if (!this._name) {
|
|
67
|
+
throw new Error('PollBuilder requires a question name via setName().')
|
|
68
|
+
}
|
|
69
|
+
if (this._options.length < 2) {
|
|
70
|
+
throw new Error('PollBuilder requires at least 2 options.')
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
poll: {
|
|
75
|
+
name: this._name,
|
|
76
|
+
values: this._options,
|
|
77
|
+
selectableCount: this._selectableCount
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
exports.PollBuilder = PollBuilder
|
|
84
|
+
exports.default = PollBuilder
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
|
+
|
|
5
|
+
const { InteractiveMessage } = require("./InteractiveMessage")
|
|
6
|
+
const { QuickReplyButton, UrlButton, CopyCodeButton, CallButton, PixButton } = require("./Buttons")
|
|
7
|
+
const { ListButton, ListSection, ListRow } = require("./Lists")
|
|
8
|
+
const { PollBuilder } = require("./PollBuilder")
|
|
9
|
+
const { EventBuilder } = require("./EventBuilder")
|
|
10
|
+
|
|
11
|
+
exports.InteractiveMessage = InteractiveMessage
|
|
12
|
+
exports.QuickReplyButton = QuickReplyButton
|
|
13
|
+
exports.UrlButton = UrlButton
|
|
14
|
+
exports.CopyCodeButton = CopyCodeButton
|
|
15
|
+
exports.CallButton = CallButton
|
|
16
|
+
exports.PixButton = PixButton
|
|
17
|
+
exports.ListButton = ListButton
|
|
18
|
+
exports.ListSection = ListSection
|
|
19
|
+
exports.ListRow = ListRow
|
|
20
|
+
exports.PollBuilder = PollBuilder
|
|
21
|
+
exports.EventBuilder = EventBuilder
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* High-level semantic event names for WaClient
|
|
7
|
+
*/
|
|
8
|
+
const Events = Object.freeze({
|
|
9
|
+
// Connection Lifecycle
|
|
10
|
+
STATUS_CHANGE: 'status.change',
|
|
11
|
+
QR_CODE: 'qr',
|
|
12
|
+
PAIRING_CODE: 'pairing.code',
|
|
13
|
+
CONNECTED: 'connected',
|
|
14
|
+
DISCONNECTED: 'disconnected',
|
|
15
|
+
LOGGED_OUT: 'logged.out',
|
|
16
|
+
|
|
17
|
+
// Messages
|
|
18
|
+
MESSAGE_RECEIVED: 'message.received',
|
|
19
|
+
MESSAGE_SENT: 'message.sent',
|
|
20
|
+
MESSAGE_UPDATE: 'message.update',
|
|
21
|
+
MESSAGE_DELETE: 'message.delete',
|
|
22
|
+
|
|
23
|
+
// Presence & Contacts
|
|
24
|
+
PRESENCE_UPDATE: 'presence.update',
|
|
25
|
+
CONTACTS_UPSERT: 'contacts.upsert',
|
|
26
|
+
|
|
27
|
+
// VoIP & Calls
|
|
28
|
+
CALL_INCOMING: 'call.incoming',
|
|
29
|
+
CALL_STATUS: 'call.status',
|
|
30
|
+
|
|
31
|
+
// Group & Community Events
|
|
32
|
+
GROUP_PARTICIPANTS_UPDATE: 'group.participants.update',
|
|
33
|
+
|
|
34
|
+
// Generic Error
|
|
35
|
+
ERROR: 'error'
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Connection states for WaClient state machine
|
|
40
|
+
*/
|
|
41
|
+
const ConnectionStatus = Object.freeze({
|
|
42
|
+
IDLE: 'idle',
|
|
43
|
+
INITIALIZING: 'initializing',
|
|
44
|
+
CONNECTING: 'connecting',
|
|
45
|
+
QR_READY: 'qr_ready',
|
|
46
|
+
PAIRING_READY: 'pairing_ready',
|
|
47
|
+
CONNECTED: 'connected',
|
|
48
|
+
RECONNECTING: 'reconnecting',
|
|
49
|
+
LOGGED_OUT: 'logged_out',
|
|
50
|
+
DISCONNECTED: 'disconnected'
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
exports.Events = Events
|
|
54
|
+
exports.ConnectionStatus = ConnectionStatus
|