@kyyinfinite/baileys 2.0.0 → 2.1.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/LICENSE +21 -0
- package/README.md +546 -1648
- package/lib/Kyyinfinite/Simple/KyyMessage.js +46 -0
- package/lib/Kyyinfinite/Simple/MediaBuilder.js +9 -3
- package/lib/Kyyinfinite/Simple/MessageBuilder.js +16 -2
- package/lib/Kyyinfinite/Simple/SimpleClient.js +37 -0
- package/lib/Kyyinfinite/Simple/TextBuilder.js +8 -2
- package/lib/Kyyinfinite/Simple/UniversalMediaBuilder.js +21 -0
- package/lib/Kyyinfinite/Simple/index.d.ts +94 -3
- package/lib/Kyyinfinite/Simple/index.js +8 -1
- package/lib/Kyyinfinite/Simple/jid.js +55 -0
- package/lib/Kyyinfinite/Simple/messageUtils.js +49 -0
- package/lib/Kyyinfinite/Simple/parseMessage.js +55 -0
- package/package.json +19 -8
- package/test/core.test.js +38 -0
- package/test/simple-api.test.js +183 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { downloadMediaMessage } from '../../Utils/messages.js'
|
|
2
|
+
|
|
3
|
+
export class KyyMessage {
|
|
4
|
+
constructor(sock, message) {
|
|
5
|
+
if (!sock) throw new Error('Socket is required')
|
|
6
|
+
if (!message) throw new TypeError('A WhatsApp message is required')
|
|
7
|
+
this.sock = sock
|
|
8
|
+
this.message = message
|
|
9
|
+
this.key = message.key || message
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
get id() { return this.key?.id }
|
|
13
|
+
get jid() { return this.key?.remoteJid }
|
|
14
|
+
get sender() { return this.key?.participant || this.key?.remoteJid }
|
|
15
|
+
get fromMe() { return Boolean(this.key?.fromMe) }
|
|
16
|
+
|
|
17
|
+
reply(content, options = {}) {
|
|
18
|
+
const message = typeof content === 'string' ? { text: content } : { ...(content || {}) }
|
|
19
|
+
const sendOptions = { ...(options || {}), quoted: this.message }
|
|
20
|
+
return this.sock.sendMessage(this.jid, message, sendOptions)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
react(text = '') {
|
|
24
|
+
return this.sock.sendMessage(this.jid, { react: { text: String(text), key: this.key } })
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
edit(content, options = {}) {
|
|
28
|
+
const message = typeof content === 'string' ? { text: content } : { ...(content || {}) }
|
|
29
|
+
message.edit = this.key
|
|
30
|
+
return this.sock.sendMessage(this.jid, message, options)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
delete() {
|
|
34
|
+
return this.sock.sendMessage(this.jid, { delete: this.key })
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
forward(jid = this.jid, force = false) {
|
|
38
|
+
return this.sock.sendMessage(jid, { forward: this.message, force })
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
download(type = 'buffer', options = {}, ctx) {
|
|
42
|
+
return downloadMediaMessage(this.message, type, options, ctx)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
raw() { return this.message }
|
|
46
|
+
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import { applyAutoMentions, resolveMedia } from './messageUtils.js'
|
|
2
|
+
|
|
1
3
|
export class MediaBuilder {
|
|
2
4
|
constructor(sock, type, media) {
|
|
3
5
|
this.sock = sock
|
|
4
6
|
this.type = type
|
|
5
|
-
this.content = { [type]: media }
|
|
7
|
+
this.content = { [type]: resolveMedia(media) }
|
|
8
|
+
this._autoMentions = true
|
|
9
|
+
this._sendOptions = {}
|
|
6
10
|
}
|
|
7
11
|
|
|
8
12
|
caption(value) { this.content.caption = String(value ?? ''); return this }
|
|
@@ -10,6 +14,8 @@ export class MediaBuilder {
|
|
|
10
14
|
mimetype(value) { this.content.mimetype = value; return this }
|
|
11
15
|
context(value) { this.content.contextInfo = value || {}; return this }
|
|
12
16
|
mentions(value) { this.content.mentions = Array.isArray(value) ? [...value] : []; return this }
|
|
17
|
+
autoMentions(value = true) { this._autoMentions = Boolean(value); return this }
|
|
18
|
+
quoted(message) { this._sendOptions.quoted = message; return this }
|
|
13
19
|
payload(value) { Object.assign(this.content, value || {}); return this }
|
|
14
20
|
viewOnce(value = true) { this.content.viewOnce = Boolean(value); return this }
|
|
15
21
|
ptt(value = true) { this.content.ptt = Boolean(value); return this }
|
|
@@ -26,10 +32,10 @@ export class MediaBuilder {
|
|
|
26
32
|
thumbnail(value) { this.content.jpegThumbnail = value; return this }
|
|
27
33
|
|
|
28
34
|
build() {
|
|
29
|
-
return { ...this.content }
|
|
35
|
+
return applyAutoMentions({ ...this.content }, this._autoMentions)
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
send(jid, options = {}) {
|
|
33
|
-
return this.sock.sendMessage(jid, this.build(), options)
|
|
39
|
+
return this.sock.sendMessage(jid, this.build(), { ...this._sendOptions, ...(options || {}) })
|
|
34
40
|
}
|
|
35
41
|
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import { applyAutoMentions, resolveMediaContent } from './messageUtils.js'
|
|
2
|
+
|
|
1
3
|
export class MessageBuilder {
|
|
2
4
|
constructor(sock, content = {}) {
|
|
3
5
|
if (!sock) throw new Error('Socket is required')
|
|
4
6
|
this.sock = sock
|
|
5
7
|
this.content = { ...content }
|
|
8
|
+
this._autoMentions = true
|
|
9
|
+
this._sendOptions = {}
|
|
6
10
|
}
|
|
7
11
|
|
|
8
12
|
payload(value) {
|
|
@@ -21,6 +25,16 @@ export class MessageBuilder {
|
|
|
21
25
|
return this
|
|
22
26
|
}
|
|
23
27
|
|
|
28
|
+
autoMentions(value = true) {
|
|
29
|
+
this._autoMentions = Boolean(value)
|
|
30
|
+
return this
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
quoted(message) {
|
|
34
|
+
this._sendOptions.quoted = message
|
|
35
|
+
return this
|
|
36
|
+
}
|
|
37
|
+
|
|
24
38
|
viewOnce(value = true) {
|
|
25
39
|
this.content.viewOnce = Boolean(value)
|
|
26
40
|
return this
|
|
@@ -32,10 +46,10 @@ export class MessageBuilder {
|
|
|
32
46
|
}
|
|
33
47
|
|
|
34
48
|
build() {
|
|
35
|
-
return { ...this.content }
|
|
49
|
+
return applyAutoMentions(resolveMediaContent({ ...this.content }), this._autoMentions)
|
|
36
50
|
}
|
|
37
51
|
|
|
38
52
|
send(jid, options = {}) {
|
|
39
|
-
return this.sock.sendMessage(jid, this.build(), options)
|
|
53
|
+
return this.sock.sendMessage(jid, this.build(), { ...this._sendOptions, ...(options || {}) })
|
|
40
54
|
}
|
|
41
55
|
}
|
|
@@ -6,6 +6,11 @@ import { createCarouselBuilder } from './CarouselBuilder.js'
|
|
|
6
6
|
import { createAIBuilder } from './AIBuilder.js'
|
|
7
7
|
import { createFoadBuilder, createFoad2Builder } from './FoadBuilder.js'
|
|
8
8
|
import { Toolkit, Button, ButtonV2, Carousel, AIRich, Foad, Foad2 } from '../wrapper.js'
|
|
9
|
+
import { KyyMessage } from './KyyMessage.js'
|
|
10
|
+
import { UniversalMediaBuilder } from './UniversalMediaBuilder.js'
|
|
11
|
+
import { parseMessage } from './parseMessage.js'
|
|
12
|
+
import { applyAutoMentions, extractMentions, resolveMedia, resolveMediaContent, quotedOptions } from './messageUtils.js'
|
|
13
|
+
import { parseJid, normalizeJid, jidUser, jidServer, jidDevice, isGroupJid, isPrivateJid, isBroadcastJid, isStatusJid, isNewsletterJid, isLidJid, makeJid } from './jid.js'
|
|
9
14
|
|
|
10
15
|
export class SimpleClient {
|
|
11
16
|
constructor(sock) {
|
|
@@ -18,6 +23,38 @@ export class SimpleClient {
|
|
|
18
23
|
}
|
|
19
24
|
|
|
20
25
|
text(text = '') { return new TextBuilder(this.sock, text) }
|
|
26
|
+
media(media) { return new UniversalMediaBuilder(this.sock, media) }
|
|
27
|
+
wrapMessage(message) { return new KyyMessage(this.sock, message) }
|
|
28
|
+
parseMessage(message, options = {}) { return parseMessage(message, options) }
|
|
29
|
+
send(jid, content, options = {}) {
|
|
30
|
+
const { autoMentions = true, ...sendOptions } = options || {}
|
|
31
|
+
const message = typeof content === 'string' ? { text: content } : resolveMediaContent({ ...(content || {}) })
|
|
32
|
+
return this.sock.sendMessage(jid, applyAutoMentions(message, autoMentions !== false), sendOptions)
|
|
33
|
+
}
|
|
34
|
+
quoted(message, content, options = {}) {
|
|
35
|
+
return this.send(this.wrapMessage(message).jid, content, quotedOptions(message, options))
|
|
36
|
+
}
|
|
37
|
+
mentions(text) { return extractMentions(text) }
|
|
38
|
+
resolveMedia(media) { return resolveMedia(media) }
|
|
39
|
+
resolveMediaContent(content) { return resolveMediaContent(content) }
|
|
40
|
+
jid(value) { return normalizeJid(value) }
|
|
41
|
+
parseJid(value) { return parseJid(value) }
|
|
42
|
+
jidUser(value) { return jidUser(value) }
|
|
43
|
+
jidServer(value) { return jidServer(value) }
|
|
44
|
+
jidDevice(value) { return jidDevice(value) }
|
|
45
|
+
isGroup(value) { return isGroupJid(value) }
|
|
46
|
+
isPrivate(value) { return isPrivateJid(value) }
|
|
47
|
+
isBroadcast(value) { return isBroadcastJid(value) }
|
|
48
|
+
isStatus(value) { return isStatusJid(value) }
|
|
49
|
+
isNewsletter(value) { return isNewsletterJid(value) }
|
|
50
|
+
isLid(value) { return isLidJid(value) }
|
|
51
|
+
makeJid(user, server = 's.whatsapp.net', device = null) { return makeJid(user, server, device) }
|
|
52
|
+
reply(message, content, options = {}) { return this.wrapMessage(message).reply(content, options) }
|
|
53
|
+
reactTo(message, text = '') { return this.wrapMessage(message).react(text) }
|
|
54
|
+
editMessage(message, content, options = {}) { return this.wrapMessage(message).edit(content, options) }
|
|
55
|
+
deleteMessage(message) { return this.wrapMessage(message).delete() }
|
|
56
|
+
forwardMessage(message, jid, force = false) { return this.wrapMessage(message).forward(jid, force) }
|
|
57
|
+
downloadMessage(message, type = 'buffer', options = {}, ctx) { return this.wrapMessage(message).download(type, options, ctx) }
|
|
21
58
|
image(media) { return new MediaBuilder(this.sock, 'image', media) }
|
|
22
59
|
video(media) { return new MediaBuilder(this.sock, 'video', media) }
|
|
23
60
|
audio(media) { return new MediaBuilder(this.sock, 'audio', media) }
|
|
@@ -1,22 +1,28 @@
|
|
|
1
|
+
import { applyAutoMentions } from './messageUtils.js'
|
|
2
|
+
|
|
1
3
|
export class TextBuilder {
|
|
2
4
|
constructor(sock, text = '') {
|
|
3
5
|
this.sock = sock
|
|
4
6
|
this.content = { text: String(text ?? '') }
|
|
7
|
+
this._autoMentions = true
|
|
8
|
+
this._sendOptions = {}
|
|
5
9
|
}
|
|
6
10
|
|
|
7
11
|
text(value) { this.content.text = String(value ?? ''); return this }
|
|
8
12
|
footer(value) { this.content.footer = String(value ?? ''); return this }
|
|
9
13
|
context(value) { this.content.contextInfo = value || {}; return this }
|
|
10
14
|
mentions(value) { this.content.mentions = Array.isArray(value) ? [...value] : []; return this }
|
|
15
|
+
autoMentions(value = true) { this._autoMentions = Boolean(value); return this }
|
|
16
|
+
quoted(message) { this._sendOptions.quoted = message; return this }
|
|
11
17
|
viewOnce(value = true) { this.content.viewOnce = Boolean(value); return this }
|
|
12
18
|
edit(key) { this.content.edit = key; return this }
|
|
13
19
|
payload(value) { Object.assign(this.content, value || {}); return this }
|
|
14
20
|
|
|
15
21
|
build() {
|
|
16
|
-
return { ...this.content }
|
|
22
|
+
return applyAutoMentions({ ...this.content }, this._autoMentions)
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
send(jid, options = {}) {
|
|
20
|
-
return this.sock.sendMessage(jid, { ...this.
|
|
26
|
+
return this.sock.sendMessage(jid, this.build(), { ...this._sendOptions, ...(options || {}) })
|
|
21
27
|
}
|
|
22
28
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { MediaBuilder } from './MediaBuilder.js'
|
|
2
|
+
|
|
3
|
+
export class UniversalMediaBuilder extends MediaBuilder {
|
|
4
|
+
constructor(sock, media) {
|
|
5
|
+
super(sock, 'image', media)
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
_setType(type) {
|
|
9
|
+
const current = this.content[this.type]
|
|
10
|
+
delete this.content[this.type]
|
|
11
|
+
this.type = type
|
|
12
|
+
this.content[type] = current
|
|
13
|
+
return this
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
asImage() { return this._setType('image') }
|
|
17
|
+
asVideo() { return this._setType('video') }
|
|
18
|
+
asAudio() { return this._setType('audio') }
|
|
19
|
+
asDocument() { return this._setType('document') }
|
|
20
|
+
asSticker() { return this._setType('sticker') }
|
|
21
|
+
}
|
|
@@ -4,6 +4,32 @@ export declare class SimpleClient {
|
|
|
4
4
|
readonly wrapper: Record<string, any>
|
|
5
5
|
constructor(sock: any)
|
|
6
6
|
text(text?: string): TextBuilder
|
|
7
|
+
media(media: any): UniversalMediaBuilder
|
|
8
|
+
wrapMessage(message: any): KyyMessage
|
|
9
|
+
parseMessage(message: any, options?: { prefix?: string, commandMode?: string }): any
|
|
10
|
+
send(jid: string, content: string | Record<string, any>, options?: Record<string, any> & { autoMentions?: boolean }): Promise<any>
|
|
11
|
+
quoted(message: any, content: string | Record<string, any>, options?: Record<string, any> & { autoMentions?: boolean }): Promise<any>
|
|
12
|
+
mentions(text: string): string[]
|
|
13
|
+
resolveMedia(media: any): any
|
|
14
|
+
resolveMediaContent(content: Record<string, any>): Record<string, any>
|
|
15
|
+
jid(value: string): string
|
|
16
|
+
parseJid(value: string): any
|
|
17
|
+
jidUser(value: string): string | null
|
|
18
|
+
jidServer(value: string): string | null
|
|
19
|
+
jidDevice(value: string): string | null
|
|
20
|
+
isGroup(value: string): boolean
|
|
21
|
+
isPrivate(value: string): boolean
|
|
22
|
+
isBroadcast(value: string): boolean
|
|
23
|
+
isStatus(value: string): boolean
|
|
24
|
+
isNewsletter(value: string): boolean
|
|
25
|
+
isLid(value: string): boolean
|
|
26
|
+
makeJid(user: string | number, server?: string, device?: string | number | null): string
|
|
27
|
+
reply(message: any, content: string | Record<string, any>, options?: Record<string, any>): Promise<any>
|
|
28
|
+
reactTo(message: any, text?: string): Promise<any>
|
|
29
|
+
editMessage(message: any, content: string | Record<string, any>, options?: Record<string, any>): Promise<any>
|
|
30
|
+
deleteMessage(message: any): Promise<any>
|
|
31
|
+
forwardMessage(message: any, jid?: string, force?: boolean): Promise<any>
|
|
32
|
+
downloadMessage(message: any, type?: 'buffer' | 'stream', options?: Record<string, any>, ctx?: any): Promise<any>
|
|
7
33
|
image(media: any): MediaBuilder
|
|
8
34
|
video(media: any): MediaBuilder
|
|
9
35
|
audio(media: any): MediaBuilder
|
|
@@ -44,12 +70,11 @@ export declare class TextBuilder {
|
|
|
44
70
|
footer(value: string): this
|
|
45
71
|
context(value: Record<string, any>): this
|
|
46
72
|
mentions(value: string[]): this
|
|
73
|
+
autoMentions(value?: boolean): this
|
|
74
|
+
quoted(message: any): this
|
|
47
75
|
viewOnce(value?: boolean): this
|
|
48
76
|
edit(key: any): this
|
|
49
77
|
payload(value: Record<string, any>): this
|
|
50
|
-
mentions(value: string[]): this
|
|
51
|
-
viewOnce(value?: boolean): this
|
|
52
|
-
edit(key: any): this
|
|
53
78
|
build(): Record<string, any>
|
|
54
79
|
send(jid: string, options?: Record<string, any>): Promise<any>
|
|
55
80
|
}
|
|
@@ -62,6 +87,8 @@ export declare class MediaBuilder {
|
|
|
62
87
|
context(value: Record<string, any>): this
|
|
63
88
|
payload(value: Record<string, any>): this
|
|
64
89
|
mentions(value: string[]): this
|
|
90
|
+
autoMentions(value?: boolean): this
|
|
91
|
+
quoted(message: any): this
|
|
65
92
|
viewOnce(value?: boolean): this
|
|
66
93
|
ptt(value?: boolean): this
|
|
67
94
|
voice(value?: boolean): this
|
|
@@ -125,6 +152,8 @@ export declare class MessageBuilder {
|
|
|
125
152
|
payload(value: Record<string, any>): this
|
|
126
153
|
context(value: Record<string, any>): this
|
|
127
154
|
mentions(value: string[]): this
|
|
155
|
+
autoMentions(value?: boolean): this
|
|
156
|
+
quoted(message: any): this
|
|
128
157
|
viewOnce(value?: boolean): this
|
|
129
158
|
edit(key: any): this
|
|
130
159
|
build(): Record<string, any>
|
|
@@ -139,3 +168,65 @@ export declare function createButtonV2Builder(sock: any, ...args: any[]): any
|
|
|
139
168
|
export declare function createCarouselBuilder(sock: any, ...args: any[]): CarouselBuilder
|
|
140
169
|
export declare function createFoadBuilder(sock: any, ...args: any[]): any
|
|
141
170
|
export declare function createFoad2Builder(sock: any, ...args: any[]): any
|
|
171
|
+
|
|
172
|
+
export declare class KyyMessage {
|
|
173
|
+
readonly sock: any
|
|
174
|
+
readonly message: any
|
|
175
|
+
readonly key: any
|
|
176
|
+
readonly id: any
|
|
177
|
+
readonly jid: any
|
|
178
|
+
readonly sender: any
|
|
179
|
+
readonly fromMe: boolean
|
|
180
|
+
constructor(sock: any, message: any)
|
|
181
|
+
reply(content: string | Record<string, any>, options?: Record<string, any>): Promise<any>
|
|
182
|
+
react(text?: string): Promise<any>
|
|
183
|
+
edit(content: string | Record<string, any>, options?: Record<string, any>): Promise<any>
|
|
184
|
+
delete(): Promise<any>
|
|
185
|
+
forward(jid?: string, force?: boolean): Promise<any>
|
|
186
|
+
download(type?: 'buffer' | 'stream', options?: Record<string, any>, ctx?: any): Promise<any>
|
|
187
|
+
raw(): any
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export declare class UniversalMediaBuilder extends MediaBuilder {
|
|
191
|
+
constructor(sock: any, media: any)
|
|
192
|
+
asImage(): this
|
|
193
|
+
asVideo(): this
|
|
194
|
+
asAudio(): this
|
|
195
|
+
asDocument(): this
|
|
196
|
+
asSticker(): this
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export declare function parseMessage(message: any, options?: { prefix?: string, commandMode?: string }): {
|
|
200
|
+
message: any
|
|
201
|
+
content: any
|
|
202
|
+
messageType: any
|
|
203
|
+
text: string
|
|
204
|
+
command: string
|
|
205
|
+
args: string[]
|
|
206
|
+
jid: any
|
|
207
|
+
sender: any
|
|
208
|
+
isGroup: boolean
|
|
209
|
+
isReply: boolean
|
|
210
|
+
quoted: any
|
|
211
|
+
key: any
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export declare function parseJid(jid: string): { user: string, device: string | null, server: string, jid: string } | null
|
|
215
|
+
export declare function normalizeJid(jid: string): string
|
|
216
|
+
export declare function jidUser(jid: string): string | null
|
|
217
|
+
export declare function jidServer(jid: string): string | null
|
|
218
|
+
export declare function jidDevice(jid: string): string | null
|
|
219
|
+
export declare function isGroupJid(jid: string): boolean
|
|
220
|
+
export declare function isPrivateJid(jid: string): boolean
|
|
221
|
+
export declare function isBroadcastJid(jid: string): boolean
|
|
222
|
+
export declare function isStatusJid(jid: string): boolean
|
|
223
|
+
export declare function isNewsletterJid(jid: string): boolean
|
|
224
|
+
export declare function isLidJid(jid: string): boolean
|
|
225
|
+
export declare function makeJid(user: string | number, server?: string, device?: string | number | null): string
|
|
226
|
+
|
|
227
|
+
export declare function extractMentions(text: string): string[]
|
|
228
|
+
export declare function getMessageText(content: Record<string, any>): string
|
|
229
|
+
export declare function applyAutoMentions(content: Record<string, any>, enabled?: boolean): Record<string, any>
|
|
230
|
+
export declare function resolveMedia(media: any): any
|
|
231
|
+
export declare function resolveMediaContent(content: Record<string, any>): Record<string, any>
|
|
232
|
+
export declare function quotedOptions(message: any, options?: Record<string, any>): Record<string, any>
|
|
@@ -15,7 +15,7 @@ export function createKyyinfinite(sock) {
|
|
|
15
15
|
|
|
16
16
|
export function attachKyyinfinite(sock) {
|
|
17
17
|
const api = new SimpleClient(sock)
|
|
18
|
-
const names = ['text', 'image', 'video', 'audio', 'voice', 'document', 'sticker', 'ptv', 'gif', 'message', 'poll', 'event', 'album', 'contacts', 'location', 'react', 'groupInvite', 'product', 'requestPhoneNumber', 'sharePhoneNumber', 'pin', 'forward', 'delete', 'disappearing', 'limitSharing', 'button', 'buttonV2', 'carousel', 'ai', 'foad', 'foad2']
|
|
18
|
+
const names = ['text', 'media', 'wrapMessage', 'parseMessage', 'jid', 'parseJid', 'jidUser', 'jidServer', 'jidDevice', 'isGroup', 'isPrivate', 'isBroadcast', 'isStatus', 'isNewsletter', 'isLid', 'makeJid', 'reply', 'reactTo', 'editMessage', 'deleteMessage', 'forwardMessage', 'downloadMessage', 'image', 'video', 'audio', 'voice', 'document', 'sticker', 'ptv', 'gif', 'message', 'poll', 'event', 'album', 'contacts', 'location', 'react', 'groupInvite', 'product', 'requestPhoneNumber', 'sharePhoneNumber', 'pin', 'forward', 'delete', 'disappearing', 'limitSharing', 'button', 'buttonV2', 'carousel', 'ai', 'foad', 'foad2']
|
|
19
19
|
|
|
20
20
|
for (const name of names) {
|
|
21
21
|
if (name in sock) continue
|
|
@@ -29,3 +29,10 @@ export function attachKyyinfinite(sock) {
|
|
|
29
29
|
|
|
30
30
|
return sock
|
|
31
31
|
}
|
|
32
|
+
|
|
33
|
+
export { KyyMessage } from './KyyMessage.js'
|
|
34
|
+
export { UniversalMediaBuilder } from './UniversalMediaBuilder.js'
|
|
35
|
+
export { parseMessage } from './parseMessage.js'
|
|
36
|
+
export * from './jid.js'
|
|
37
|
+
|
|
38
|
+
export * from './messageUtils.js'
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const JID_RE = /^([^:@\s]+)(?::([^@\s]+))?@([^@\s]+)$/
|
|
2
|
+
|
|
3
|
+
export function parseJid(jid) {
|
|
4
|
+
if (typeof jid !== 'string' || !jid) return null
|
|
5
|
+
const match = jid.match(JID_RE)
|
|
6
|
+
if (!match) return null
|
|
7
|
+
return { user: match[1], device: match[2] || null, server: match[3], jid }
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function normalizeJid(jid) {
|
|
11
|
+
if (typeof jid !== 'string') return jid
|
|
12
|
+
return jid.trim()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function jidUser(jid) {
|
|
16
|
+
return parseJid(jid)?.user || null
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function jidServer(jid) {
|
|
20
|
+
return parseJid(jid)?.server || null
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function jidDevice(jid) {
|
|
24
|
+
return parseJid(jid)?.device || null
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function isGroupJid(jid) {
|
|
28
|
+
return jidServer(jid) === 'g.us'
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function isPrivateJid(jid) {
|
|
32
|
+
const server = jidServer(jid)
|
|
33
|
+
return server === 's.whatsapp.net' || server === 'lid'
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function isBroadcastJid(jid) {
|
|
37
|
+
return jidServer(jid) === 'broadcast'
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function isStatusJid(jid) {
|
|
41
|
+
return jid === 'status@broadcast'
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function isNewsletterJid(jid) {
|
|
45
|
+
return jidServer(jid) === 'newsletter'
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function isLidJid(jid) {
|
|
49
|
+
return jidServer(jid) === 'lid'
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function makeJid(user, server = 's.whatsapp.net', device = null) {
|
|
53
|
+
if (user == null || user === '') throw new TypeError('JID user is required')
|
|
54
|
+
return `${String(user)}${device != null ? `:${device}` : ''}@${server}`
|
|
55
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const MENTION_RE = /(^|\s)@(\d{5,16})(?=\s|$|[.,!?])/g
|
|
2
|
+
|
|
3
|
+
export function extractMentions(text) {
|
|
4
|
+
if (typeof text !== 'string' || !text) return []
|
|
5
|
+
const result = []
|
|
6
|
+
const seen = new Set()
|
|
7
|
+
for (const match of text.matchAll(MENTION_RE)) {
|
|
8
|
+
const jid = `${match[2]}@s.whatsapp.net`
|
|
9
|
+
if (!seen.has(jid)) {
|
|
10
|
+
seen.add(jid)
|
|
11
|
+
result.push(jid)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return result
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function getMessageText(content) {
|
|
18
|
+
if (!content || typeof content !== 'object') return ''
|
|
19
|
+
return [content.text, content.caption, content.title, content.description]
|
|
20
|
+
.filter(value => typeof value === 'string')
|
|
21
|
+
.join('\n')
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function applyAutoMentions(content, enabled = true) {
|
|
25
|
+
if (!enabled || !content || typeof content !== 'object') return content
|
|
26
|
+
if (Array.isArray(content.mentions)) return content
|
|
27
|
+
const mentions = extractMentions(getMessageText(content))
|
|
28
|
+
if (!mentions.length) return content
|
|
29
|
+
return { ...content, mentions }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function resolveMedia(media) {
|
|
33
|
+
if (typeof media !== 'string') return media
|
|
34
|
+
return { url: media }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function resolveMediaContent(content) {
|
|
38
|
+
if (!content || typeof content !== 'object') return content
|
|
39
|
+
const mediaKeys = ['image', 'video', 'audio', 'document', 'sticker']
|
|
40
|
+
const output = { ...content }
|
|
41
|
+
for (const key of mediaKeys) {
|
|
42
|
+
if (typeof output[key] === 'string') output[key] = resolveMedia(output[key])
|
|
43
|
+
}
|
|
44
|
+
return output
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function quotedOptions(message, options = {}) {
|
|
48
|
+
return { ...(options || {}), quoted: message }
|
|
49
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { getContentType } from '../../Utils/messages.js'
|
|
2
|
+
|
|
3
|
+
function unwrap(message) {
|
|
4
|
+
let content = message?.message || message || {}
|
|
5
|
+
const wrappers = ['ephemeralMessage', 'viewOnceMessage', 'viewOnceMessageV2', 'viewOnceMessageV2Extension', 'documentWithCaptionMessage']
|
|
6
|
+
for (let i = 0; i < 6; i++) {
|
|
7
|
+
const type = getContentType(content)
|
|
8
|
+
if (!type || !wrappers.includes(type)) break
|
|
9
|
+
content = content[type]?.message || content[type] || content
|
|
10
|
+
}
|
|
11
|
+
return content
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function parseMessage(message, options = {}) {
|
|
15
|
+
const content = unwrap(message)
|
|
16
|
+
const type = getContentType(content)
|
|
17
|
+
const node = type ? content[type] : undefined
|
|
18
|
+
let text = ''
|
|
19
|
+
|
|
20
|
+
if (typeof node === 'string') text = node
|
|
21
|
+
else if (node?.text) text = node.text
|
|
22
|
+
else if (node?.caption) text = node.caption
|
|
23
|
+
else if (node?.selectedDisplayText) text = node.selectedDisplayText
|
|
24
|
+
else if (node?.title) text = node.title
|
|
25
|
+
else if (node?.contentText) text = node.contentText
|
|
26
|
+
|
|
27
|
+
const prefix = options.prefix ?? ''
|
|
28
|
+
const commandMode = options.commandMode ?? 'prefix'
|
|
29
|
+
let command = ''
|
|
30
|
+
let args = []
|
|
31
|
+
|
|
32
|
+
const normalized = String(text || '').trim()
|
|
33
|
+
const hasPrefix = !prefix || normalized.startsWith(prefix)
|
|
34
|
+
if (normalized && hasPrefix && (commandMode === 'prefix' || !prefix)) {
|
|
35
|
+
const body = prefix ? normalized.slice(prefix.length).trim() : normalized
|
|
36
|
+
const parts = body ? body.split(/\s+/) : []
|
|
37
|
+
command = parts.shift() || ''
|
|
38
|
+
args = parts
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
message,
|
|
43
|
+
content,
|
|
44
|
+
messageType: type,
|
|
45
|
+
text: normalized,
|
|
46
|
+
command,
|
|
47
|
+
args,
|
|
48
|
+
jid: message?.key?.remoteJid,
|
|
49
|
+
sender: message?.key?.participant || message?.key?.remoteJid,
|
|
50
|
+
isGroup: Boolean(message?.key?.remoteJid?.endsWith('@g.us')),
|
|
51
|
+
isReply: Boolean(node?.contextInfo?.quotedMessage),
|
|
52
|
+
quoted: node?.contextInfo?.quotedMessage,
|
|
53
|
+
key: message?.key
|
|
54
|
+
}
|
|
55
|
+
}
|
package/package.json
CHANGED
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kyyinfinite/baileys",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.
|
|
5
|
-
"description": "
|
|
4
|
+
"version": "2.1.0",
|
|
5
|
+
"description": "WhatsApp Web library for Node.js with the Kyyinfinite Simple API",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"whatsapp",
|
|
8
8
|
"automation"
|
|
9
9
|
],
|
|
10
|
-
"homepage": "https://github.com/
|
|
10
|
+
"homepage": "https://github.com/kyyinfinite/baileys",
|
|
11
11
|
"repository": {
|
|
12
|
-
"
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/kyyinfinite/baileys.git"
|
|
13
14
|
},
|
|
14
15
|
"license": "MIT",
|
|
15
|
-
"author": "
|
|
16
|
+
"author": "kyyinfinite",
|
|
16
17
|
"main": "lib/index.js",
|
|
17
18
|
"types": "lib/index.d.ts",
|
|
18
19
|
"files": [
|
|
19
20
|
"lib/**/*",
|
|
20
21
|
"WAProto/**/*",
|
|
21
|
-
"engine-requirements.js"
|
|
22
|
+
"engine-requirements.js",
|
|
23
|
+
"LICENSE",
|
|
24
|
+
"THIRD_PARTY_NOTICES.md",
|
|
25
|
+
"CHANGELOG.md",
|
|
26
|
+
"test/**/*",
|
|
27
|
+
"TESTING.md"
|
|
22
28
|
],
|
|
23
29
|
"scripts": {
|
|
24
30
|
"build:all": "npm run build && npm run build:docs",
|
|
@@ -34,9 +40,11 @@
|
|
|
34
40
|
"lint:fix": "npm run format && npm run lint -- --fix",
|
|
35
41
|
"preinstall": "node ./engine-requirements.js",
|
|
36
42
|
"release": "release-it",
|
|
37
|
-
"test": "node
|
|
43
|
+
"test": "node test/simple-api.test.js",
|
|
38
44
|
"test:e2e": "NODE_TLS_REJECT_UNAUTHORIZED=0 node --experimental-vm-modules ./node_modules/.bin/jest --runInBand --forceExit --testMatch '**/*.test-e2e.ts'",
|
|
39
|
-
"update:version": "tsx ./scripts/update-version.ts"
|
|
45
|
+
"update:version": "tsx ./scripts/update-version.ts",
|
|
46
|
+
"test:core": "node test/core.test.js",
|
|
47
|
+
"test:all": "npm run test:core && npm test"
|
|
40
48
|
},
|
|
41
49
|
"dependencies": {
|
|
42
50
|
"@cacheable/node-cache": "^1.4.0",
|
|
@@ -135,5 +143,8 @@
|
|
|
135
143
|
"packageManager": "yarn@4.9.2",
|
|
136
144
|
"engines": {
|
|
137
145
|
"node": ">=20.0.0"
|
|
146
|
+
},
|
|
147
|
+
"bugs": {
|
|
148
|
+
"url": "https://github.com/kyyinfinite/baileys/issues"
|
|
138
149
|
}
|
|
139
150
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import assert from 'node:assert/strict'
|
|
2
|
+
import { parseJid, normalizeJid, jidUser, jidServer, jidDevice, isGroupJid, isPrivateJid, isBroadcastJid, isStatusJid, isNewsletterJid, isLidJid, makeJid } from '../lib/Kyyinfinite/Simple/jid.js'
|
|
3
|
+
import { extractMentions, getMessageText, applyAutoMentions, resolveMedia, resolveMediaContent, quotedOptions } from '../lib/Kyyinfinite/Simple/messageUtils.js'
|
|
4
|
+
|
|
5
|
+
const tests = [
|
|
6
|
+
['parseJid', () => assert.deepEqual(parseJid('12345:7@s.whatsapp.net'), { user: '12345', device: '7', server: 's.whatsapp.net', jid: '12345:7@s.whatsapp.net' })],
|
|
7
|
+
['parseJid invalid', () => assert.equal(parseJid('invalid'), null)],
|
|
8
|
+
['normalizeJid', () => assert.equal(normalizeJid(' 123@s.whatsapp.net '), '123@s.whatsapp.net')],
|
|
9
|
+
['jid accessors', () => {
|
|
10
|
+
assert.equal(jidUser('123:4@s.whatsapp.net'), '123')
|
|
11
|
+
assert.equal(jidDevice('123:4@s.whatsapp.net'), '4')
|
|
12
|
+
assert.equal(jidServer('123:4@s.whatsapp.net'), 's.whatsapp.net')
|
|
13
|
+
}],
|
|
14
|
+
['JID classifiers', () => {
|
|
15
|
+
assert.equal(isGroupJid('123@g.us'), true)
|
|
16
|
+
assert.equal(isPrivateJid('123@s.whatsapp.net'), true)
|
|
17
|
+
assert.equal(isBroadcastJid('123@broadcast'), true)
|
|
18
|
+
assert.equal(isStatusJid('status@broadcast'), true)
|
|
19
|
+
assert.equal(isNewsletterJid('123@newsletter'), true)
|
|
20
|
+
assert.equal(isLidJid('123@lid'), true)
|
|
21
|
+
}],
|
|
22
|
+
['makeJid', () => assert.equal(makeJid(123, 's.whatsapp.net', 7), '123:7@s.whatsapp.net')],
|
|
23
|
+
['mention extraction', () => assert.deepEqual(extractMentions('@628123456789 hi @628123456789!'), ['628123456789@s.whatsapp.net'])],
|
|
24
|
+
['message text extraction', () => assert.equal(getMessageText({ text: 'a', caption: 'b', title: 'c' }), 'a\nb\nc')],
|
|
25
|
+
['auto mentions enabled', () => assert.deepEqual(applyAutoMentions({ text: 'Hi @628123456789' }).mentions, ['628123456789@s.whatsapp.net'])],
|
|
26
|
+
['auto mentions disabled', () => assert.equal(applyAutoMentions({ text: 'Hi @628123456789' }, false).mentions, undefined)],
|
|
27
|
+
['explicit mentions preserved', () => assert.deepEqual(applyAutoMentions({ text: '@628123456789', mentions: ['custom@s.whatsapp.net'] }).mentions, ['custom@s.whatsapp.net'])],
|
|
28
|
+
['media URL resolver', () => assert.deepEqual(resolveMedia('https://example.com/a.jpg'), { url: 'https://example.com/a.jpg' })],
|
|
29
|
+
['media content resolver', () => assert.deepEqual(resolveMediaContent({ image: 'a.jpg', video: 'b.mp4', text: 'x' }), { image: { url: 'a.jpg' }, video: { url: 'b.mp4' }, text: 'x' })],
|
|
30
|
+
['quoted options', () => assert.deepEqual(quotedOptions({ id: 1 }, { ephemeralExpiration: 3600 }), { quoted: { id: 1 }, ephemeralExpiration: 3600 })]
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
for (const [name, fn] of tests) {
|
|
34
|
+
fn()
|
|
35
|
+
console.log(`PASS ${name}`)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
console.log(`\nCore 2.1.0 API tests: ${tests.length}/${tests.length} PASS`)
|