@nerxa/socketon 0.0.0-stage → 1.21.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/EXPERIMENTAL.md +350 -0
- package/LICENSE +24 -0
- package/README.md +6317 -2
- package/WAProto/index.d.ts +17301 -0
- package/WAProto/index.js +125088 -0
- package/engine-requirements.js +14 -0
- package/package.json +100 -4
- package/src/Defaults/index.d.ts +152 -0
- package/src/Defaults/index.js +164 -0
- package/src/MessageBuilder/bot-signature.d.ts +22 -0
- package/src/MessageBuilder/bot-signature.js +122 -0
- package/src/MessageBuilder/extras.d.ts +449 -0
- package/src/MessageBuilder/extras.js +1356 -0
- package/src/MessageBuilder/index.d.ts +210 -0
- package/src/MessageBuilder/index.js +3594 -0
- package/src/MessageBuilder/metaai.d.ts +438 -0
- package/src/MessageBuilder/metaai.js +890 -0
- package/src/Signal/Group/ciphertext-message.d.ts +9 -0
- package/src/Signal/Group/ciphertext-message.js +11 -0
- package/src/Signal/Group/group-session-builder.d.ts +7 -0
- package/src/Signal/Group/group-session-builder.js +27 -0
- package/src/Signal/Group/group_cipher.d.ts +11 -0
- package/src/Signal/Group/group_cipher.js +78 -0
- package/src/Signal/Group/index.d.ts +11 -0
- package/src/Signal/Group/index.js +11 -0
- package/src/Signal/Group/keyhelper.d.ts +6 -0
- package/src/Signal/Group/keyhelper.js +17 -0
- package/src/Signal/Group/sender-chain-key.d.ts +13 -0
- package/src/Signal/Group/sender-chain-key.js +25 -0
- package/src/Signal/Group/sender-key-distribution-message.d.ts +16 -0
- package/src/Signal/Group/sender-key-distribution-message.js +62 -0
- package/src/Signal/Group/sender-key-message.d.ts +18 -0
- package/src/Signal/Group/sender-key-message.js +65 -0
- package/src/Signal/Group/sender-key-name.d.ts +11 -0
- package/src/Signal/Group/sender-key-name.js +47 -0
- package/src/Signal/Group/sender-key-record.d.ts +12 -0
- package/src/Signal/Group/sender-key-record.js +40 -0
- package/src/Signal/Group/sender-key-state.d.ts +16 -0
- package/src/Signal/Group/sender-key-state.js +83 -0
- package/src/Signal/Group/sender-message-key.d.ts +11 -0
- package/src/Signal/Group/sender-message-key.js +25 -0
- package/src/Signal/libsignal.d.ts +54 -0
- package/src/Signal/libsignal.js +427 -0
- package/src/Signal/lid-mapping.d.ts +20 -0
- package/src/Signal/lid-mapping.js +274 -0
- package/src/Socket/Client/index.d.ts +2 -0
- package/src/Socket/Client/index.js +3 -0
- package/src/Socket/Client/tcp.js +177 -0
- package/src/Socket/Client/types.d.ts +5 -0
- package/src/Socket/Client/types.js +9 -0
- package/src/Socket/Client/websocket.d.ts +12 -0
- package/src/Socket/Client/websocket.js +53 -0
- package/src/Socket/business.d.ts +431 -0
- package/src/Socket/business.js +379 -0
- package/src/Socket/chats.d.ts +247 -0
- package/src/Socket/chats.js +1484 -0
- package/src/Socket/communities.d.ts +598 -0
- package/src/Socket/communities.js +421 -0
- package/src/Socket/email.js +145 -0
- package/src/Socket/groups.d.ts +298 -0
- package/src/Socket/groups.js +339 -0
- package/src/Socket/index.d.ts +581 -0
- package/src/Socket/index.js +37 -0
- package/src/Socket/messages-recv.d.ts +370 -0
- package/src/Socket/messages-recv.js +1864 -0
- package/src/Socket/messages-send.d.ts +390 -0
- package/src/Socket/messages-send.js +1574 -0
- package/src/Socket/mex.d.ts +1 -0
- package/src/Socket/mex.js +44 -0
- package/src/Socket/mobile-builders.js +72 -0
- package/src/Socket/mobile.js +424 -0
- package/src/Socket/newsletter.d.ts +468 -0
- package/src/Socket/newsletter.js +671 -0
- package/src/Socket/socket.d.ts +77 -0
- package/src/Socket/socket.js +1106 -0
- package/src/Store/index.d.ts +3 -0
- package/src/Store/index.js +3 -0
- package/src/Store/make-in-memory-store.d.ts +62 -0
- package/src/Store/make-in-memory-store.js +396 -0
- package/src/Store/make-ordered-dictionary.d.ts +12 -0
- package/src/Store/make-ordered-dictionary.js +78 -0
- package/src/Store/object-repository.d.ts +10 -0
- package/src/Store/object-repository.js +23 -0
- package/src/Types/Auth.d.ts +1 -0
- package/src/Types/Auth.js +1 -0
- package/src/Types/Bussines.d.ts +1 -0
- package/src/Types/Bussines.js +1 -0
- package/src/Types/Call.d.ts +1 -0
- package/src/Types/Call.js +1 -0
- package/src/Types/Chat.d.ts +2 -0
- package/src/Types/Chat.js +24 -0
- package/src/Types/Contact.d.ts +1 -0
- package/src/Types/Contact.js +1 -0
- package/src/Types/Events.d.ts +1 -0
- package/src/Types/Events.js +0 -0
- package/src/Types/GroupMetadata.d.ts +5 -0
- package/src/Types/GroupMetadata.js +6 -0
- package/src/Types/Label.d.ts +2 -0
- package/src/Types/Label.js +24 -0
- package/src/Types/LabelAssociation.d.ts +2 -0
- package/src/Types/LabelAssociation.js +6 -0
- package/src/Types/Message.d.ts +13 -0
- package/src/Types/Message.js +23 -0
- package/src/Types/Mex.d.ts +2 -0
- package/src/Types/Mex.js +95 -0
- package/src/Types/Product.d.ts +1 -0
- package/src/Types/Product.js +1 -0
- package/src/Types/Signal.d.ts +1 -0
- package/src/Types/Signal.js +0 -0
- package/src/Types/Socket.d.ts +1 -0
- package/src/Types/Socket.js +0 -0
- package/src/Types/State.d.ts +5 -0
- package/src/Types/State.js +54 -0
- package/src/Types/USync.d.ts +1 -0
- package/src/Types/USync.js +0 -0
- package/src/Types/index.d.ts +13 -0
- package/src/Types/index.js +25 -0
- package/src/Utils/auth-store.d.ts +29 -0
- package/src/Utils/auth-store.js +76 -0
- package/src/Utils/auth-utils.d.ts +58 -0
- package/src/Utils/auth-utils.js +273 -0
- package/src/Utils/browser-utils.d.ts +9 -0
- package/src/Utils/browser-utils.js +28 -0
- package/src/Utils/business.d.ts +49 -0
- package/src/Utils/business.js +226 -0
- package/src/Utils/chat-utils.d.ts +408 -0
- package/src/Utils/chat-utils.js +846 -0
- package/src/Utils/companion-reg-client-utils.d.ts +4 -0
- package/src/Utils/companion-reg-client-utils.js +39 -0
- package/src/Utils/crypto.d.ts +39 -0
- package/src/Utils/crypto.js +110 -0
- package/src/Utils/decode-wa-message.d.ts +99 -0
- package/src/Utils/decode-wa-message.js +373 -0
- package/src/Utils/event-buffer.d.ts +22 -0
- package/src/Utils/event-buffer.js +624 -0
- package/src/Utils/generics.d.ts +63 -0
- package/src/Utils/generics.js +375 -0
- package/src/Utils/group-metadata-cache.d.ts +4 -0
- package/src/Utils/group-metadata-cache.js +25 -0
- package/src/Utils/history.d.ts +75 -0
- package/src/Utils/history.js +131 -0
- package/src/Utils/html-app.d.ts +19 -0
- package/src/Utils/html-app.js +96 -0
- package/src/Utils/html-multiplayer.d.ts +10 -0
- package/src/Utils/html-multiplayer.js +94 -0
- package/src/Utils/identity-change-handler.d.ts +13 -0
- package/src/Utils/identity-change-handler.js +48 -0
- package/src/Utils/index.d.ts +44 -0
- package/src/Utils/index.js +44 -0
- package/src/Utils/link-preview-metadata.d.ts +47 -0
- package/src/Utils/link-preview-metadata.js +88 -0
- package/src/Utils/link-preview.d.ts +12 -0
- package/src/Utils/link-preview.js +79 -0
- package/src/Utils/logger.d.ts +2 -0
- package/src/Utils/logger.js +2 -0
- package/src/Utils/lt-hash.d.ts +6 -0
- package/src/Utils/lt-hash.js +3 -0
- package/src/Utils/make-mutex.d.ts +6 -0
- package/src/Utils/make-mutex.js +32 -0
- package/src/Utils/message-retry-manager.d.ts +79 -0
- package/src/Utils/message-retry-manager.js +255 -0
- package/src/Utils/messages-media.d.ts +136 -0
- package/src/Utils/messages-media.js +814 -0
- package/src/Utils/messages.d.ts +62 -0
- package/src/Utils/messages.js +2223 -0
- package/src/Utils/mobile-companion-crypto.js +191 -0
- package/src/Utils/modern-messages.d.ts +150 -0
- package/src/Utils/modern-messages.js +496 -0
- package/src/Utils/native-flow.d.ts +11 -0
- package/src/Utils/native-flow.js +115 -0
- package/src/Utils/newsletter-status.d.ts +158 -0
- package/src/Utils/newsletter-status.js +651 -0
- package/src/Utils/noise-handler.d.ts +20 -0
- package/src/Utils/noise-handler.js +200 -0
- package/src/Utils/offline-node-processor.d.ts +9 -0
- package/src/Utils/offline-node-processor.js +33 -0
- package/src/Utils/optional-media.d.ts +3 -0
- package/src/Utils/optional-media.js +45 -0
- package/src/Utils/payment-messages.d.ts +66 -0
- package/src/Utils/payment-messages.js +160 -0
- package/src/Utils/pre-key-manager.d.ts +25 -0
- package/src/Utils/pre-key-manager.js +95 -0
- package/src/Utils/process-message.d.ts +60 -0
- package/src/Utils/process-message.js +688 -0
- package/src/Utils/reporting-utils.d.ts +12 -0
- package/src/Utils/reporting-utils.js +256 -0
- package/src/Utils/scheduled-message.d.ts +51 -0
- package/src/Utils/scheduled-message.js +112 -0
- package/src/Utils/sender-key-memory.d.ts +19 -0
- package/src/Utils/sender-key-memory.js +51 -0
- package/src/Utils/signal.d.ts +82 -0
- package/src/Utils/signal.js +193 -0
- package/src/Utils/stanza-ack.d.ts +16 -0
- package/src/Utils/stanza-ack.js +30 -0
- package/src/Utils/status-stickers.d.ts +127 -0
- package/src/Utils/status-stickers.js +260 -0
- package/src/Utils/sync-action-utils.d.ts +2 -0
- package/src/Utils/sync-action-utils.js +44 -0
- package/src/Utils/tc-token-utils.d.ts +29 -0
- package/src/Utils/tc-token-utils.js +155 -0
- package/src/Utils/ttl-cache.d.ts +28 -0
- package/src/Utils/ttl-cache.js +120 -0
- package/src/Utils/use-mongo-auth-state.d.ts +21 -0
- package/src/Utils/use-mongo-auth-state.js +67 -0
- package/src/Utils/use-multi-file-auth-state.d.ts +11 -0
- package/src/Utils/use-multi-file-auth-state.js +106 -0
- package/src/Utils/use-mysql-auth-state.d.ts +19 -0
- package/src/Utils/use-mysql-auth-state.js +79 -0
- package/src/Utils/use-postgres-auth-state.d.ts +19 -0
- package/src/Utils/use-postgres-auth-state.js +79 -0
- package/src/Utils/use-redis-auth-state.d.ts +19 -0
- package/src/Utils/use-redis-auth-state.js +89 -0
- package/src/Utils/use-single-file-auth-state.d.ts +10 -0
- package/src/Utils/use-single-file-auth-state.js +108 -0
- package/src/Utils/use-sqlite-auth-state.d.ts +12 -0
- package/src/Utils/use-sqlite-auth-state.js +120 -0
- package/src/Utils/useNekoDBAuth.d.ts +19 -0
- package/src/Utils/useNekoDBAuth.js +111 -0
- package/src/Utils/username.d.ts +12 -0
- package/src/Utils/username.js +58 -0
- package/src/Utils/validate-connection.d.ts +43 -0
- package/src/Utils/validate-connection.js +277 -0
- package/src/Utils/voice-recognition.d.ts +53 -0
- package/src/Utils/voice-recognition.js +219 -0
- package/src/Voip/audio-feeder.d.ts +24 -0
- package/src/Voip/audio-feeder.js +268 -0
- package/src/Voip/index.d.ts +88 -0
- package/src/Voip/index.js +936 -0
- package/src/Voip/relay-transport.d.ts +5 -0
- package/src/Voip/relay-transport.js +824 -0
- package/src/Voip/signaling.d.ts +11 -0
- package/src/Voip/signaling.js +1099 -0
- package/src/Voip/types.d.ts +2 -0
- package/src/Voip/types.js +12 -0
- package/src/Voip/video-feeder.d.ts +24 -0
- package/src/Voip/video-feeder.js +268 -0
- package/src/Voip/wasm-engine.d.ts +26 -0
- package/src/Voip/wasm-engine.js +1307 -0
- package/src/Voip/worker-bootstrap.js +1023 -0
- package/src/WABinary/constants.d.ts +22 -0
- package/src/WABinary/constants.js +1300 -0
- package/src/WABinary/decode.d.ts +9 -0
- package/src/WABinary/decode.js +261 -0
- package/src/WABinary/encode.d.ts +2 -0
- package/src/WABinary/encode.js +219 -0
- package/src/WABinary/generic-utils.d.ts +76 -0
- package/src/WABinary/generic-utils.js +214 -0
- package/src/WABinary/index.d.ts +5 -0
- package/src/WABinary/index.js +5 -0
- package/src/WABinary/jid-utils.d.ts +30 -0
- package/src/WABinary/jid-utils.js +97 -0
- package/src/WABinary/types.d.ts +1 -0
- package/src/WABinary/types.js +0 -0
- package/src/WAM/BinaryInfo.d.ts +7 -0
- package/src/WAM/BinaryInfo.js +9 -0
- package/src/WAM/constants.d.ts +34926 -0
- package/src/WAM/constants.js +22852 -0
- package/src/WAM/encode.d.ts +1 -0
- package/src/WAM/encode.js +148 -0
- package/src/WAM/index.d.ts +3 -0
- package/src/WAM/index.js +3 -0
- package/src/WAUSync/Protocols/USyncContactProtocol.d.ts +36 -0
- package/src/WAUSync/Protocols/USyncContactProtocol.js +50 -0
- package/src/WAUSync/Protocols/USyncDeviceProtocol.d.ts +22 -0
- package/src/WAUSync/Protocols/USyncDeviceProtocol.js +51 -0
- package/src/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
- package/src/WAUSync/Protocols/USyncDisappearingModeProtocol.js +26 -0
- package/src/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
- package/src/WAUSync/Protocols/USyncStatusProtocol.js +37 -0
- package/src/WAUSync/Protocols/USyncUsernameProtocol.d.ts +9 -0
- package/src/WAUSync/Protocols/USyncUsernameProtocol.js +23 -0
- package/src/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +38 -0
- package/src/WAUSync/Protocols/UsyncBotProfileProtocol.js +49 -0
- package/src/WAUSync/Protocols/UsyncLIDProtocol.d.ts +14 -0
- package/src/WAUSync/Protocols/UsyncLIDProtocol.js +28 -0
- package/src/WAUSync/Protocols/index.d.ts +5 -0
- package/src/WAUSync/Protocols/index.js +5 -0
- package/src/WAUSync/USyncQuery.d.ts +20 -0
- package/src/WAUSync/USyncQuery.js +93 -0
- package/src/WAUSync/USyncUser.d.ts +16 -0
- package/src/WAUSync/USyncUser.js +30 -0
- package/src/WAUSync/index.d.ts +3 -0
- package/src/WAUSync/index.js +3 -0
- package/src/assets/wasm/README.md +76 -0
- package/src/assets/wasm/loader.js +5 -0
- package/src/assets/wasm/whatsapp.wasm +0 -0
- package/src/assets/wasm/worker-modules.js +273 -0
- package/src/index.d.ts +43 -0
- package/src/index.js +48 -0
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
import { proto } from '../../WAProto/index.js'
|
|
2
|
+
|
|
3
|
+
const requireObject = (value, name) => {
|
|
4
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
5
|
+
throw new TypeError(`${name} must be an object`)
|
|
6
|
+
}
|
|
7
|
+
return value
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const requireKey = (value, name = 'key') => {
|
|
11
|
+
requireObject(value, name)
|
|
12
|
+
if (!value.id) {
|
|
13
|
+
throw new TypeError(`${name}.id is required`)
|
|
14
|
+
}
|
|
15
|
+
return value
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const enumValue = (enumObject, value, fallback) => {
|
|
19
|
+
if (typeof value === 'number') return value
|
|
20
|
+
if (typeof value === 'string') {
|
|
21
|
+
const key = value.trim().toUpperCase()
|
|
22
|
+
if (key in enumObject) return enumObject[key]
|
|
23
|
+
}
|
|
24
|
+
return fallback
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const STATUS_NOTIFICATION_TYPES = Object.freeze({
|
|
28
|
+
...proto.Message.StatusNotificationMessage.StatusNotificationType,
|
|
29
|
+
STATUS_GROUP_STATUS_REPLY: 4
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const toSeconds = value => value instanceof Date ? Math.floor(value.getTime() / 1000) : value
|
|
33
|
+
const toMilliseconds = value => value instanceof Date ? value.getTime() : value
|
|
34
|
+
|
|
35
|
+
const makeInnerCommentMessage = content => {
|
|
36
|
+
const data = requireObject(content, 'comment.content')
|
|
37
|
+
if (data.raw && typeof data.raw === 'object') return data.raw
|
|
38
|
+
if (typeof data.text === 'string') {
|
|
39
|
+
return {
|
|
40
|
+
extendedTextMessage: proto.Message.ExtendedTextMessage.create({
|
|
41
|
+
text: data.text,
|
|
42
|
+
contextInfo: data.contextInfo
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const keys = Object.keys(data)
|
|
47
|
+
if (keys.some(key => key.endsWith('Message'))) return data
|
|
48
|
+
throw new TypeError('comment.content supports text, raw, or protobuf message fields')
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const makeQuestionMessage = input => {
|
|
52
|
+
const data = requireObject(input, 'question')
|
|
53
|
+
if (typeof data.text !== 'string' || !data.text.length) {
|
|
54
|
+
throw new TypeError('question.text is required')
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
questionMessage: proto.Message.FutureProofMessage.create({
|
|
58
|
+
message: {
|
|
59
|
+
extendedTextMessage: proto.Message.ExtendedTextMessage.create({
|
|
60
|
+
text: data.text,
|
|
61
|
+
contextInfo: {
|
|
62
|
+
...(data.contextInfo || {}),
|
|
63
|
+
isQuestion: true
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const makeQuestionResponseMessage = input => {
|
|
72
|
+
const data = requireObject(input, 'questionResponse')
|
|
73
|
+
requireKey(data.key, 'questionResponse.key')
|
|
74
|
+
return {
|
|
75
|
+
questionResponseMessage: proto.Message.QuestionResponseMessage.create({
|
|
76
|
+
key: data.key,
|
|
77
|
+
text: data.text ?? ''
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export const makeQuestionReplyMessage = input => {
|
|
83
|
+
const data = requireObject(input, 'questionReply')
|
|
84
|
+
if (typeof data.text !== 'string' || !data.text.length) {
|
|
85
|
+
throw new TypeError('questionReply.text is required')
|
|
86
|
+
}
|
|
87
|
+
if (data.serverQuestionId === undefined || data.serverQuestionId === null) {
|
|
88
|
+
throw new TypeError('questionReply.serverQuestionId is required')
|
|
89
|
+
}
|
|
90
|
+
const quoted = {
|
|
91
|
+
serverQuestionId: Number(data.serverQuestionId)
|
|
92
|
+
}
|
|
93
|
+
if (data.quotedQuestion) quoted.quotedQuestion = data.quotedQuestion
|
|
94
|
+
if (data.quotedResponse) quoted.quotedResponse = data.quotedResponse
|
|
95
|
+
return {
|
|
96
|
+
questionReplyMessage: proto.Message.FutureProofMessage.create({
|
|
97
|
+
message: {
|
|
98
|
+
extendedTextMessage: proto.Message.ExtendedTextMessage.create({
|
|
99
|
+
text: data.text,
|
|
100
|
+
contextInfo: {
|
|
101
|
+
...(data.contextInfo || {}),
|
|
102
|
+
questionReplyQuotedMessage: quoted
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export const makeStatusQuestionAnswerMessage = input => {
|
|
111
|
+
const data = requireObject(input, 'statusQuestionAnswer')
|
|
112
|
+
requireKey(data.key, 'statusQuestionAnswer.key')
|
|
113
|
+
return {
|
|
114
|
+
statusQuestionAnswerMessage: proto.Message.StatusQuestionAnswerMessage.create({
|
|
115
|
+
key: data.key,
|
|
116
|
+
text: data.text ?? ''
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export const makeStatusQuotedMessage = input => {
|
|
122
|
+
const data = requireObject(input, 'statusQuoted')
|
|
123
|
+
requireKey(data.originalStatusId, 'statusQuoted.originalStatusId')
|
|
124
|
+
const type = enumValue(
|
|
125
|
+
proto.Message.StatusQuotedMessage.StatusQuotedMessageType,
|
|
126
|
+
data.type,
|
|
127
|
+
proto.Message.StatusQuotedMessage.StatusQuotedMessageType.QUESTION_ANSWER
|
|
128
|
+
)
|
|
129
|
+
return {
|
|
130
|
+
statusQuotedMessage: proto.Message.StatusQuotedMessage.create({
|
|
131
|
+
type,
|
|
132
|
+
text: data.text,
|
|
133
|
+
thumbnail: data.thumbnail,
|
|
134
|
+
originalStatusId: data.originalStatusId
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export const makeStatusStickerInteractionMessage = input => {
|
|
140
|
+
const data = requireObject(input, 'statusStickerInteraction')
|
|
141
|
+
requireKey(data.key, 'statusStickerInteraction.key')
|
|
142
|
+
if (!data.stickerKey) {
|
|
143
|
+
throw new TypeError('statusStickerInteraction.stickerKey is required')
|
|
144
|
+
}
|
|
145
|
+
const type = enumValue(
|
|
146
|
+
proto.Message.StatusStickerInteractionMessage.StatusStickerType,
|
|
147
|
+
data.type,
|
|
148
|
+
proto.Message.StatusStickerInteractionMessage.StatusStickerType.REACTION
|
|
149
|
+
)
|
|
150
|
+
return {
|
|
151
|
+
statusStickerInteractionMessage: proto.Message.StatusStickerInteractionMessage.create({
|
|
152
|
+
key: data.key,
|
|
153
|
+
stickerKey: data.stickerKey,
|
|
154
|
+
type
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export const makeStatusNotificationMessage = input => {
|
|
160
|
+
const data = requireObject(input, 'statusNotification')
|
|
161
|
+
requireKey(data.responseMessageKey, 'statusNotification.responseMessageKey')
|
|
162
|
+
requireKey(data.originalMessageKey, 'statusNotification.originalMessageKey')
|
|
163
|
+
const type = enumValue(
|
|
164
|
+
STATUS_NOTIFICATION_TYPES,
|
|
165
|
+
data.type,
|
|
166
|
+
STATUS_NOTIFICATION_TYPES.UNKNOWN
|
|
167
|
+
)
|
|
168
|
+
return {
|
|
169
|
+
statusNotificationMessage: proto.Message.StatusNotificationMessage.create({
|
|
170
|
+
responseMessageKey: data.responseMessageKey,
|
|
171
|
+
originalMessageKey: data.originalMessageKey,
|
|
172
|
+
type
|
|
173
|
+
})
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export const makeNewsletterAdminInviteMessage = input => {
|
|
178
|
+
const data = requireObject(input, 'newsletterAdminInvite')
|
|
179
|
+
if (!data.newsletterJid) {
|
|
180
|
+
throw new TypeError('newsletterAdminInvite.newsletterJid is required')
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
newsletterAdminInviteMessage: proto.Message.NewsletterAdminInviteMessage.create({
|
|
184
|
+
newsletterJid: data.newsletterJid,
|
|
185
|
+
newsletterName: data.newsletterName,
|
|
186
|
+
jpegThumbnail: data.jpegThumbnail,
|
|
187
|
+
caption: data.caption,
|
|
188
|
+
inviteExpiration: data.inviteExpiration,
|
|
189
|
+
contextInfo: data.contextInfo
|
|
190
|
+
})
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export const makeNewsletterFollowerInviteMessage = input => {
|
|
195
|
+
const data = requireObject(input, 'newsletterFollowerInvite')
|
|
196
|
+
if (!data.newsletterJid) {
|
|
197
|
+
throw new TypeError('newsletterFollowerInvite.newsletterJid is required')
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
newsletterFollowerInviteMessageV2: proto.Message.NewsletterFollowerInviteMessage.create({
|
|
201
|
+
newsletterJid: data.newsletterJid,
|
|
202
|
+
newsletterName: data.newsletterName,
|
|
203
|
+
jpegThumbnail: data.jpegThumbnail,
|
|
204
|
+
caption: data.caption,
|
|
205
|
+
contextInfo: data.contextInfo
|
|
206
|
+
})
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export const makePollAddOptionMessage = input => {
|
|
211
|
+
const data = requireObject(input, 'pollAddOption')
|
|
212
|
+
requireKey(data.pollCreationMessageKey, 'pollAddOption.pollCreationMessageKey')
|
|
213
|
+
const addOption = typeof data.option === 'string'
|
|
214
|
+
? { optionName: data.option }
|
|
215
|
+
: data.addOption || data.option
|
|
216
|
+
if (!addOption?.optionName) {
|
|
217
|
+
throw new TypeError('pollAddOption.option is required')
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
pollAddOptionMessage: proto.Message.PollAddOptionMessage.create({
|
|
221
|
+
pollCreationMessageKey: data.pollCreationMessageKey,
|
|
222
|
+
addOption,
|
|
223
|
+
metadata: data.metadata
|
|
224
|
+
})
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export const makeCommentMessage = input => {
|
|
229
|
+
const data = requireObject(input, 'comment')
|
|
230
|
+
requireKey(data.targetMessageKey, 'comment.targetMessageKey')
|
|
231
|
+
const message = data.message || (data.content ? makeInnerCommentMessage(data.content) : null)
|
|
232
|
+
requireObject(message, 'comment.message')
|
|
233
|
+
return {
|
|
234
|
+
commentMessage: proto.Message.CommentMessage.create({
|
|
235
|
+
message,
|
|
236
|
+
targetMessageKey: data.targetMessageKey
|
|
237
|
+
})
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export const makeEventInviteMessage = input => {
|
|
242
|
+
const data = requireObject(input, 'eventInvite')
|
|
243
|
+
if (!data.eventId) {
|
|
244
|
+
throw new TypeError('eventInvite.eventId is required')
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
eventInviteMessage: proto.Message.EventInviteMessage.create({
|
|
248
|
+
contextInfo: data.contextInfo,
|
|
249
|
+
eventId: data.eventId,
|
|
250
|
+
eventTitle: data.eventTitle,
|
|
251
|
+
jpegThumbnail: data.jpegThumbnail,
|
|
252
|
+
startTime: toSeconds(data.startTime),
|
|
253
|
+
caption: data.caption,
|
|
254
|
+
isCanceled: data.isCanceled,
|
|
255
|
+
endTime: toSeconds(data.endTime),
|
|
256
|
+
callLink: data.callLink
|
|
257
|
+
})
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export const makeScheduledCallCreationMessage = input => {
|
|
262
|
+
const data = requireObject(input, 'scheduledCall')
|
|
263
|
+
if (!data.scheduledTimestampMs) {
|
|
264
|
+
throw new TypeError('scheduledCall.scheduledTimestampMs is required')
|
|
265
|
+
}
|
|
266
|
+
const callType = enumValue(
|
|
267
|
+
proto.Message.ScheduledCallCreationMessage.CallType,
|
|
268
|
+
data.callType,
|
|
269
|
+
proto.Message.ScheduledCallCreationMessage.CallType.UNKNOWN
|
|
270
|
+
)
|
|
271
|
+
return {
|
|
272
|
+
scheduledCallCreationMessage: proto.Message.ScheduledCallCreationMessage.create({
|
|
273
|
+
scheduledTimestampMs: toMilliseconds(data.scheduledTimestampMs),
|
|
274
|
+
callType,
|
|
275
|
+
title: data.title
|
|
276
|
+
})
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export const makeScheduledCallEditMessage = input => {
|
|
281
|
+
const data = requireObject(input, 'scheduledCallEdit')
|
|
282
|
+
requireKey(data.key, 'scheduledCallEdit.key')
|
|
283
|
+
const editType = enumValue(
|
|
284
|
+
proto.Message.ScheduledCallEditMessage.EditType,
|
|
285
|
+
data.editType,
|
|
286
|
+
proto.Message.ScheduledCallEditMessage.EditType.CANCEL
|
|
287
|
+
)
|
|
288
|
+
return {
|
|
289
|
+
scheduledCallEditMessage: proto.Message.ScheduledCallEditMessage.create({
|
|
290
|
+
key: data.key,
|
|
291
|
+
editType
|
|
292
|
+
})
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export const makeGroupStatusReactionMessage = input => {
|
|
297
|
+
const data = requireObject(input, 'groupStatusReaction')
|
|
298
|
+
requireKey(data.key, 'groupStatusReaction.key')
|
|
299
|
+
return {
|
|
300
|
+
groupStatusMessageV2: proto.Message.FutureProofMessage.create({
|
|
301
|
+
message: {
|
|
302
|
+
reactionMessage: proto.Message.ReactionMessage.create({
|
|
303
|
+
key: data.key,
|
|
304
|
+
text: data.text ?? '',
|
|
305
|
+
groupingKey: data.groupingKey,
|
|
306
|
+
senderTimestampMs: data.senderTimestampMs || Date.now()
|
|
307
|
+
})
|
|
308
|
+
}
|
|
309
|
+
})
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export const makeNewsletterStatusAttribution = input => {
|
|
314
|
+
const data = requireObject(input, 'newsletterStatus')
|
|
315
|
+
if (!data.newsletterJid) {
|
|
316
|
+
throw new TypeError('newsletterStatus.newsletterJid is required')
|
|
317
|
+
}
|
|
318
|
+
if (data.messageId === undefined || data.messageId === null) {
|
|
319
|
+
throw new TypeError('newsletterStatus.messageId is required')
|
|
320
|
+
}
|
|
321
|
+
return proto.StatusAttribution.create({
|
|
322
|
+
type: proto.StatusAttribution.Type.NEWSLETTER_STATUS,
|
|
323
|
+
actionUrl: data.actionUrl,
|
|
324
|
+
statusReshare: {
|
|
325
|
+
source: proto.StatusAttribution.StatusReshare.Source.CHANNEL_RESHARE,
|
|
326
|
+
metadata: {
|
|
327
|
+
duration: data.duration,
|
|
328
|
+
channelJid: data.newsletterJid,
|
|
329
|
+
channelMessageId: Number(data.messageId),
|
|
330
|
+
hasMultipleReshares: data.hasMultipleReshares ?? false
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
})
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export const makeGroupStatusAttribution = input => {
|
|
337
|
+
const data = requireObject(input, 'groupStatusAttribution')
|
|
338
|
+
if (!data.authorJid) {
|
|
339
|
+
throw new TypeError('groupStatusAttribution.authorJid is required')
|
|
340
|
+
}
|
|
341
|
+
return proto.StatusAttribution.create({
|
|
342
|
+
type: proto.StatusAttribution.Type.GROUP_STATUS,
|
|
343
|
+
actionUrl: data.actionUrl,
|
|
344
|
+
groupStatus: {
|
|
345
|
+
authorJid: data.authorJid
|
|
346
|
+
}
|
|
347
|
+
})
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export const STATUS_AUDIENCE_DEFAULT_LIST_NAME = 'Close friends'
|
|
351
|
+
export const STATUS_AUDIENCE_DEFAULT_EMOJI = '⭐'
|
|
352
|
+
|
|
353
|
+
export const makeStatusAudienceMetadata = input => {
|
|
354
|
+
const data = typeof input === 'string' ? { listName: input } : requireObject(input, 'statusAudience')
|
|
355
|
+
const audienceType = enumValue(
|
|
356
|
+
proto.ContextInfo.StatusAudienceMetadata.AudienceType,
|
|
357
|
+
data.audienceType,
|
|
358
|
+
proto.ContextInfo.StatusAudienceMetadata.AudienceType.CLOSE_FRIENDS
|
|
359
|
+
)
|
|
360
|
+
const listName = data.listName === undefined ? STATUS_AUDIENCE_DEFAULT_LIST_NAME : String(data.listName)
|
|
361
|
+
const listEmoji = data.listEmoji === undefined ? STATUS_AUDIENCE_DEFAULT_EMOJI : String(data.listEmoji)
|
|
362
|
+
return proto.ContextInfo.StatusAudienceMetadata.create({
|
|
363
|
+
audienceType,
|
|
364
|
+
listName,
|
|
365
|
+
listEmoji
|
|
366
|
+
})
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
export const makeMessageAssociation = input => {
|
|
370
|
+
const data = requireObject(input, 'messageAssociation')
|
|
371
|
+
const parentMessageKey = data.parentMessageKey ?? data.key
|
|
372
|
+
requireKey(parentMessageKey, 'messageAssociation.parentMessageKey')
|
|
373
|
+
const associationType = enumValue(
|
|
374
|
+
proto.MessageAssociation.AssociationType,
|
|
375
|
+
data.associationType ?? data.type,
|
|
376
|
+
proto.MessageAssociation.AssociationType.UNKNOWN
|
|
377
|
+
)
|
|
378
|
+
return proto.MessageAssociation.create({
|
|
379
|
+
associationType,
|
|
380
|
+
parentMessageKey,
|
|
381
|
+
messageIndex: data.messageIndex
|
|
382
|
+
})
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export const makeStatusAddYoursAssociation = input => {
|
|
386
|
+
const data = input && typeof input === 'object' && !Array.isArray(input) && input.id
|
|
387
|
+
? { key: input }
|
|
388
|
+
: requireObject(input, 'addYours')
|
|
389
|
+
const parentMessageKey = data.key ?? data.parentMessageKey
|
|
390
|
+
requireKey(parentMessageKey, 'addYours.key')
|
|
391
|
+
const associationType = enumValue(
|
|
392
|
+
proto.MessageAssociation.AssociationType,
|
|
393
|
+
data.type ?? data.associationType,
|
|
394
|
+
proto.MessageAssociation.AssociationType.STATUS_ADD_YOURS
|
|
395
|
+
)
|
|
396
|
+
return proto.MessageAssociation.create({
|
|
397
|
+
associationType,
|
|
398
|
+
parentMessageKey,
|
|
399
|
+
messageIndex: data.messageIndex
|
|
400
|
+
})
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
export const makeStatusMentionMessage = input => {
|
|
404
|
+
const data = requireObject(input, 'statusMention')
|
|
405
|
+
requireKey(data.key, 'statusMention.key')
|
|
406
|
+
const field = data.group ? 'groupStatusMentionMessage' : 'statusMentionMessage'
|
|
407
|
+
return {
|
|
408
|
+
[field]: proto.Message.FutureProofMessage.create({
|
|
409
|
+
message: {
|
|
410
|
+
protocolMessage: proto.Message.ProtocolMessage.create({
|
|
411
|
+
key: data.key,
|
|
412
|
+
type: proto.Message.ProtocolMessage.Type.STATUS_MENTION_MESSAGE
|
|
413
|
+
})
|
|
414
|
+
}
|
|
415
|
+
})
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const modernBuilders = [
|
|
420
|
+
['question', makeQuestionMessage],
|
|
421
|
+
['questionReply', makeQuestionReplyMessage],
|
|
422
|
+
['questionResponse', makeQuestionResponseMessage],
|
|
423
|
+
['statusQuestionAnswer', makeStatusQuestionAnswerMessage],
|
|
424
|
+
['statusQuoted', makeStatusQuotedMessage],
|
|
425
|
+
['statusStickerInteraction', makeStatusStickerInteractionMessage],
|
|
426
|
+
['statusNotification', makeStatusNotificationMessage],
|
|
427
|
+
['newsletterAdminInvite', makeNewsletterAdminInviteMessage],
|
|
428
|
+
['newsletterFollowerInvite', makeNewsletterFollowerInviteMessage],
|
|
429
|
+
['pollAddOption', makePollAddOptionMessage],
|
|
430
|
+
['comment', makeCommentMessage],
|
|
431
|
+
['eventInvite', makeEventInviteMessage],
|
|
432
|
+
['scheduledCall', makeScheduledCallCreationMessage],
|
|
433
|
+
['scheduledCallEdit', makeScheduledCallEditMessage],
|
|
434
|
+
['groupStatusReaction', makeGroupStatusReactionMessage],
|
|
435
|
+
['statusMention', makeStatusMentionMessage]
|
|
436
|
+
]
|
|
437
|
+
|
|
438
|
+
export const prepareModernMessageContent = content => {
|
|
439
|
+
if (!content || typeof content !== 'object' || Array.isArray(content)) return content
|
|
440
|
+
let output = { ...content }
|
|
441
|
+
const attributions = Array.isArray(output.contextInfo?.statusAttributions)
|
|
442
|
+
? [...output.contextInfo.statusAttributions]
|
|
443
|
+
: []
|
|
444
|
+
if (output.newsletterStatus) {
|
|
445
|
+
attributions.push(makeNewsletterStatusAttribution(output.newsletterStatus))
|
|
446
|
+
delete output.newsletterStatus
|
|
447
|
+
}
|
|
448
|
+
if (output.groupStatusAttribution) {
|
|
449
|
+
attributions.push(makeGroupStatusAttribution(output.groupStatusAttribution))
|
|
450
|
+
delete output.groupStatusAttribution
|
|
451
|
+
}
|
|
452
|
+
if (Array.isArray(output.statusAttributions)) {
|
|
453
|
+
attributions.push(...output.statusAttributions)
|
|
454
|
+
delete output.statusAttributions
|
|
455
|
+
}
|
|
456
|
+
const carried = []
|
|
457
|
+
const audience = output.statusAudience
|
|
458
|
+
if (audience !== undefined && audience !== null) {
|
|
459
|
+
carried.push('statusAudience')
|
|
460
|
+
output.contextInfo = {
|
|
461
|
+
...(output.contextInfo || {}),
|
|
462
|
+
statusAudienceMetadata: makeStatusAudienceMetadata(audience)
|
|
463
|
+
}
|
|
464
|
+
delete output.statusAudience
|
|
465
|
+
}
|
|
466
|
+
if (attributions.length) {
|
|
467
|
+
output.contextInfo = {
|
|
468
|
+
...(output.contextInfo || {}),
|
|
469
|
+
statusAttributions: attributions
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
if (output.addYours !== undefined && output.addYours !== null) {
|
|
473
|
+
carried.push('addYours')
|
|
474
|
+
output.messageAssociation = makeStatusAddYoursAssociation(output.addYours)
|
|
475
|
+
delete output.addYours
|
|
476
|
+
}
|
|
477
|
+
else if (output.messageAssociation !== undefined && output.messageAssociation !== null) {
|
|
478
|
+
carried.push('messageAssociation')
|
|
479
|
+
output.messageAssociation = makeMessageAssociation(output.messageAssociation)
|
|
480
|
+
}
|
|
481
|
+
for (const [key, builder] of modernBuilders) {
|
|
482
|
+
if (output[key] !== undefined && output[key] !== null) {
|
|
483
|
+
if (carried.length) {
|
|
484
|
+
throw new TypeError(
|
|
485
|
+
`${carried.join(' and ')} cannot be combined with ${key}: ${key} builds its own message and keeps no room for them. `
|
|
486
|
+
+ 'Build it with the low-level makers and generateWAMessageFromContent instead.'
|
|
487
|
+
)
|
|
488
|
+
}
|
|
489
|
+
return {
|
|
490
|
+
raw: true,
|
|
491
|
+
...builder(output[key])
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
return output
|
|
496
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const NATIVE_FLOW_NAMES: readonly string[]
|
|
2
|
+
export declare const WEB_SUPPORTED_INTERACTIVE_FLOWS: readonly string[]
|
|
3
|
+
export declare const NATIVE_FLOW_BUTTON_LIMIT: Readonly<{ quickReply: number; other: number }>
|
|
4
|
+
export declare function getNativeFlowNameByButtonName(name: string): string | undefined
|
|
5
|
+
export declare function isWebSupportedButtonName(name: string): boolean
|
|
6
|
+
export declare function checkNativeFlowButtons(buttons: ({ name?: string } | string)[]): {
|
|
7
|
+
ok: boolean
|
|
8
|
+
limit: number
|
|
9
|
+
problems: string[]
|
|
10
|
+
unsupported: string[]
|
|
11
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
export const NATIVE_FLOW_NAMES = Object.freeze([
|
|
2
|
+
'booking_confirmation',
|
|
3
|
+
'order_details',
|
|
4
|
+
'order_status',
|
|
5
|
+
'payment_status',
|
|
6
|
+
'payment_method',
|
|
7
|
+
'payment_reminder',
|
|
8
|
+
'message_with_link',
|
|
9
|
+
'message_with_link_status',
|
|
10
|
+
'quick_reply',
|
|
11
|
+
'cta_call',
|
|
12
|
+
'cta_url',
|
|
13
|
+
'cta_catalog',
|
|
14
|
+
'catalog_message',
|
|
15
|
+
'payment_info',
|
|
16
|
+
'cta_copy',
|
|
17
|
+
'mixed',
|
|
18
|
+
'galaxy_message',
|
|
19
|
+
'cta_app',
|
|
20
|
+
'call_permission_request',
|
|
21
|
+
'payment_request',
|
|
22
|
+
'api_signup',
|
|
23
|
+
'inapp_signup',
|
|
24
|
+
'form_message',
|
|
25
|
+
'menu_options',
|
|
26
|
+
'a2ui_reply_action',
|
|
27
|
+
'address_message',
|
|
28
|
+
'mpm'
|
|
29
|
+
])
|
|
30
|
+
|
|
31
|
+
const BUTTON_NAME_TO_FLOW = Object.freeze({
|
|
32
|
+
review_and_pay: 'order_details',
|
|
33
|
+
payment_info: 'payment_info',
|
|
34
|
+
review_order: 'order_status',
|
|
35
|
+
order_status: 'order_status',
|
|
36
|
+
payment_status: 'payment_status',
|
|
37
|
+
payment_method: 'payment_method',
|
|
38
|
+
open_webview: 'message_with_link',
|
|
39
|
+
message_with_link_status: 'message_with_link_status',
|
|
40
|
+
cta_url: 'cta_url',
|
|
41
|
+
cta_call: 'cta_call',
|
|
42
|
+
quick_reply: 'quick_reply',
|
|
43
|
+
catalog_message: 'catalog_message',
|
|
44
|
+
cta_catalog: 'cta_catalog',
|
|
45
|
+
cta_copy: 'cta_copy',
|
|
46
|
+
galaxy_message: 'galaxy_message',
|
|
47
|
+
payment_reminder: 'payment_reminder',
|
|
48
|
+
booking_confirmation: 'booking_confirmation',
|
|
49
|
+
call_permission_request: 'call_permission_request',
|
|
50
|
+
payment_request: 'payment_request',
|
|
51
|
+
api_signup: 'api_signup',
|
|
52
|
+
inapp_signup: 'inapp_signup',
|
|
53
|
+
cta_app: 'cta_app',
|
|
54
|
+
form_message: 'form_message',
|
|
55
|
+
address_message: 'address_message',
|
|
56
|
+
mpm: 'mpm'
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
export const WEB_SUPPORTED_INTERACTIVE_FLOWS = Object.freeze([
|
|
60
|
+
'quick_reply',
|
|
61
|
+
'cta_call',
|
|
62
|
+
'cta_url',
|
|
63
|
+
'cta_catalog',
|
|
64
|
+
'catalog_message',
|
|
65
|
+
'cta_copy',
|
|
66
|
+
'galaxy_message',
|
|
67
|
+
'order_status',
|
|
68
|
+
'payment_reminder',
|
|
69
|
+
'booking_confirmation',
|
|
70
|
+
'payment_request',
|
|
71
|
+
'api_signup',
|
|
72
|
+
'inapp_signup',
|
|
73
|
+
'cta_app',
|
|
74
|
+
'form_message'
|
|
75
|
+
])
|
|
76
|
+
|
|
77
|
+
export const NATIVE_FLOW_BUTTON_LIMIT = Object.freeze({
|
|
78
|
+
quickReply: 10,
|
|
79
|
+
other: 3
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
export const getNativeFlowNameByButtonName = (name) => BUTTON_NAME_TO_FLOW[name]
|
|
83
|
+
|
|
84
|
+
export const isWebSupportedButtonName = (name) => {
|
|
85
|
+
const flow = getNativeFlowNameByButtonName(name)
|
|
86
|
+
return flow !== undefined && WEB_SUPPORTED_INTERACTIVE_FLOWS.includes(flow)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export const checkNativeFlowButtons = (buttons) => {
|
|
90
|
+
const list = (Array.isArray(buttons) ? buttons : []).map(button => (typeof button === 'string' ? { name: button } : button))
|
|
91
|
+
const problems = []
|
|
92
|
+
|
|
93
|
+
if (!list.length) {
|
|
94
|
+
return { ok: true, limit: NATIVE_FLOW_BUTTON_LIMIT.other, problems, unsupported: [] }
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const firstIsQuickReply = list[0]?.name === 'quick_reply'
|
|
98
|
+
const limit = firstIsQuickReply ? NATIVE_FLOW_BUTTON_LIMIT.quickReply : NATIVE_FLOW_BUTTON_LIMIT.other
|
|
99
|
+
|
|
100
|
+
if (list.length > limit) {
|
|
101
|
+
problems.push(`WhatsApp Web renders at most ${limit} buttons when the first one is ${firstIsQuickReply ? 'quick_reply' : 'not quick_reply'}, got ${list.length}`)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const unsupported = [...new Set(list.map(button => button?.name).filter(name => !isWebSupportedButtonName(name)))]
|
|
105
|
+
for (const name of unsupported) {
|
|
106
|
+
problems.push(`"${name}" is not a native flow WhatsApp Web or iOS can render, only Android shows it`)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const mixesKinds = list.slice(1).some(button => (button?.name === 'quick_reply') !== firstIsQuickReply)
|
|
110
|
+
if (mixesKinds) {
|
|
111
|
+
problems.push('quick_reply buttons cannot be mixed with other button types in one message')
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return { ok: problems.length === 0, limit, problems, unsupported }
|
|
115
|
+
}
|