mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
Cleanup + add remaining utils
This commit is contained in:
@@ -3,8 +3,7 @@ import EventEmitter from "events"
|
|||||||
import * as Curve from 'curve25519-js'
|
import * as Curve from 'curve25519-js'
|
||||||
import { BaileysEventEmitter, BaileysEventMap, SocketConfig, CurveKeyPair, WAInitResponse, ConnectionState, DisconnectReason } from "../Types"
|
import { BaileysEventEmitter, BaileysEventMap, SocketConfig, CurveKeyPair, WAInitResponse, ConnectionState, DisconnectReason } from "../Types"
|
||||||
import { makeSocket } from "./socket"
|
import { makeSocket } from "./socket"
|
||||||
import { generateClientID, promiseTimeout } from "../Utils/generics"
|
import { generateClientID, promiseTimeout, normalizedAuthInfo, computeChallengeResponse, validateNewConnection } from "../Utils"
|
||||||
import { normalizedAuthInfo, computeChallengeResponse, validateNewConnection } from "../Utils/validate-connection"
|
|
||||||
import { randomBytes } from "crypto"
|
import { randomBytes } from "crypto"
|
||||||
import { AuthenticationCredentials } from "../Types"
|
import { AuthenticationCredentials } from "../Types"
|
||||||
|
|
||||||
@@ -106,7 +105,7 @@ const makeAuthSocket = (config: SocketConfig) => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
.finally(() => (
|
.finally(() => (
|
||||||
ev.off('state.update', listener)
|
ev.off('connection.update', listener)
|
||||||
))
|
))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
import { SocketConfig } from '../Types'
|
import { SocketConfig } from '../Types'
|
||||||
import { DEFAULT_CONNECTION_CONFIG } from '../Defaults'
|
import { DEFAULT_CONNECTION_CONFIG } from '../Defaults'
|
||||||
import { EventEmitter } from 'events'
|
import { EventEmitter } from 'events'
|
||||||
import * as Connection from './groups'
|
import _makeConnection from './groups'
|
||||||
// export the last socket layer
|
// export the last socket layer
|
||||||
const makeConnection = (config: Partial<SocketConfig>) => (
|
const makeConnection = (config: Partial<SocketConfig>) => (
|
||||||
Connection.default({
|
_makeConnection({
|
||||||
...DEFAULT_CONNECTION_CONFIG,
|
...DEFAULT_CONNECTION_CONFIG,
|
||||||
...config
|
...config
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export type Connection = ReturnType<typeof makeConnection>
|
||||||
|
|
||||||
export default makeConnection
|
export default makeConnection
|
||||||
@@ -1,12 +1,10 @@
|
|||||||
import BinaryNode from "../BinaryNode";
|
import BinaryNode from "../BinaryNode";
|
||||||
import { Boom } from '@hapi/boom'
|
import { Boom } from '@hapi/boom'
|
||||||
import { EventEmitter } from 'events'
|
import { EventEmitter } from 'events'
|
||||||
import { Chat, Presence, SocketConfig, WAMessage, WAMessageKey, ParticipantAction, WAMessageProto, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo } from "../Types";
|
import { Chat, Presence, WAMessageCursor, SocketConfig, WAMessage, WAMessageKey, ParticipantAction, WAMessageProto, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo } from "../Types";
|
||||||
import { isGroupID, toNumber, whatsappID } from "../Utils/generics";
|
import { isGroupID, toNumber, whatsappID, generateWAMessage, decryptMediaMessageBuffer } from "../Utils";
|
||||||
import makeChatsSocket from "./chats";
|
import makeChatsSocket from "./chats";
|
||||||
import { WA_DEFAULT_EPHEMERAL } from "../Defaults";
|
import { WA_DEFAULT_EPHEMERAL } from "../Defaults";
|
||||||
import { generateWAMessage } from "../Utils/messages";
|
|
||||||
import { decryptMediaMessageBuffer } from "../Utils/messages-media";
|
|
||||||
|
|
||||||
const STATUS_MAP = {
|
const STATUS_MAP = {
|
||||||
read: WAMessageStatus.READ,
|
read: WAMessageStatus.READ,
|
||||||
@@ -47,9 +45,12 @@ const makeMessagesSocket = (config: SocketConfig) => {
|
|||||||
const fetchMessagesFromWA = async(
|
const fetchMessagesFromWA = async(
|
||||||
jid: string,
|
jid: string,
|
||||||
count: number,
|
count: number,
|
||||||
indexMessage?: { id?: string; fromMe?: boolean },
|
cursor?: WAMessageCursor
|
||||||
mostRecentFirst: boolean = true
|
|
||||||
) => {
|
) => {
|
||||||
|
let key: WAMessageKey
|
||||||
|
if(cursor) {
|
||||||
|
key = 'before' in cursor ? cursor.before : cursor.after
|
||||||
|
}
|
||||||
const { data }:BinaryNode = await query({
|
const { data }:BinaryNode = await query({
|
||||||
json: new BinaryNode(
|
json: new BinaryNode(
|
||||||
'query',
|
'query',
|
||||||
@@ -57,10 +58,10 @@ const makeMessagesSocket = (config: SocketConfig) => {
|
|||||||
epoch: currentEpoch().toString(),
|
epoch: currentEpoch().toString(),
|
||||||
type: 'message',
|
type: 'message',
|
||||||
jid: jid,
|
jid: jid,
|
||||||
kind: mostRecentFirst ? 'before' : 'after',
|
kind: !cursor || 'before' in cursor ? 'before' : 'after',
|
||||||
count: count.toString(),
|
count: count.toString(),
|
||||||
index: indexMessage?.id,
|
index: key?.id,
|
||||||
owner: indexMessage?.fromMe === false ? 'false' : 'true',
|
owner: key?.fromMe === false ? 'false' : 'true',
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
binaryTag: [WAMetric.queryMessages, WAFlag.ignore],
|
binaryTag: [WAMetric.queryMessages, WAFlag.ignore],
|
||||||
@@ -91,7 +92,7 @@ const makeMessagesSocket = (config: SocketConfig) => {
|
|||||||
})
|
})
|
||||||
Object.keys(response[1]).forEach (key => content[key] = response[1][key]) // update message
|
Object.keys(response[1]).forEach (key => content[key] = response[1][key]) // update message
|
||||||
|
|
||||||
ev.emit('messages.upsert', { messages: [message], type: 'append' })
|
ev.emit('messages.update', [{ key: message.key, message: message.message }])
|
||||||
|
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
@@ -365,6 +366,18 @@ const makeMessagesSocket = (config: SocketConfig) => {
|
|||||||
},
|
},
|
||||||
updateMediaMessage,
|
updateMediaMessage,
|
||||||
fetchMessagesFromWA,
|
fetchMessagesFromWA,
|
||||||
|
/** Load a single message specified by the ID */
|
||||||
|
loadMessageFromWA: async(jid: string, id: string) => {
|
||||||
|
let message: WAMessage
|
||||||
|
|
||||||
|
// load the message before the given message
|
||||||
|
let messages = (await fetchMessagesFromWA(jid, 1, { before: {id, fromMe: true} }))
|
||||||
|
if(!messages[0]) messages = (await fetchMessagesFromWA(jid, 1, { before: {id, fromMe: false} }))
|
||||||
|
// the message after the loaded message is the message required
|
||||||
|
const [actual] = await fetchMessagesFromWA(jid, 1, { after: messages[0] && messages[0].key })
|
||||||
|
message = actual
|
||||||
|
return message
|
||||||
|
},
|
||||||
searchMessages: async(txt: string, inJid: string | null, count: number, page: number) => {
|
searchMessages: async(txt: string, inJid: string | null, count: number, page: number) => {
|
||||||
const {data, attributes}: BinaryNode = await query({
|
const {data, attributes}: BinaryNode = await query({
|
||||||
json: new BinaryNode(
|
json: new BinaryNode(
|
||||||
@@ -419,10 +432,6 @@ const makeMessagesSocket = (config: SocketConfig) => {
|
|||||||
{
|
{
|
||||||
...options,
|
...options,
|
||||||
userJid: userJid,
|
userJid: userJid,
|
||||||
/*ephemeralOptions: chat?.ephemeral ? {
|
|
||||||
expiration: chat.ephemeral,
|
|
||||||
eph_setting_ts: chat.eph_setting_ts
|
|
||||||
} : undefined,*/
|
|
||||||
getUrlInfo: generateUrlInfo,
|
getUrlInfo: generateUrlInfo,
|
||||||
getMediaOptions: refreshMediaConn
|
getMediaOptions: refreshMediaConn
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,7 @@ import { promisify } from "util"
|
|||||||
import WebSocket from "ws"
|
import WebSocket from "ws"
|
||||||
import BinaryNode from "../BinaryNode"
|
import BinaryNode from "../BinaryNode"
|
||||||
import { DisconnectReason, SocketConfig, SocketQueryOptions, SocketSendMessageOptions } from "../Types"
|
import { DisconnectReason, SocketConfig, SocketQueryOptions, SocketSendMessageOptions } from "../Types"
|
||||||
import { aesEncrypt, hmacSign, promiseTimeout, unixTimestampSeconds } from "../Utils/generics"
|
import { aesEncrypt, hmacSign, promiseTimeout, unixTimestampSeconds, decodeWAMessage } from "../Utils"
|
||||||
import { decodeWAMessage } from "../Utils/decode-wa-message"
|
|
||||||
import { WAFlag, WAMetric, WATag } from "../Types"
|
import { WAFlag, WAMetric, WATag } from "../Types"
|
||||||
import { DEFAULT_ORIGIN, DEF_CALLBACK_PREFIX, DEF_TAG_PREFIX, PHONE_CONNECTION_CB } from "../Defaults"
|
import { DEFAULT_ORIGIN, DEF_CALLBACK_PREFIX, DEF_TAG_PREFIX, PHONE_CONNECTION_CB } from "../Defaults"
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import { Browsers } from "../Utils/generics"
|
|||||||
|
|
||||||
export const UNAUTHORIZED_CODES = [401, 403, 419]
|
export const UNAUTHORIZED_CODES = [401, 403, 419]
|
||||||
|
|
||||||
|
export const STORIES_JID = 'status@broadcast'
|
||||||
|
|
||||||
export const DEFAULT_ORIGIN = 'https://web.whatsapp.com'
|
export const DEFAULT_ORIGIN = 'https://web.whatsapp.com'
|
||||||
export const DEF_CALLBACK_PREFIX = 'CB:'
|
export const DEF_CALLBACK_PREFIX = 'CB:'
|
||||||
export const DEF_TAG_PREFIX = 'TAG:'
|
export const DEF_TAG_PREFIX = 'TAG:'
|
||||||
|
|||||||
@@ -1,39 +1,44 @@
|
|||||||
import KeyedDB from "@adiwajshing/keyed-db"
|
import KeyedDB from "@adiwajshing/keyed-db"
|
||||||
|
import { Comparable } from "@adiwajshing/keyed-db/lib/Types"
|
||||||
import { Logger } from "pino"
|
import { Logger } from "pino"
|
||||||
import makeConnection from "../Connection"
|
import type { Connection } from "../Connection"
|
||||||
import { BaileysEventEmitter, Chat, ConnectionState, Contact, WAMessage, WAMessageKey } from "../Types"
|
import type { BaileysEventEmitter, Chat, ConnectionState, Contact, WAMessage, WAMessageCursor } from "../Types"
|
||||||
|
import { toNumber } from "../Utils"
|
||||||
|
import makeOrderedDictionary from "./ordered-dictionary"
|
||||||
|
|
||||||
export const waChatKey = (pin: boolean) => ({
|
export const waChatKey = (pin: boolean) => ({
|
||||||
key: (c: Chat) => (pin ? (c.pin ? '1' : '0') : '') + (c.archive === 'true' ? '0' : '1') + c.t.toString(16).padStart(8, '0') + c.jid,
|
key: (c: Chat) => (pin ? (c.pin ? '1' : '0') : '') + (c.archive === 'true' ? '0' : '1') + c.t.toString(16).padStart(8, '0') + c.jid,
|
||||||
compare: (k1: string, k2: string) => k2.localeCompare (k1)
|
compare: (k1: string, k2: string) => k2.localeCompare (k1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const waMessageID = (m: WAMessage) => m.key.id
|
||||||
|
|
||||||
export type BaileysInMemoryStoreConfig = {
|
export type BaileysInMemoryStoreConfig = {
|
||||||
|
chatKey: Comparable<Chat, string>
|
||||||
logger: Logger
|
logger: Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const makeMessagesDictionary = () => makeOrderedDictionary(waMessageID)
|
||||||
|
|
||||||
export default(
|
export default(
|
||||||
{ logger }: BaileysInMemoryStoreConfig
|
{ logger, chatKey }: BaileysInMemoryStoreConfig
|
||||||
) => {
|
) => {
|
||||||
const chats = new KeyedDB<Chat, string>(waChatKey(true), c => c.jid)
|
|
||||||
const messages: { [_: string]: WAMessage[] } = {}
|
const chats = new KeyedDB<Chat, string>(chatKey, c => c.jid)
|
||||||
|
const messages: { [_: string]: ReturnType<typeof makeMessagesDictionary> } = {}
|
||||||
const contacts: { [_: string]: Contact } = {}
|
const contacts: { [_: string]: Contact } = {}
|
||||||
const state: ConnectionState = {
|
const state: ConnectionState = {
|
||||||
connection: 'close',
|
connection: 'close',
|
||||||
phoneConnected: false
|
phoneConnected: false
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageIndex = (key: WAMessageKey) => {
|
const assertMessageList = (jid: string) => {
|
||||||
const messageList = messages[key.remoteJid!]
|
if(!messages[jid]) messages[jid] = makeMessagesDictionary()
|
||||||
if(messageList) {
|
return messages[jid]
|
||||||
const idx = messageList.findIndex(m => m.key.id === key.id)
|
|
||||||
if(idx >= 0) {
|
|
||||||
return { messageList, idx }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const listen = (ev: BaileysEventEmitter) => {
|
const listen = (ev: BaileysEventEmitter) => {
|
||||||
|
|
||||||
ev.on('connection.update', update => {
|
ev.on('connection.update', update => {
|
||||||
Object.assign(state, update)
|
Object.assign(state, update)
|
||||||
})
|
})
|
||||||
@@ -91,55 +96,54 @@ export default(
|
|||||||
case 'notify':
|
case 'notify':
|
||||||
for(const msg of newMessages) {
|
for(const msg of newMessages) {
|
||||||
const jid = msg.key.remoteJid!
|
const jid = msg.key.remoteJid!
|
||||||
const result = messageIndex(newMessages[0].key)
|
const list = assertMessageList(jid)
|
||||||
if(!result) {
|
list.upsert(msg, 'append')
|
||||||
if(!messages[jid]) {
|
|
||||||
messages[jid] = []
|
if(type === 'notify' && !chats.get(jid)) {
|
||||||
}
|
ev.emit('chats.upsert', {
|
||||||
messages[jid].push(msg)
|
chats: [ { jid, t: toNumber(msg.messageTimestamp), count: 1 } ],
|
||||||
} else {
|
type: 'upsert'
|
||||||
result.messageList[result.idx] = msg
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'last':
|
case 'last':
|
||||||
for(const msg of newMessages) {
|
for(const msg of newMessages) {
|
||||||
const jid = msg.key.remoteJid!
|
const jid = msg.key.remoteJid!
|
||||||
if(!messages[jid]) {
|
const list = assertMessageList(jid)
|
||||||
messages[jid] = []
|
const [lastItem] = list.array.slice(-1)
|
||||||
}
|
|
||||||
const [lastItem] = messages[jid].slice(-1)
|
|
||||||
// reset message list
|
// reset message list
|
||||||
if(lastItem && lastItem.key.id !== msg.key.id) {
|
if(lastItem && lastItem.key.id !== msg.key.id) {
|
||||||
messages[jid] = [msg]
|
list.clear()
|
||||||
|
list.upsert(msg, 'append')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'prepend':
|
case 'prepend':
|
||||||
|
for(const msg of newMessages) {
|
||||||
|
const jid = msg.key.remoteJid!
|
||||||
|
const list = assertMessageList(jid)
|
||||||
|
list.upsert(msg, 'prepend')
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
ev.on('messages.update', updates => {
|
ev.on('messages.update', updates => {
|
||||||
for(const update of updates) {
|
for(const update of updates) {
|
||||||
const result = messageIndex(update.key!)
|
const list = assertMessageList(update.key.remoteJid)
|
||||||
if(result) {
|
const result = list.updateAssign(update)
|
||||||
Object.assign(result.messageList[result.idx], update)
|
if(!result) {
|
||||||
} else {
|
|
||||||
logger.debug({ update }, `got update for non-existant message`)
|
logger.debug({ update }, `got update for non-existant message`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
ev.on('messages.delete', item => {
|
ev.on('messages.delete', item => {
|
||||||
|
const list = assertMessageList(item.jid)
|
||||||
if('all' in item) {
|
if('all' in item) {
|
||||||
messages[item.jid] = []
|
list.clear()
|
||||||
} else {
|
} else {
|
||||||
const idSet = new Set(item.ids)
|
const idSet = new Set(item.ids)
|
||||||
if(messages[item.jid]) {
|
list.filter(m => !idSet.has(m.key.id))
|
||||||
messages[item.jid] = messages[item.jid].filter(
|
|
||||||
m => !idSet.has(m.key.id)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -148,14 +152,60 @@ export default(
|
|||||||
chats,
|
chats,
|
||||||
contacts,
|
contacts,
|
||||||
messages,
|
messages,
|
||||||
|
state,
|
||||||
listen,
|
listen,
|
||||||
fetchImageUrl: async(jid: string, sock: ReturnType<typeof makeConnection>) => {
|
loadMessages: async(jid: string, count: number, cursor: WAMessageCursor, sock: Connection | undefined) => {
|
||||||
|
const list = assertMessageList(jid)
|
||||||
|
const retrieve = async(count: number, cursor: WAMessageCursor) => {
|
||||||
|
const result = await sock?.fetchMessagesFromWA(jid, count, cursor)
|
||||||
|
return result || []
|
||||||
|
}
|
||||||
|
const mode = !cursor || 'before' in cursor ? 'before' : 'after'
|
||||||
|
const cursorKey = !!cursor ? ('before' in cursor ? cursor.before : cursor.after) : undefined
|
||||||
|
const cursorValue = cursorKey ? list.get(cursorKey.id) : undefined
|
||||||
|
|
||||||
|
let messages: WAMessage[]
|
||||||
|
if(messages && mode ==='before' && (!cursorKey || cursorValue)) {
|
||||||
|
const msgIdx = messages.findIndex(m => m.key.id === cursorKey.id)
|
||||||
|
messages = list.array.slice(0, msgIdx)
|
||||||
|
|
||||||
|
const diff = count - messages.length
|
||||||
|
if (diff < 0) {
|
||||||
|
messages = messages.slice(-count) // get the last X messages
|
||||||
|
} else if (diff > 0) {
|
||||||
|
const [fMessage] = messages
|
||||||
|
const extra = await retrieve (diff, { before: fMessage?.key || cursorKey })
|
||||||
|
// add to DB
|
||||||
|
for(let i = extra.length-1; i >= 0;i--) {
|
||||||
|
list.upsert(extra[i], 'prepend')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else messages = await retrieve(count, cursor)
|
||||||
|
|
||||||
|
return messages
|
||||||
|
},
|
||||||
|
loadMessage: async(jid: string, id: string, sock: Connection | undefined) => {
|
||||||
|
let message = messages[jid]?.get(id)
|
||||||
|
if(!message) {
|
||||||
|
message = await sock?.loadMessageFromWA(jid, id)
|
||||||
|
}
|
||||||
|
return message
|
||||||
|
},
|
||||||
|
mostRecentMessage: async(jid: string, sock: Connection | undefined) => {
|
||||||
|
let message = messages[jid]?.array.slice(-1)[0]
|
||||||
|
if(!message) {
|
||||||
|
const [result] = await sock?.fetchMessagesFromWA(jid, 1, undefined)
|
||||||
|
message = result
|
||||||
|
}
|
||||||
|
return message
|
||||||
|
},
|
||||||
|
fetchImageUrl: async(jid: string, sock: Connection | undefined) => {
|
||||||
const contact = contacts[jid]
|
const contact = contacts[jid]
|
||||||
if(!contact) {
|
if(!contact) {
|
||||||
return sock.fetchImageUrl(jid)
|
return sock?.fetchImageUrl(jid)
|
||||||
}
|
}
|
||||||
if(!contact.imgUrl) {
|
if(!contact.imgUrl) {
|
||||||
contact.imgUrl = await sock.fetchImageUrl(jid)
|
contact.imgUrl = await sock?.fetchImageUrl(jid)
|
||||||
}
|
}
|
||||||
return contact.imgUrl
|
return contact.imgUrl
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
import inMemoryStore from "./in-memory-store";
|
import makeInMemoryStore from './in-memory-store'
|
||||||
export default inMemoryStore
|
export { makeInMemoryStore }
|
||||||
66
src/Store/ordered-dictionary.ts
Normal file
66
src/Store/ordered-dictionary.ts
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
|
||||||
|
const makeOrderedDictionary = function<T>(idGetter: (item: T) => string) {
|
||||||
|
const array: T[] = []
|
||||||
|
const dict: { [_: string]: T } = { }
|
||||||
|
|
||||||
|
const get = (id: string) => dict[id]
|
||||||
|
|
||||||
|
const update = (item: T) => {
|
||||||
|
const id = idGetter(item)
|
||||||
|
const idx = array.findIndex(i => idGetter(i) === id)
|
||||||
|
if(idx >= 0) {
|
||||||
|
array[idx] = item
|
||||||
|
dict[id] = item
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const upsert = (item: T, mode: 'append' | 'prepend') => {
|
||||||
|
const id = idGetter(item)
|
||||||
|
if(get(id)) {
|
||||||
|
update(item)
|
||||||
|
} else {
|
||||||
|
if(mode === 'append') {
|
||||||
|
array.push(item)
|
||||||
|
} else {
|
||||||
|
array.splice(0, 0, item)
|
||||||
|
}
|
||||||
|
dict[id] = item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const remove = (item: T) => {
|
||||||
|
const id = idGetter(item)
|
||||||
|
const idx = array.findIndex(i => idGetter(i) === id)
|
||||||
|
if(idx >= 0) {
|
||||||
|
array.splice(idx, 1)
|
||||||
|
delete dict[id]
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
array,
|
||||||
|
get,
|
||||||
|
upsert,
|
||||||
|
update,
|
||||||
|
remove,
|
||||||
|
updateAssign: (update: Partial<T>) => {
|
||||||
|
const item = get(idGetter(update as any))
|
||||||
|
if(item) {
|
||||||
|
Object.assign(item, update)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
clear: () => {
|
||||||
|
array.splice(0, array.length)
|
||||||
|
Object.keys(dict).forEach(key => { delete dict[key] })
|
||||||
|
},
|
||||||
|
filter: (contain: (item: T) => boolean) => {
|
||||||
|
//const copy =
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default makeOrderedDictionary
|
||||||
|
//export type OrderedDictionary<T> = ReturnType<typeof makeOrderedDictionary>
|
||||||
@@ -54,4 +54,5 @@ export type ChatModification =
|
|||||||
messages: { id: string, fromMe?: boolean }[],
|
messages: { id: string, fromMe?: boolean }[],
|
||||||
star: boolean
|
star: boolean
|
||||||
}
|
}
|
||||||
}
|
} |
|
||||||
|
{ delete: true }
|
||||||
@@ -78,7 +78,6 @@ export type AnyMediaMessageContent = (
|
|||||||
{ mimetype?: string }
|
{ mimetype?: string }
|
||||||
|
|
||||||
export type AnyRegularMessageContent =
|
export type AnyRegularMessageContent =
|
||||||
string |
|
|
||||||
({
|
({
|
||||||
text: string
|
text: string
|
||||||
}
|
}
|
||||||
@@ -109,14 +108,15 @@ export type MiscMessageGenerationOptions = {
|
|||||||
timestamp?: Date
|
timestamp?: Date
|
||||||
/** the message you want to quote */
|
/** the message you want to quote */
|
||||||
quoted?: WAMessage
|
quoted?: WAMessage
|
||||||
}
|
/** disappearing messages settings */
|
||||||
export type MessageGenerationOptionsFromContent = MiscMessageGenerationOptions & {
|
|
||||||
userJid: string
|
|
||||||
ephemeralOptions?: {
|
ephemeralOptions?: {
|
||||||
expiration: number | string
|
expiration: number | string
|
||||||
eph_setting_ts: number | string
|
eph_setting_ts: number | string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export type MessageGenerationOptionsFromContent = MiscMessageGenerationOptions & {
|
||||||
|
userJid: string
|
||||||
|
}
|
||||||
export type MediaGenerationOptions = {
|
export type MediaGenerationOptions = {
|
||||||
logger?: Logger
|
logger?: Logger
|
||||||
agent?: Agent
|
agent?: Agent
|
||||||
@@ -133,3 +133,19 @@ export interface MessageInfo {
|
|||||||
reads: {jid: string, t: string}[]
|
reads: {jid: string, t: string}[]
|
||||||
deliveries: {jid: string, t: string}[]
|
deliveries: {jid: string, t: string}[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface MessageStatusUpdate {
|
||||||
|
from: string
|
||||||
|
to: string
|
||||||
|
/** Which participant caused the update (only for groups) */
|
||||||
|
participant?: string
|
||||||
|
timestamp: Date
|
||||||
|
/** Message IDs read/delivered */
|
||||||
|
ids: string[]
|
||||||
|
/** Status of the Message IDs */
|
||||||
|
type: WAMessageStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export type WAMessageCursor = { before: WAMessageKey | undefined } | { after: WAMessageKey | undefined }
|
||||||
@@ -195,5 +195,7 @@ export type BaileysEventMap = {
|
|||||||
}
|
}
|
||||||
export interface BaileysEventEmitter extends EventEmitter {
|
export interface BaileysEventEmitter extends EventEmitter {
|
||||||
on<T extends keyof BaileysEventMap>(event: T, listener: (arg: BaileysEventMap[T]) => void): this
|
on<T extends keyof BaileysEventMap>(event: T, listener: (arg: BaileysEventMap[T]) => void): this
|
||||||
|
off<T extends keyof BaileysEventMap>(event: T, listener: (arg: BaileysEventMap[T]) => void): this
|
||||||
|
removeAllListeners<T extends keyof BaileysEventMap>(event: T): this
|
||||||
emit<T extends keyof BaileysEventMap>(event: T, arg: BaileysEventMap[T]): boolean
|
emit<T extends keyof BaileysEventMap>(event: T, arg: BaileysEventMap[T]): boolean
|
||||||
}
|
}
|
||||||
5
src/Utils/index.ts
Normal file
5
src/Utils/index.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export * from './decode-wa-message'
|
||||||
|
export * from './generics'
|
||||||
|
export * from './messages'
|
||||||
|
export * from './messages-media'
|
||||||
|
export * from './validate-connection'
|
||||||
@@ -220,9 +220,6 @@ export const generateWAMessageContent = async(
|
|||||||
options: MessageContentGenerationOptions
|
options: MessageContentGenerationOptions
|
||||||
) => {
|
) => {
|
||||||
let m: WAMessageContent = {}
|
let m: WAMessageContent = {}
|
||||||
if(typeof message === 'string') {
|
|
||||||
message = { text: message }
|
|
||||||
}
|
|
||||||
if('text' in message) {
|
if('text' in message) {
|
||||||
const extContent = { ...message } as WATextMessage
|
const extContent = { ...message } as WATextMessage
|
||||||
if (!!options.getUrlInfo && message.text.match(URL_REGEX)) {
|
if (!!options.getUrlInfo && message.text.match(URL_REGEX)) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {Boom} from '@hapi/boom'
|
import {Boom} from '@hapi/boom'
|
||||||
import * as Curve from 'curve25519-js'
|
import * as Curve from 'curve25519-js'
|
||||||
import type { Contact } from '../Types/Contact'
|
import type { Contact } from '../Types/Contact'
|
||||||
import type { AnyAuthenticationCredentials, AuthenticationCredentials, CurveKeyPair } from "../Types"
|
import type { AnyAuthenticationCredentials, AuthenticationCredentials, AuthenticationCredentialsBase64, CurveKeyPair } from "../Types"
|
||||||
import { aesDecrypt, hkdf, hmacSign, whatsappID } from './generics'
|
import { aesDecrypt, hkdf, hmacSign, whatsappID } from './generics'
|
||||||
import { readFileSync } from 'fs'
|
import { readFileSync } from 'fs'
|
||||||
|
|
||||||
@@ -32,6 +32,16 @@ export const normalizedAuthInfo = (authInfo: AnyAuthenticationCredentials | stri
|
|||||||
}
|
}
|
||||||
return authInfo as AuthenticationCredentials
|
return authInfo as AuthenticationCredentials
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const base64EncodedAuthenticationCredentials = (creds: AnyAuthenticationCredentials) => {
|
||||||
|
const normalized = normalizedAuthInfo(creds)
|
||||||
|
return {
|
||||||
|
...normalized,
|
||||||
|
encKey: normalized.encKey.toString('base64'),
|
||||||
|
macKey: normalized.macKey.toString('base64')
|
||||||
|
} as AuthenticationCredentialsBase64
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Once the QR code is scanned and we can validate our connection, or we resolved the challenge when logging back in
|
* Once the QR code is scanned and we can validate our connection, or we resolved the challenge when logging back in
|
||||||
* @private
|
* @private
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import makeConnection from './Connection'
|
import makeConnection from './Connection'
|
||||||
|
|
||||||
export * from '../WAMessage/WAMessage'
|
export * from '../WAMessage/WAMessage'
|
||||||
export * from './Utils/messages'
|
export * from './Utils'
|
||||||
export * from './Types'
|
export * from './Types'
|
||||||
export * from './Store'
|
export * from './Store'
|
||||||
|
export * from './Defaults'
|
||||||
|
|
||||||
export default makeConnection
|
export default makeConnection
|
||||||
Reference in New Issue
Block a user