gifted-baileys 1.5.5 → 1.5.7

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.
Files changed (251) hide show
  1. package/README.md +6 -1642
  2. package/WAProto/WAProto.proto +969 -88
  3. package/WAProto/index.d.ts +13199 -1260
  4. package/WAProto/index.js +124901 -74525
  5. package/lib/Defaults/baileys-version.json +3 -0
  6. package/lib/Defaults/index.d.ts +284 -0
  7. package/{src → lib}/Defaults/index.js +7 -14
  8. package/lib/Signal/libsignal.d.ts +3 -0
  9. package/lib/Signal/libsignal.js +161 -0
  10. package/lib/Socket/Client/abstract-socket-client.d.ts +15 -0
  11. package/lib/Socket/Client/index.d.ts +2 -0
  12. package/{src → lib}/Socket/Client/index.js +2 -3
  13. package/lib/Socket/Client/mobile-socket-client.d.ts +12 -0
  14. package/lib/Socket/Client/mobile-socket-client.js +65 -0
  15. package/lib/Socket/Client/types.d.ts +17 -0
  16. package/lib/Socket/Client/types.js +13 -0
  17. package/lib/Socket/Client/websocket.d.ts +12 -0
  18. package/lib/Socket/Client/websocket.js +62 -0
  19. package/lib/Socket/business.d.ts +170 -0
  20. package/{src → lib}/Socket/business.js +28 -33
  21. package/lib/Socket/chats.d.ts +81 -0
  22. package/{src → lib}/Socket/chats.js +174 -176
  23. package/lib/Socket/groups.d.ts +115 -0
  24. package/{src → lib}/Socket/groups.js +80 -68
  25. package/lib/Socket/index.d.ts +172 -0
  26. package/{src → lib}/Socket/index.js +4 -1
  27. package/lib/Socket/messages-recv.d.ts +158 -0
  28. package/{src → lib}/Socket/messages-recv.js +378 -211
  29. package/lib/Socket/messages-send.d.ts +155 -0
  30. package/{src → lib}/Socket/messages-send.js +452 -177
  31. package/lib/Socket/newsletter.d.ts +132 -0
  32. package/{src → lib}/Socket/newsletter.js +107 -98
  33. package/lib/Socket/registration.d.ts +264 -0
  34. package/{src → lib}/Socket/registration.js +56 -48
  35. package/lib/Socket/socket.d.ts +44 -0
  36. package/{src → lib}/Socket/socket.js +77 -77
  37. package/lib/Socket/usync.d.ts +37 -0
  38. package/lib/Socket/usync.js +70 -0
  39. package/lib/Store/index.d.ts +3 -0
  40. package/lib/Store/make-cache-manager-store.d.ts +14 -0
  41. package/{src → lib}/Store/make-cache-manager-store.js +25 -34
  42. package/lib/Store/make-in-memory-store.d.ts +118 -0
  43. package/{src → lib}/Store/make-in-memory-store.js +36 -32
  44. package/lib/Store/make-ordered-dictionary.d.ts +13 -0
  45. package/lib/Store/object-repository.d.ts +10 -0
  46. package/{src → lib}/Store/object-repository.js +1 -1
  47. package/lib/Types/Auth.d.ts +109 -0
  48. package/lib/Types/Call.d.ts +13 -0
  49. package/lib/Types/Chat.d.ts +107 -0
  50. package/{src/Types/Contact.ts → lib/Types/Contact.d.ts} +8 -9
  51. package/lib/Types/Events.d.ts +172 -0
  52. package/lib/Types/GroupMetadata.d.ts +56 -0
  53. package/lib/Types/Label.d.ts +46 -0
  54. package/{src/Types/LabelAssociation.ts → lib/Types/LabelAssociation.d.ts} +16 -22
  55. package/lib/Types/Message.d.ts +433 -0
  56. package/lib/Types/Newsletter.d.ts +92 -0
  57. package/lib/Types/Product.d.ts +78 -0
  58. package/lib/Types/Signal.d.ts +57 -0
  59. package/{src/Types/Socket.ts → lib/Types/Socket.d.ts} +61 -68
  60. package/lib/Types/State.d.ts +27 -0
  61. package/lib/Types/USync.d.ts +25 -0
  62. package/lib/Types/index.d.ts +66 -0
  63. package/lib/Utils/auth-utils.d.ts +18 -0
  64. package/{src → lib}/Utils/auth-utils.js +73 -90
  65. package/lib/Utils/baileys-event-stream.d.ts +16 -0
  66. package/lib/Utils/baileys-event-stream.js +63 -0
  67. package/lib/Utils/business.d.ts +22 -0
  68. package/{src → lib}/Utils/business.js +15 -43
  69. package/lib/Utils/chat-utils.d.ts +70 -0
  70. package/{src → lib}/Utils/chat-utils.js +87 -94
  71. package/lib/Utils/crypto.d.ts +40 -0
  72. package/{src → lib}/Utils/crypto.js +4 -2
  73. package/lib/Utils/decode-wa-message.d.ts +36 -0
  74. package/lib/Utils/decode-wa-message.js +226 -0
  75. package/lib/Utils/event-buffer.d.ts +35 -0
  76. package/{src → lib}/Utils/event-buffer.js +4 -13
  77. package/lib/Utils/generics.d.ts +88 -0
  78. package/{src → lib}/Utils/generics.js +67 -86
  79. package/lib/Utils/history.d.ts +19 -0
  80. package/{src → lib}/Utils/history.js +13 -39
  81. package/lib/Utils/index.d.ts +17 -0
  82. package/lib/Utils/link-preview.d.ts +21 -0
  83. package/{src → lib}/Utils/link-preview.js +17 -54
  84. package/lib/Utils/logger.d.ts +2 -0
  85. package/lib/Utils/lt-hash.d.ts +12 -0
  86. package/lib/Utils/make-mutex.d.ts +7 -0
  87. package/{src → lib}/Utils/make-mutex.js +4 -13
  88. package/lib/Utils/messages-media.d.ts +113 -0
  89. package/{src → lib}/Utils/messages-media.js +193 -255
  90. package/lib/Utils/messages.d.ts +77 -0
  91. package/{src → lib}/Utils/messages.js +588 -118
  92. package/lib/Utils/noise-handler.d.ts +20 -0
  93. package/lib/Utils/process-message.d.ts +41 -0
  94. package/{src → lib}/Utils/process-message.js +27 -30
  95. package/lib/Utils/signal.d.ts +33 -0
  96. package/{src → lib}/Utils/signal.js +25 -42
  97. package/lib/Utils/use-multi-file-auth-state.d.ts +12 -0
  98. package/{src → lib}/Utils/use-multi-file-auth-state.js +27 -28
  99. package/lib/Utils/validate-connection.d.ts +11 -0
  100. package/{src → lib}/Utils/validate-connection.js +40 -9
  101. package/lib/WABinary/constants.d.ts +27 -0
  102. package/lib/WABinary/decode.d.ts +6 -0
  103. package/lib/WABinary/encode.d.ts +2 -0
  104. package/{src → lib}/WABinary/encode.js +16 -10
  105. package/lib/WABinary/generic-utils.d.ts +14 -0
  106. package/lib/WABinary/index.d.ts +5 -0
  107. package/lib/WABinary/jid-utils.d.ts +31 -0
  108. package/lib/WABinary/types.d.ts +18 -0
  109. package/lib/WABinary/types.js +2 -0
  110. package/lib/WAM/BinaryInfo.d.ts +8 -0
  111. package/lib/WAM/constants.d.ts +38 -0
  112. package/lib/WAM/encode.d.ts +2 -0
  113. package/lib/WAM/index.d.ts +3 -0
  114. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +9 -0
  115. package/lib/WAUSync/Protocols/USyncContactProtocol.js +32 -0
  116. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +22 -0
  117. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +57 -0
  118. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
  119. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +30 -0
  120. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
  121. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +42 -0
  122. package/lib/WAUSync/Protocols/index.d.ts +4 -0
  123. package/lib/WAUSync/Protocols/index.js +20 -0
  124. package/lib/WAUSync/USyncQuery.d.ts +26 -0
  125. package/lib/WAUSync/USyncQuery.js +79 -0
  126. package/lib/WAUSync/USyncUser.d.ts +10 -0
  127. package/lib/WAUSync/USyncUser.js +22 -0
  128. package/lib/WAUSync/index.d.ts +3 -0
  129. package/lib/WAUSync/index.js +19 -0
  130. package/{src → lib}/index.js +1 -0
  131. package/package.json +26 -8
  132. package/LICENSE +0 -21
  133. package/src/Defaults/baileys-version.json +0 -3
  134. package/src/Defaults/index.ts +0 -131
  135. package/src/Signal/libsignal.js +0 -180
  136. package/src/Signal/libsignal.ts +0 -141
  137. package/src/Socket/Client/abstract-socket-client.ts +0 -19
  138. package/src/Socket/Client/index.ts +0 -3
  139. package/src/Socket/Client/mobile-socket-client.js +0 -78
  140. package/src/Socket/Client/mobile-socket-client.ts +0 -66
  141. package/src/Socket/Client/web-socket-client.js +0 -75
  142. package/src/Socket/Client/web-socket-client.ts +0 -57
  143. package/src/Socket/business.ts +0 -281
  144. package/src/Socket/chats.ts +0 -1030
  145. package/src/Socket/groups.ts +0 -356
  146. package/src/Socket/index.ts +0 -13
  147. package/src/Socket/messages-recv.ts +0 -985
  148. package/src/Socket/messages-send.ts +0 -871
  149. package/src/Socket/newsletter.ts +0 -282
  150. package/src/Socket/registration.ts +0 -250
  151. package/src/Socket/socket.ts +0 -777
  152. package/src/Store/index.ts +0 -3
  153. package/src/Store/make-cache-manager-store.ts +0 -100
  154. package/src/Store/make-in-memory-store.ts +0 -475
  155. package/src/Store/make-ordered-dictionary.ts +0 -86
  156. package/src/Store/object-repository.ts +0 -32
  157. package/src/Tests/test.app-state-sync.js +0 -204
  158. package/src/Tests/test.app-state-sync.ts +0 -207
  159. package/src/Tests/test.event-buffer.js +0 -270
  160. package/src/Tests/test.event-buffer.ts +0 -319
  161. package/src/Tests/test.key-store.js +0 -76
  162. package/src/Tests/test.key-store.ts +0 -92
  163. package/src/Tests/test.libsignal.js +0 -141
  164. package/src/Tests/test.libsignal.ts +0 -186
  165. package/src/Tests/test.media-download.js +0 -93
  166. package/src/Tests/test.media-download.ts +0 -76
  167. package/src/Tests/test.messages.js +0 -33
  168. package/src/Tests/test.messages.ts +0 -37
  169. package/src/Tests/utils.js +0 -34
  170. package/src/Tests/utils.ts +0 -36
  171. package/src/Types/Auth.ts +0 -113
  172. package/src/Types/Call.ts +0 -15
  173. package/src/Types/Chat.ts +0 -106
  174. package/src/Types/Events.ts +0 -93
  175. package/src/Types/GroupMetadata.ts +0 -53
  176. package/src/Types/Label.ts +0 -36
  177. package/src/Types/Message.ts +0 -288
  178. package/src/Types/Newsletter.ts +0 -98
  179. package/src/Types/Product.ts +0 -85
  180. package/src/Types/Signal.ts +0 -68
  181. package/src/Types/State.ts +0 -29
  182. package/src/Types/index.ts +0 -59
  183. package/src/Utils/auth-utils.ts +0 -222
  184. package/src/Utils/baileys-event-stream.js +0 -92
  185. package/src/Utils/baileys-event-stream.ts +0 -66
  186. package/src/Utils/business.ts +0 -275
  187. package/src/Utils/chat-utils.ts +0 -860
  188. package/src/Utils/crypto.ts +0 -131
  189. package/src/Utils/decode-wa-message.js +0 -211
  190. package/src/Utils/decode-wa-message.ts +0 -228
  191. package/src/Utils/event-buffer.ts +0 -613
  192. package/src/Utils/generics.ts +0 -434
  193. package/src/Utils/history.ts +0 -112
  194. package/src/Utils/index.ts +0 -17
  195. package/src/Utils/link-preview.ts +0 -122
  196. package/src/Utils/logger.ts +0 -3
  197. package/src/Utils/lt-hash.ts +0 -61
  198. package/src/Utils/make-mutex.ts +0 -44
  199. package/src/Utils/messages-media.ts +0 -847
  200. package/src/Utils/messages.ts +0 -956
  201. package/src/Utils/noise-handler.ts +0 -197
  202. package/src/Utils/process-message.ts +0 -414
  203. package/src/Utils/signal.ts +0 -177
  204. package/src/Utils/use-multi-file-auth-state.ts +0 -90
  205. package/src/Utils/validate-connection.ts +0 -238
  206. package/src/WABinary/constants.ts +0 -42
  207. package/src/WABinary/decode.ts +0 -265
  208. package/src/WABinary/encode.ts +0 -236
  209. package/src/WABinary/generic-utils.ts +0 -121
  210. package/src/WABinary/index.ts +0 -5
  211. package/src/WABinary/jid-utils.ts +0 -68
  212. package/src/WABinary/types.ts +0 -17
  213. package/src/WAM/BinaryInfo.ts +0 -12
  214. package/src/WAM/constants.ts +0 -15382
  215. package/src/WAM/encode.ts +0 -174
  216. package/src/WAM/index.ts +0 -3
  217. package/src/gifted +0 -1
  218. package/src/index.ts +0 -13
  219. /package/{src → lib}/Defaults/phonenumber-mcc.json +0 -0
  220. /package/{src → lib}/Socket/Client/abstract-socket-client.js +0 -0
  221. /package/{src → lib}/Store/index.js +0 -0
  222. /package/{src → lib}/Store/make-ordered-dictionary.js +0 -0
  223. /package/{src → lib}/Types/Auth.js +0 -0
  224. /package/{src → lib}/Types/Call.js +0 -0
  225. /package/{src → lib}/Types/Chat.js +0 -0
  226. /package/{src → lib}/Types/Contact.js +0 -0
  227. /package/{src → lib}/Types/Events.js +0 -0
  228. /package/{src → lib}/Types/GroupMetadata.js +0 -0
  229. /package/{src → lib}/Types/Label.js +0 -0
  230. /package/{src → lib}/Types/LabelAssociation.js +0 -0
  231. /package/{src → lib}/Types/Message.js +0 -0
  232. /package/{src → lib}/Types/Newsletter.js +0 -0
  233. /package/{src → lib}/Types/Product.js +0 -0
  234. /package/{src → lib}/Types/Signal.js +0 -0
  235. /package/{src → lib}/Types/Socket.js +0 -0
  236. /package/{src → lib}/Types/State.js +0 -0
  237. /package/{src/WABinary/types.js → lib/Types/USync.js} +0 -0
  238. /package/{src → lib}/Types/index.js +0 -0
  239. /package/{src → lib}/Utils/index.js +0 -0
  240. /package/{src → lib}/Utils/logger.js +0 -0
  241. /package/{src → lib}/Utils/lt-hash.js +0 -0
  242. /package/{src → lib}/Utils/noise-handler.js +0 -0
  243. /package/{src → lib}/WABinary/constants.js +0 -0
  244. /package/{src → lib}/WABinary/decode.js +0 -0
  245. /package/{src → lib}/WABinary/generic-utils.js +0 -0
  246. /package/{src → lib}/WABinary/index.js +0 -0
  247. /package/{src → lib}/WABinary/jid-utils.js +0 -0
  248. /package/{src → lib}/WAM/BinaryInfo.js +0 -0
  249. /package/{src → lib}/WAM/constants.js +0 -0
  250. /package/{src → lib}/WAM/encode.js +0 -0
  251. /package/{src → lib}/WAM/index.js +0 -0
@@ -1,3 +0,0 @@
1
- import makeCacheManagerAuthState from './make-cache-manager-store'
2
- import makeInMemoryStore from './make-in-memory-store'
3
- export { makeInMemoryStore, makeCacheManagerAuthState }
@@ -1,100 +0,0 @@
1
- import { caching, Storage } from 'cache-manager'
2
- import { proto } from '../../WAProto'
3
- import { AuthenticationCreds } from '../Types'
4
- import { BufferJSON, initAuthCreds } from '../Utils'
5
- import logger from '../Utils/logger'
6
-
7
- const makeCacheManagerAuthState = async(store: Storage, sessionKey: string) => {
8
- const defaultKey = (file: string): string => `${sessionKey}:${file}`
9
-
10
- const databaseConn = await caching(store)
11
-
12
- const writeData = async(file: string, data: object) => {
13
- let ttl: number | undefined = undefined
14
- if(file === 'creds') {
15
- ttl = 63115200 // 2 years
16
- }
17
-
18
- await databaseConn.set(
19
- defaultKey(file),
20
- JSON.stringify(data, BufferJSON.replacer),
21
- ttl
22
- )
23
- }
24
-
25
- const readData = async(file: string): Promise<AuthenticationCreds | null> => {
26
- try {
27
- const data = await databaseConn.get(defaultKey(file))
28
-
29
- if(data) {
30
- return JSON.parse(data as string, BufferJSON.reviver)
31
- }
32
-
33
- return null
34
- } catch(error) {
35
- logger.error(error)
36
- return null
37
- }
38
- }
39
-
40
- const removeData = async(file: string) => {
41
- try {
42
- return await databaseConn.del(defaultKey(file))
43
- } catch{
44
- logger.error(`Error removing ${file} from session ${sessionKey}`)
45
- }
46
- }
47
-
48
- const clearState = async() => {
49
- try {
50
- const result = await databaseConn.store.keys(`${sessionKey}*`)
51
- await Promise.all(
52
- result.map(async(key) => await databaseConn.del(key))
53
- )
54
- } catch(err) {
55
- }
56
- }
57
-
58
- const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds()
59
-
60
- return {
61
- clearState,
62
- saveCreds: () => writeData('creds', creds),
63
- state: {
64
- creds,
65
- keys: {
66
- get: async(type: string, ids: string[]) => {
67
- const data = {}
68
- await Promise.all(
69
- ids.map(async(id) => {
70
- let value: proto.Message.AppStateSyncKeyData | AuthenticationCreds | null =
71
- await readData(`${type}-${id}`)
72
- if(type === 'app-state-sync-key' && value) {
73
- value = proto.Message.AppStateSyncKeyData.fromObject(value)
74
- }
75
-
76
- data[id] = value
77
- })
78
- )
79
-
80
- return data
81
- },
82
- set: async(data) => {
83
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
- const tasks: Promise<any>[] = []
85
- for(const category in data) {
86
- for(const id in data[category]) {
87
- const value = data[category][id]
88
- const key = `${category}-${id}`
89
- tasks.push(value ? writeData(key, value) : removeData(key))
90
- }
91
- }
92
-
93
- await Promise.all(tasks)
94
- },
95
- }
96
- }
97
- }
98
- }
99
-
100
- export default makeCacheManagerAuthState
@@ -1,475 +0,0 @@
1
- import type KeyedDB from '@adiwajshing/keyed-db'
2
- import type { Comparable } from '@adiwajshing/keyed-db/lib/Types'
3
- import type { Logger } from 'pino'
4
- import { proto } from '../../WAProto'
5
- import { DEFAULT_CONNECTION_CONFIG } from '../Defaults'
6
- import type makeMDSocket from '../Socket'
7
- import type { BaileysEventEmitter, Chat, ConnectionState, Contact, GroupMetadata, PresenceData, WAMessage, WAMessageCursor, WAMessageKey } from '../Types'
8
- import { Label } from '../Types/Label'
9
- import { LabelAssociation, LabelAssociationType, MessageLabelAssociation } from '../Types/LabelAssociation'
10
- import { md5, toNumber, updateMessageWithReaction, updateMessageWithReceipt } from '../Utils'
11
- import { jidDecode, jidNormalizedUser } from '../WABinary'
12
- import makeOrderedDictionary from './make-ordered-dictionary'
13
- import { ObjectRepository } from './object-repository'
14
-
15
- type WASocket = ReturnType<typeof makeMDSocket>
16
-
17
- export const waChatKey = (pin: boolean) => ({
18
- key: (c: Chat) => (pin ? (c.pinned ? '1' : '0') : '') + (c.archived ? '0' : '1') + (c.conversationTimestamp ? c.conversationTimestamp.toString(16).padStart(8, '0') : '') + c.id,
19
- compare: (k1: string, k2: string) => k2.localeCompare(k1)
20
- })
21
-
22
- export const waMessageID = (m: WAMessage) => m.key.id || ''
23
-
24
- export const waLabelAssociationKey: Comparable<LabelAssociation, string> = {
25
- key: (la: LabelAssociation) => (la.type === LabelAssociationType.Chat ? la.chatId + la.labelId : la.chatId + la.messageId + la.labelId),
26
- compare: (k1: string, k2: string) => k2.localeCompare(k1)
27
- }
28
-
29
- export type BaileysInMemoryStoreConfig = {
30
- chatKey?: Comparable<Chat, string>
31
- labelAssociationKey?: Comparable<LabelAssociation, string>
32
- logger?: Logger
33
- socket?: WASocket
34
- }
35
-
36
- const makeMessagesDictionary = () => makeOrderedDictionary(waMessageID)
37
-
38
- export default (config: BaileysInMemoryStoreConfig) => {
39
- const socket = config.socket
40
- const chatKey = config.chatKey || waChatKey(true)
41
- const labelAssociationKey = config.labelAssociationKey || waLabelAssociationKey
42
- const logger: Logger = config.logger || DEFAULT_CONNECTION_CONFIG.logger.child({ stream: 'in-mem-store' })
43
- const KeyedDB = require('@adiwajshing/keyed-db').default
44
-
45
- const chats = new KeyedDB(chatKey, c => c.id) as KeyedDB<Chat, string>
46
- const messages: { [_: string]: ReturnType<typeof makeMessagesDictionary> } = {}
47
- const contacts: { [_: string]: Contact } = {}
48
- const groupMetadata: { [_: string]: GroupMetadata } = {}
49
- const presences: { [id: string]: { [participant: string]: PresenceData } } = {}
50
- const state: ConnectionState = { connection: 'close' }
51
- const labels = new ObjectRepository<Label>()
52
- const labelAssociations = new KeyedDB(labelAssociationKey, labelAssociationKey.key) as KeyedDB<LabelAssociation, string>
53
-
54
- const assertMessageList = (jid: string) => {
55
- if(!messages[jid]) {
56
- messages[jid] = makeMessagesDictionary()
57
- }
58
-
59
- return messages[jid]
60
- }
61
-
62
- const contactsUpsert = (newContacts: Contact[]) => {
63
- const oldContacts = new Set(Object.keys(contacts))
64
- for(const contact of newContacts) {
65
- oldContacts.delete(contact.id)
66
- contacts[contact.id] = Object.assign(
67
- contacts[contact.id] || {},
68
- contact
69
- )
70
- }
71
-
72
- return oldContacts
73
- }
74
-
75
- const labelsUpsert = (newLabels: Label[]) => {
76
- for(const label of newLabels) {
77
- labels.upsertById(label.id, label)
78
- }
79
- }
80
-
81
- /**
82
- * binds to a BaileysEventEmitter.
83
- * It listens to all events and constructs a state that you can query accurate data from.
84
- * Eg. can use the store to fetch chats, contacts, messages etc.
85
- * @param ev typically the event emitter from the socket connection
86
- */
87
- const bind = (ev: BaileysEventEmitter) => {
88
- ev.on('connection.update', update => {
89
- Object.assign(state, update)
90
- })
91
-
92
- ev.on('messaging-history.set', ({
93
- chats: newChats,
94
- contacts: newContacts,
95
- messages: newMessages,
96
- isLatest
97
- }) => {
98
- if(isLatest) {
99
- chats.clear()
100
-
101
- for(const id in messages) {
102
- delete messages[id]
103
- }
104
- }
105
-
106
- const chatsAdded = chats.insertIfAbsent(...newChats).length
107
- logger.debug({ chatsAdded }, 'synced chats')
108
-
109
- const oldContacts = contactsUpsert(newContacts)
110
- if(isLatest) {
111
- for(const jid of oldContacts) {
112
- delete contacts[jid]
113
- }
114
- }
115
-
116
- logger.debug({ deletedContacts: isLatest ? oldContacts.size : 0, newContacts }, 'synced contacts')
117
-
118
- for(const msg of newMessages) {
119
- const jid = msg.key.remoteJid!
120
- const list = assertMessageList(jid)
121
- list.upsert(msg, 'prepend')
122
- }
123
-
124
- logger.debug({ messages: newMessages.length }, 'synced messages')
125
- })
126
-
127
- ev.on('contacts.upsert', contacts => {
128
- contactsUpsert(contacts)
129
- })
130
-
131
- ev.on('contacts.update', async updates => {
132
- for(const update of updates) {
133
- let contact: Contact
134
- if(contacts[update.id!]) {
135
- contact = contacts[update.id!]
136
- } else {
137
- const contactHashes = await Promise.all(Object.keys(contacts).map(async contactId => {
138
- const { user } = jidDecode(contactId)!
139
- return [contactId, (await md5(Buffer.from(user + 'WA_ADD_NOTIF', 'utf8'))).toString('base64').slice(0, 3)]
140
- }))
141
- contact = contacts[contactHashes.find(([, b]) => b === update.id)?.[0] || ''] // find contact by attrs.hash, when user is not saved as a contact
142
- }
143
-
144
- if(contact) {
145
- if(update.imgUrl === 'changed') {
146
- contact.imgUrl = socket ? await socket?.profilePictureUrl(contact.id) : undefined
147
- } else if(update.imgUrl === 'removed') {
148
- delete contact.imgUrl
149
- }
150
- } else {
151
- return logger.debug({ update }, 'got update for non-existant contact')
152
- }
153
-
154
- Object.assign(contacts[contact.id], contact)
155
- }
156
- })
157
- ev.on('chats.upsert', newChats => {
158
- chats.upsert(...newChats)
159
- })
160
- ev.on('chats.update', updates => {
161
- for(let update of updates) {
162
- const result = chats.update(update.id!, chat => {
163
- if(update.unreadCount! > 0) {
164
- update = { ...update }
165
- update.unreadCount = (chat.unreadCount || 0) + update.unreadCount!
166
- }
167
-
168
- Object.assign(chat, update)
169
- })
170
- if(!result) {
171
- logger.debug({ update }, 'got update for non-existant chat')
172
- }
173
- }
174
- })
175
-
176
- ev.on('labels.edit', (label: Label) => {
177
- if(label.deleted) {
178
- return labels.deleteById(label.id)
179
- }
180
-
181
- // WhatsApp can store only up to 20 labels
182
- if(labels.count() < 20) {
183
- return labels.upsertById(label.id, label)
184
- }
185
-
186
- logger.error('Labels count exceed')
187
- })
188
-
189
- ev.on('labels.association', ({ type, association }) => {
190
- switch (type) {
191
- case 'add':
192
- labelAssociations.upsert(association)
193
- break
194
- case 'remove':
195
- labelAssociations.delete(association)
196
- break
197
- default:
198
- console.error(`unknown operation type [${type}]`)
199
- }
200
- })
201
-
202
- ev.on('presence.update', ({ id, presences: update }) => {
203
- presences[id] = presences[id] || {}
204
- Object.assign(presences[id], update)
205
- })
206
- ev.on('chats.delete', deletions => {
207
- for(const item of deletions) {
208
- if(chats.get(item)) {
209
- chats.deleteById(item)
210
- }
211
- }
212
- })
213
- ev.on('messages.upsert', ({ messages: newMessages, type }) => {
214
- switch (type) {
215
- case 'append':
216
- case 'notify':
217
- for(const msg of newMessages) {
218
- const jid = jidNormalizedUser(msg.key.remoteJid!)
219
- const list = assertMessageList(jid)
220
- list.upsert(msg, 'append')
221
-
222
- if(type === 'notify') {
223
- if(!chats.get(jid)) {
224
- ev.emit('chats.upsert', [
225
- {
226
- id: jid,
227
- conversationTimestamp: toNumber(msg.messageTimestamp),
228
- unreadCount: 1
229
- }
230
- ])
231
- }
232
- }
233
- }
234
-
235
- break
236
- }
237
- })
238
- ev.on('messages.update', updates => {
239
- for(const { update, key } of updates) {
240
- const list = assertMessageList(jidNormalizedUser(key.remoteJid!))
241
- if(update?.status) {
242
- const listStatus = list.get(key.id!)?.status
243
- if(listStatus && update?.status <= listStatus) {
244
- logger.debug({ update, storedStatus: listStatus }, 'status stored newer then update')
245
- delete update.status
246
- logger.debug({ update }, 'new update object')
247
- }
248
- }
249
-
250
- const result = list.updateAssign(key.id!, update)
251
- if(!result) {
252
- logger.debug({ update }, 'got update for non-existent message')
253
- }
254
- }
255
- })
256
- ev.on('messages.delete', item => {
257
- if('all' in item) {
258
- const list = messages[item.jid]
259
- list?.clear()
260
- } else {
261
- const jid = item.keys[0].remoteJid!
262
- const list = messages[jid]
263
- if(list) {
264
- const idSet = new Set(item.keys.map(k => k.id))
265
- list.filter(m => !idSet.has(m.key.id))
266
- }
267
- }
268
- })
269
-
270
- ev.on('groups.update', updates => {
271
- for(const update of updates) {
272
- const id = update.id!
273
- if(groupMetadata[id]) {
274
- Object.assign(groupMetadata[id], update)
275
- } else {
276
- logger.debug({ update }, 'got update for non-existant group metadata')
277
- }
278
- }
279
- })
280
-
281
- ev.on('group-participants.update', ({ id, participants, action }) => {
282
- const metadata = groupMetadata[id]
283
- if(metadata) {
284
- switch (action) {
285
- case 'add':
286
- metadata.participants.push(...participants.map(id => ({ id, isAdmin: false, isSuperAdmin: false })))
287
- break
288
- case 'demote':
289
- case 'promote':
290
- for(const participant of metadata.participants) {
291
- if(participants.includes(participant.id)) {
292
- participant.isAdmin = action === 'promote'
293
- }
294
- }
295
-
296
- break
297
- case 'remove':
298
- metadata.participants = metadata.participants.filter(p => !participants.includes(p.id))
299
- break
300
- }
301
- }
302
- })
303
-
304
- ev.on('message-receipt.update', updates => {
305
- for(const { key, receipt } of updates) {
306
- const obj = messages[key.remoteJid!]
307
- const msg = obj?.get(key.id!)
308
- if(msg) {
309
- updateMessageWithReceipt(msg, receipt)
310
- }
311
- }
312
- })
313
-
314
- ev.on('messages.reaction', (reactions) => {
315
- for(const { key, reaction } of reactions) {
316
- const obj = messages[key.remoteJid!]
317
- const msg = obj?.get(key.id!)
318
- if(msg) {
319
- updateMessageWithReaction(msg, reaction)
320
- }
321
- }
322
- })
323
- }
324
-
325
- const toJSON = () => ({
326
- chats,
327
- contacts,
328
- messages,
329
- labels,
330
- labelAssociations
331
- })
332
-
333
- const fromJSON = (json: {chats: Chat[], contacts: { [id: string]: Contact }, messages: { [id: string]: WAMessage[] }, labels: { [labelId: string]: Label }, labelAssociations: LabelAssociation[]}) => {
334
- chats.upsert(...json.chats)
335
- labelAssociations.upsert(...json.labelAssociations || [])
336
- contactsUpsert(Object.values(json.contacts))
337
- labelsUpsert(Object.values(json.labels || {}))
338
- for(const jid in json.messages) {
339
- const list = assertMessageList(jid)
340
- for(const msg of json.messages[jid]) {
341
- list.upsert(proto.WebMessageInfo.fromObject(msg), 'append')
342
- }
343
- }
344
- }
345
-
346
-
347
- return {
348
- chats,
349
- contacts,
350
- messages,
351
- groupMetadata,
352
- state,
353
- presences,
354
- labels,
355
- labelAssociations,
356
- bind,
357
- /** loads messages from the store, if not found -- uses the legacy connection */
358
- loadMessages: async(jid: string, count: number, cursor: WAMessageCursor) => {
359
- const list = assertMessageList(jid)
360
- const mode = !cursor || 'before' in cursor ? 'before' : 'after'
361
- const cursorKey = !!cursor ? ('before' in cursor ? cursor.before : cursor.after) : undefined
362
- const cursorValue = cursorKey ? list.get(cursorKey.id!) : undefined
363
-
364
- let messages: WAMessage[]
365
- if(list && mode === 'before' && (!cursorKey || cursorValue)) {
366
- if(cursorValue) {
367
- const msgIdx = list.array.findIndex(m => m.key.id === cursorKey?.id)
368
- messages = list.array.slice(0, msgIdx)
369
- } else {
370
- messages = list.array
371
- }
372
-
373
- const diff = count - messages.length
374
- if(diff < 0) {
375
- messages = messages.slice(-count) // get the last X messages
376
- }
377
- } else {
378
- messages = []
379
- }
380
-
381
- return messages
382
- },
383
- /**
384
- * Get all available labels for profile
385
- *
386
- * Keep in mind that the list is formed from predefined tags and tags
387
- * that were "caught" during their editing.
388
- */
389
- getLabels: () => {
390
- return labels
391
- },
392
-
393
- /**
394
- * Get labels for chat
395
- *
396
- * @returns Label IDs
397
- **/
398
- getChatLabels: (chatId: string) => {
399
- return labelAssociations.filter((la) => la.chatId === chatId).all()
400
- },
401
-
402
- /**
403
- * Get labels for message
404
- *
405
- * @returns Label IDs
406
- **/
407
- getMessageLabels: (messageId: string) => {
408
- const associations = labelAssociations
409
- .filter((la: MessageLabelAssociation) => la.messageId === messageId)
410
- .all()
411
-
412
- return associations.map(({ labelId }) => labelId)
413
-
414
- },
415
- loadMessage: async(jid: string, id: string) => messages[jid]?.get(id),
416
- mostRecentMessage: async(jid: string) => {
417
- const message: WAMessage | undefined = messages[jid]?.array.slice(-1)[0]
418
- return message
419
- },
420
- fetchImageUrl: async(jid: string, sock: WASocket | undefined) => {
421
- const contact = contacts[jid]
422
- if(!contact) {
423
- return sock?.profilePictureUrl(jid)
424
- }
425
-
426
- if(typeof contact.imgUrl === 'undefined') {
427
- contact.imgUrl = await sock?.profilePictureUrl(jid)
428
- }
429
-
430
- return contact.imgUrl
431
- },
432
- fetchGroupMetadata: async(jid: string, sock: WASocket | undefined) => {
433
- if(!groupMetadata[jid]) {
434
- const metadata = await sock?.groupMetadata(jid)
435
- if(metadata) {
436
- groupMetadata[jid] = metadata
437
- }
438
- }
439
-
440
- return groupMetadata[jid]
441
- },
442
- // fetchBroadcastListInfo: async(jid: string, sock: WASocket | undefined) => {
443
- // if(!groupMetadata[jid]) {
444
- // const metadata = await sock?.getBroadcastListInfo(jid)
445
- // if(metadata) {
446
- // groupMetadata[jid] = metadata
447
- // }
448
- // }
449
-
450
- // return groupMetadata[jid]
451
- // },
452
- fetchMessageReceipts: async({ remoteJid, id }: WAMessageKey) => {
453
- const list = messages[remoteJid!]
454
- const msg = list?.get(id!)
455
- return msg?.userReceipt
456
- },
457
- toJSON,
458
- fromJSON,
459
- writeToFile: (path: string) => {
460
- // require fs here so that in case "fs" is not available -- the app does not crash
461
- const { writeFileSync } = require('fs')
462
- writeFileSync(path, JSON.stringify(toJSON()))
463
- },
464
- readFromFile: (path: string) => {
465
- // require fs here so that in case "fs" is not available -- the app does not crash
466
- const { readFileSync, existsSync } = require('fs')
467
- if(existsSync(path)) {
468
- logger.debug({ path }, 'reading from file')
469
- const jsonStr = readFileSync(path, { encoding: 'utf-8' })
470
- const json = JSON.parse(jsonStr)
471
- fromJSON(json)
472
- }
473
- }
474
- }
475
- }
@@ -1,86 +0,0 @@
1
- function makeOrderedDictionary<T>(idGetter: (item: T) => string) {
2
- const array: T[] = []
3
- const dict: { [_: string]: T } = { }
4
-
5
- const get = (id: string): T | undefined => dict[id]
6
-
7
- const update = (item: T) => {
8
- const id = idGetter(item)
9
- const idx = array.findIndex(i => idGetter(i) === id)
10
- if(idx >= 0) {
11
- array[idx] = item
12
- dict[id] = item
13
- }
14
-
15
- return false
16
- }
17
-
18
- const upsert = (item: T, mode: 'append' | 'prepend') => {
19
- const id = idGetter(item)
20
- if(get(id)) {
21
- update(item)
22
- } else {
23
- if(mode === 'append') {
24
- array.push(item)
25
- } else {
26
- array.splice(0, 0, item)
27
- }
28
-
29
- dict[id] = item
30
- }
31
- }
32
-
33
- const remove = (item: T) => {
34
- const id = idGetter(item)
35
- const idx = array.findIndex(i => idGetter(i) === id)
36
- if(idx >= 0) {
37
- array.splice(idx, 1)
38
- delete dict[id]
39
- return true
40
- }
41
-
42
- return false
43
- }
44
-
45
- return {
46
- array,
47
- get,
48
- upsert,
49
- update,
50
- remove,
51
- updateAssign: (id: string, update: Partial<T>) => {
52
- const item = get(id)
53
- if(item) {
54
- Object.assign(item, update)
55
- delete dict[id]
56
- dict[idGetter(item)] = item
57
- return true
58
- }
59
-
60
- return false
61
- },
62
- clear: () => {
63
- array.splice(0, array.length)
64
- Object.keys(dict).forEach(key => {
65
- delete dict[key]
66
- })
67
- },
68
- filter: (contain: (item: T) => boolean) => {
69
- let i = 0
70
- while(i < array.length) {
71
- if(!contain(array[i])) {
72
- delete dict[idGetter(array[i])]
73
- array.splice(i, 1)
74
- } else {
75
- i += 1
76
- }
77
- }
78
- },
79
- toJSON: () => array,
80
- fromJSON: (newItems: T[]) => {
81
- array.splice(0, array.length, ...newItems)
82
- }
83
- }
84
- }
85
-
86
- export default makeOrderedDictionary
@@ -1,32 +0,0 @@
1
- export class ObjectRepository<T extends object> {
2
- readonly entityMap: Map<string, T>
3
-
4
- constructor(entities: Record<string, T> = {}) {
5
- this.entityMap = new Map(Object.entries(entities))
6
- }
7
-
8
- findById(id: string) {
9
- return this.entityMap.get(id)
10
- }
11
-
12
- findAll() {
13
- return Array.from(this.entityMap.values())
14
- }
15
-
16
- upsertById(id: string, entity: T) {
17
- return this.entityMap.set(id, { ...entity })
18
- }
19
-
20
- deleteById(id: string) {
21
- return this.entityMap.delete(id)
22
- }
23
-
24
- count() {
25
- return this.entityMap.size
26
- }
27
-
28
- toJSON() {
29
- return this.findAll()
30
- }
31
-
32
- }