mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
feat: add desktop + full history sync opts
This commit is contained in:
53
README.md
53
README.md
@@ -103,35 +103,44 @@ The entire `SocketConfig` structure is mentioned here with default values:
|
|||||||
``` ts
|
``` ts
|
||||||
type SocketConfig = {
|
type SocketConfig = {
|
||||||
/** provide an auth state object to maintain the auth state */
|
/** provide an auth state object to maintain the auth state */
|
||||||
auth?: AuthenticationState
|
auth: AuthenticationState
|
||||||
/** the WS url to connect to WA */
|
/** By default true, should history messages be downloaded and processed */
|
||||||
waWebSocketUrl: string | URL
|
downloadHistory: boolean
|
||||||
/** Fails the connection if the connection times out in this time interval or no data is received */
|
/** transaction capability options for SignalKeyStore */
|
||||||
connectTimeoutMs: number
|
transactionOpts: TransactionCapabilityOptions
|
||||||
/** Default timeout for queries, undefined for no timeout */
|
/** provide a cache to store a user's device list */
|
||||||
defaultQueryTimeoutMs: number | undefined
|
userDevicesCache?: NodeCache
|
||||||
/** ping-pong interval for WS connection */
|
/** marks the client as online whenever the socket successfully connects */
|
||||||
keepAliveIntervalMs: number
|
markOnlineOnConnect: boolean
|
||||||
/** proxy agent */
|
/**
|
||||||
agent?: Agent
|
* map to store the retry counts for failed messages;
|
||||||
/** pino logger */
|
* used to determine whether to retry a message or not */
|
||||||
logger: Logger
|
msgRetryCounterMap?: MessageRetryMap
|
||||||
/** version to connect with */
|
/** width for link preview images */
|
||||||
version: WAVersion
|
linkPreviewImageThumbnailWidth: number
|
||||||
/** override browser config */
|
/** Should Baileys ask the phone for full history, will be received async */
|
||||||
browser: WABrowserDescription
|
syncFullHistory: boolean
|
||||||
/** agent used for fetch requests -- uploading/downloading media */
|
|
||||||
fetchAgent?: Agent
|
|
||||||
/** should the QR be printed in the terminal */
|
|
||||||
printQRInTerminal: boolean
|
|
||||||
/**
|
/**
|
||||||
* fetch a message from your store
|
* fetch a message from your store
|
||||||
* implement this so that messages that failed to send (solves the "this message can take a while" issue) can be retried
|
* implement this so that messages failed to send (solves the "this message can take a while" issue) can be retried
|
||||||
* */
|
* */
|
||||||
getMessage: (key: proto.IMessageKey) => Promise<proto.IMessage | undefined>
|
getMessage: (key: proto.IMessageKey) => Promise<proto.IMessage | undefined>
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Emulating the Desktop app instead of the web
|
||||||
|
|
||||||
|
1. Baileys, by default, emulates a chrome web session
|
||||||
|
2. If you'd like to emulate a desktop connection (and receive more message history), add this to your Socket config:
|
||||||
|
``` ts
|
||||||
|
const conn = makeWASocket({
|
||||||
|
...otherOpts,
|
||||||
|
// can use Windows, Ubuntu here too
|
||||||
|
browser: Browsers.macOS('Desktop'),
|
||||||
|
syncFullHistory: true
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
## Saving & Restoring Sessions
|
## Saving & Restoring Sessions
|
||||||
|
|
||||||
You obviously don't want to keep scanning the QR code every time you want to connect.
|
You obviously don't want to keep scanning the QR code every time you want to connect.
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ export const DEFAULT_CONNECTION_CONFIG: SocketConfig = {
|
|||||||
auth: undefined as any,
|
auth: undefined as any,
|
||||||
downloadHistory: true,
|
downloadHistory: true,
|
||||||
markOnlineOnConnect: true,
|
markOnlineOnConnect: true,
|
||||||
|
syncFullHistory: false,
|
||||||
linkPreviewImageThumbnailWidth: 192,
|
linkPreviewImageThumbnailWidth: 192,
|
||||||
transactionOpts: { maxCommitRetries: 10, delayBetweenTriesMs: 3000 },
|
transactionOpts: { maxCommitRetries: 10, delayBetweenTriesMs: 3000 },
|
||||||
getMessage: async() => undefined
|
getMessage: async() => undefined
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export const makeSocket = ({
|
|||||||
auth: authState,
|
auth: authState,
|
||||||
printQRInTerminal,
|
printQRInTerminal,
|
||||||
defaultQueryTimeoutMs,
|
defaultQueryTimeoutMs,
|
||||||
|
syncFullHistory,
|
||||||
transactionOpts
|
transactionOpts
|
||||||
}: SocketConfig) => {
|
}: SocketConfig) => {
|
||||||
const ws = new WebSocket(waWebSocketUrl, undefined, {
|
const ws = new WebSocket(waWebSocketUrl, undefined, {
|
||||||
@@ -178,12 +179,14 @@ export const makeSocket = ({
|
|||||||
|
|
||||||
const keyEnc = noise.processHandshake(handshake, creds.noiseKey)
|
const keyEnc = noise.processHandshake(handshake, creds.noiseKey)
|
||||||
|
|
||||||
|
const config = { version, browser, syncFullHistory }
|
||||||
|
|
||||||
let node: proto.IClientPayload
|
let node: proto.IClientPayload
|
||||||
if(!creds.me) {
|
if(!creds.me) {
|
||||||
node = generateRegistrationNode(creds, { version, browser })
|
node = generateRegistrationNode(creds, config)
|
||||||
logger.info({ node }, 'not logged in, attempting registration...')
|
logger.info({ node }, 'not logged in, attempting registration...')
|
||||||
} else {
|
} else {
|
||||||
node = generateLoginNode(creds.me!.id, { version, browser })
|
node = generateLoginNode(creds.me!.id, config)
|
||||||
logger.info({ node }, 'logging in...')
|
logger.info({ node }, 'logging in...')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ export type SocketConfig = CommonSocketConfig & {
|
|||||||
msgRetryCounterMap?: MessageRetryMap
|
msgRetryCounterMap?: MessageRetryMap
|
||||||
/** width for link preview images */
|
/** width for link preview images */
|
||||||
linkPreviewImageThumbnailWidth: number
|
linkPreviewImageThumbnailWidth: number
|
||||||
|
/** Should Baileys ask the phone for full history, will be received async */
|
||||||
|
syncFullHistory: boolean
|
||||||
/**
|
/**
|
||||||
* fetch a message from your store
|
* fetch a message from your store
|
||||||
* implement this so that messages failed to send (solves the "this message can take a while" issue) can be retried
|
* implement this so that messages failed to send (solves the "this message can take a while" issue) can be retried
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export const processHistoryMessage = (
|
|||||||
const curItem = recvChats[message.key.remoteJid!]
|
const curItem = recvChats[message.key.remoteJid!]
|
||||||
const timestamp = toNumber(message.messageTimestamp)
|
const timestamp = toNumber(message.messageTimestamp)
|
||||||
if(!message.key.fromMe && (!curItem || timestamp > curItem.lastMsgRecvTimestamp)) {
|
if(!message.key.fromMe && (!curItem || timestamp > curItem.lastMsgRecvTimestamp)) {
|
||||||
recvChats[message.key.remoteJid!] = { lastMsgRecvTimestamp: timestamp }
|
recvChats[chat.id] = { lastMsgRecvTimestamp: timestamp }
|
||||||
// keep only the most recent message in the chat array
|
// keep only the most recent message in the chat array
|
||||||
chat.messages = [{ message }]
|
chat.messages = [{ message }]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { Curve, hmacSign } from './crypto'
|
|||||||
import { encodeBigEndian } from './generics'
|
import { encodeBigEndian } from './generics'
|
||||||
import { createSignalIdentity } from './signal'
|
import { createSignalIdentity } from './signal'
|
||||||
|
|
||||||
type ClientPayloadConfig = Pick<SocketConfig, 'version' | 'browser'>
|
type ClientPayloadConfig = Pick<SocketConfig, 'version' | 'browser' | 'syncFullHistory'>
|
||||||
|
|
||||||
const getUserAgent = ({ version }: ClientPayloadConfig): proto.IUserAgent => {
|
const getUserAgent = ({ version }: ClientPayloadConfig): proto.IUserAgent => {
|
||||||
const osVersion = '0.1'
|
const osVersion = '0.1'
|
||||||
@@ -31,16 +31,26 @@ const getUserAgent = ({ version }: ClientPayloadConfig): proto.IUserAgent => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getWebInfo = (): proto.IWebInfo => ({
|
const PLATFORM_MAP = {
|
||||||
webSubPlatform: proto.WebInfo.WebInfoWebSubPlatform.WEB_BROWSER
|
'Mac OS': proto.WebInfo.WebInfoWebSubPlatform.DARWIN,
|
||||||
})
|
'Windows': proto.WebInfo.WebInfoWebSubPlatform.WIN32
|
||||||
|
}
|
||||||
|
|
||||||
|
const getWebInfo = (config: ClientPayloadConfig): proto.IWebInfo => {
|
||||||
|
let webSubPlatform = proto.WebInfo.WebInfoWebSubPlatform.WEB_BROWSER
|
||||||
|
if(config.syncFullHistory && PLATFORM_MAP[config.browser[0]]) {
|
||||||
|
webSubPlatform = PLATFORM_MAP[config.browser[0]]
|
||||||
|
}
|
||||||
|
|
||||||
|
return { webSubPlatform }
|
||||||
|
}
|
||||||
|
|
||||||
const getClientPayload = (config: ClientPayloadConfig): proto.IClientPayload => {
|
const getClientPayload = (config: ClientPayloadConfig): proto.IClientPayload => {
|
||||||
return {
|
return {
|
||||||
connectType: proto.ClientPayload.ClientPayloadConnectType.WIFI_UNKNOWN,
|
connectType: proto.ClientPayload.ClientPayloadConnectType.WIFI_UNKNOWN,
|
||||||
connectReason: proto.ClientPayload.ClientPayloadConnectReason.USER_ACTIVATED,
|
connectReason: proto.ClientPayload.ClientPayloadConnectReason.USER_ACTIVATED,
|
||||||
userAgent: getUserAgent(config),
|
userAgent: getUserAgent(config),
|
||||||
webInfo: getWebInfo(),
|
webInfo: getWebInfo(config),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +85,7 @@ export const generateRegistrationNode = (
|
|||||||
},
|
},
|
||||||
platformType: proto.DeviceProps.DevicePropsPlatformType[config.browser[1].toUpperCase()]
|
platformType: proto.DeviceProps.DevicePropsPlatformType[config.browser[1].toUpperCase()]
|
||||||
|| proto.DeviceProps.DevicePropsPlatformType.UNKNOWN,
|
|| proto.DeviceProps.DevicePropsPlatformType.UNKNOWN,
|
||||||
requireFullSync: false,
|
requireFullSync: config.syncFullHistory,
|
||||||
}
|
}
|
||||||
|
|
||||||
const companionProto = proto.DeviceProps.encode(companion).finish()
|
const companionProto = proto.DeviceProps.encode(companion).finish()
|
||||||
|
|||||||
Reference in New Issue
Block a user