mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
PTT Audio + Automatic link preview generation + Minor changes
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,3 +12,4 @@ lib
|
|||||||
docs
|
docs
|
||||||
browser-token.json
|
browser-token.json
|
||||||
auth_info_messcat.json
|
auth_info_messcat.json
|
||||||
|
Proxy
|
||||||
@@ -223,7 +223,11 @@ To note:
|
|||||||
mimetype: Mimetype.pdf, /* (for media messages) specify the type of media (optional for all media types except documents),
|
mimetype: Mimetype.pdf, /* (for media messages) specify the type of media (optional for all media types except documents),
|
||||||
import {Mimetype} from '@adiwajshing/baileys'
|
import {Mimetype} from '@adiwajshing/baileys'
|
||||||
*/
|
*/
|
||||||
filename: 'somefile.pdf' // (for media messages) file name for the media
|
filename: 'somefile.pdf', // (for media messages) file name for the media
|
||||||
|
/* will send audio messages as voice notes, if set to true */
|
||||||
|
ptt: true,
|
||||||
|
// will detect links & generate a link preview automatically (default true)
|
||||||
|
detectLinks: true
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
## Forwarding Messages
|
## Forwarding Messages
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ WAConnectionTest('Messages', conn => {
|
|||||||
assert.equal (content?.contextInfo?.isForwarded, true)
|
assert.equal (content?.contextInfo?.isForwarded, true)
|
||||||
})
|
})
|
||||||
it('should send a link preview', async () => {
|
it('should send a link preview', async () => {
|
||||||
const content = await conn.generateLinkPreview ('hello this is from https://www.github.com/adiwajshing/Baileys')
|
const text = 'hello this is from https://www.github.com/adiwajshing/Baileys'
|
||||||
const message = await sendAndRetreiveMessage(conn, content, MessageType.text)
|
const message = await sendAndRetreiveMessage(conn, text, MessageType.text, { detectLinks: true })
|
||||||
const received = message.message.extendedTextMessage
|
const received = message.message.extendedTextMessage
|
||||||
|
|
||||||
assert.strictEqual(received.text, content.text)
|
assert.strictEqual(received.text, text)
|
||||||
assert.ok (received.canonicalUrl)
|
assert.ok (received.canonicalUrl)
|
||||||
assert.ok (received.title)
|
assert.ok (received.title)
|
||||||
assert.ok (received.description)
|
assert.ok (received.description)
|
||||||
@@ -58,6 +58,13 @@ WAConnectionTest('Messages', conn => {
|
|||||||
|
|
||||||
await conn.downloadAndSaveMediaMessage(message,'./Media/received_aud')
|
await conn.downloadAndSaveMediaMessage(message,'./Media/received_aud')
|
||||||
})
|
})
|
||||||
|
it('should send an audio as a voice note', async () => {
|
||||||
|
const content = await fs.readFile('./Media/sonata.mp3')
|
||||||
|
const message = await sendAndRetreiveMessage(conn, content, MessageType.audio, { mimetype: Mimetype.ogg, ptt: true })
|
||||||
|
|
||||||
|
assert.equal (message.message?.audioMessage?.ptt, true)
|
||||||
|
await conn.downloadAndSaveMediaMessage(message,'./Media/received_aud')
|
||||||
|
})
|
||||||
it('should send an image', async () => {
|
it('should send an image', async () => {
|
||||||
const content = await fs.readFile('./Media/meme.jpeg')
|
const content = await fs.readFile('./Media/meme.jpeg')
|
||||||
const message = await sendAndRetreiveMessage(conn, content, MessageType.image)
|
const message = await sendAndRetreiveMessage(conn, content, MessageType.image)
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import {
|
|||||||
} from './Constants'
|
} from './Constants'
|
||||||
import { EventEmitter } from 'events'
|
import { EventEmitter } from 'events'
|
||||||
import KeyedDB from '@adiwajshing/keyed-db'
|
import KeyedDB from '@adiwajshing/keyed-db'
|
||||||
import { STATUS_CODES } from 'http'
|
import { STATUS_CODES, Agent } from 'http'
|
||||||
|
|
||||||
export class WAConnection extends EventEmitter {
|
export class WAConnection extends EventEmitter {
|
||||||
/** The version of WhatsApp Web we're telling the servers we are */
|
/** The version of WhatsApp Web we're telling the servers we are */
|
||||||
@@ -341,6 +341,8 @@ export class WAConnection extends EventEmitter {
|
|||||||
}
|
}
|
||||||
protected endConnection () {
|
protected endConnection () {
|
||||||
this.conn?.removeAllListeners ('close')
|
this.conn?.removeAllListeners ('close')
|
||||||
|
this.conn?.removeAllListeners ('error')
|
||||||
|
this.conn?.removeAllListeners ('open')
|
||||||
this.conn?.removeAllListeners ('message')
|
this.conn?.removeAllListeners ('message')
|
||||||
//this.conn?.close ()
|
//this.conn?.close ()
|
||||||
this.conn?.terminate()
|
this.conn?.terminate()
|
||||||
@@ -358,12 +360,12 @@ export class WAConnection extends EventEmitter {
|
|||||||
/**
|
/**
|
||||||
* Does a fetch request with the configuration of the connection
|
* Does a fetch request with the configuration of the connection
|
||||||
*/
|
*/
|
||||||
protected fetchRequest = (endpoint: string, method: string = 'GET', body?: any) => (
|
protected fetchRequest = (endpoint: string, method: string = 'GET', body?: any, agent?: Agent) => (
|
||||||
fetch(endpoint, {
|
fetch(endpoint, {
|
||||||
method,
|
method,
|
||||||
body,
|
body,
|
||||||
headers: { Origin: DEFAULT_ORIGIN },
|
headers: { Origin: DEFAULT_ORIGIN },
|
||||||
agent: this.connectOptions.agent
|
agent: agent || this.connectOptions.agent
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
generateMessageTag (longTag: boolean = false) {
|
generateMessageTag (longTag: boolean = false) {
|
||||||
|
|||||||
@@ -35,14 +35,15 @@ export class WAConnection extends Base {
|
|||||||
|
|
||||||
const loggedOut = error instanceof BaileysError && UNAUTHORIZED_CODES.includes(error.status)
|
const loggedOut = error instanceof BaileysError && UNAUTHORIZED_CODES.includes(error.status)
|
||||||
const willReconnect = !loggedOut && (tries <= (options?.maxRetries || 5)) && this.state === 'connecting'
|
const willReconnect = !loggedOut && (tries <= (options?.maxRetries || 5)) && this.state === 'connecting'
|
||||||
|
const reason = loggedOut ? DisconnectReason.invalidSession : error.message
|
||||||
|
|
||||||
this.log (`connect attempt ${tries} failed: ${error}${ willReconnect ? ', retrying...' : ''}`, MessageLogLevel.info)
|
this.log (`connect attempt ${tries} failed: ${error}${ willReconnect ? ', retrying...' : ''}`, MessageLogLevel.info)
|
||||||
|
|
||||||
if ((this.state as string) !== 'close' && !willReconnect) {
|
if ((this.state as string) !== 'close' && !willReconnect) {
|
||||||
this.closeInternal (loggedOut ? DisconnectReason.invalidSession : error.message)
|
this.closeInternal (reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!willReconnect) throw error
|
if (!willReconnect) throw error
|
||||||
|
this.emit ('intermediate-close', {reason})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,19 +68,12 @@ export class WAConnection extends Base {
|
|||||||
|
|
||||||
let cancel: () => void
|
let cancel: () => void
|
||||||
const task = Utils.promiseTimeout(timeoutMs, (resolve, reject) => {
|
const task = Utils.promiseTimeout(timeoutMs, (resolve, reject) => {
|
||||||
let task: Promise<any> = Promise.resolve ()
|
cancel = () => reject (CancelledError())
|
||||||
const checkIdleTime = () => {
|
const checkIdleTime = () => {
|
||||||
this.debounceTimeout && clearTimeout (this.debounceTimeout)
|
this.debounceTimeout && clearTimeout (this.debounceTimeout)
|
||||||
this.debounceTimeout = setTimeout (() => rejectSafe (TimedOutError()), this.connectOptions.maxIdleTimeMs)
|
this.debounceTimeout = setTimeout (() => rejectSafe (TimedOutError()), this.connectOptions.maxIdleTimeMs)
|
||||||
}
|
}
|
||||||
const debouncedTimeout = () => this.connectOptions.maxIdleTimeMs && this.conn.addEventListener ('message', checkIdleTime)
|
const debouncedTimeout = () => this.connectOptions.maxIdleTimeMs && this.conn.addEventListener ('message', checkIdleTime)
|
||||||
|
|
||||||
// add wait for chats promise if required
|
|
||||||
if (typeof options?.waitForChats === 'undefined' ? true : options?.waitForChats) {
|
|
||||||
const {waitForChats, cancelChats} = this.receiveChatsAndContacts(this.connectOptions.waitOnlyForLastMessage)
|
|
||||||
task = waitForChats
|
|
||||||
cancel = cancelChats
|
|
||||||
}
|
|
||||||
// determine whether reconnect should be used or not
|
// determine whether reconnect should be used or not
|
||||||
const shouldUseReconnect = this.lastDisconnectReason !== DisconnectReason.replaced &&
|
const shouldUseReconnect = this.lastDisconnectReason !== DisconnectReason.replaced &&
|
||||||
this.lastDisconnectReason !== DisconnectReason.unknown &&
|
this.lastDisconnectReason !== DisconnectReason.unknown &&
|
||||||
@@ -93,38 +87,34 @@ export class WAConnection extends Base {
|
|||||||
|
|
||||||
this.conn.on ('open', async () => {
|
this.conn.on ('open', async () => {
|
||||||
this.log(`connected to WhatsApp Web server, authenticating via ${reconnectID ? 'reconnect' : 'takeover'}`, MessageLogLevel.info)
|
this.log(`connected to WhatsApp Web server, authenticating via ${reconnectID ? 'reconnect' : 'takeover'}`, MessageLogLevel.info)
|
||||||
|
let waitForChats: Promise<{[k: string]: Partial<WAChat>}>
|
||||||
|
// add wait for chats promise if required
|
||||||
|
if (typeof options?.waitForChats === 'undefined' ? true : options?.waitForChats) {
|
||||||
|
const recv = this.receiveChatsAndContacts(this.connectOptions.waitOnlyForLastMessage)
|
||||||
|
waitForChats = recv.waitForChats
|
||||||
|
cancel = () => {
|
||||||
|
reject (CancelledError())
|
||||||
|
recv.cancelChats ()
|
||||||
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
task = Promise.all ([
|
await this.authenticate (debouncedTimeout, reconnectID)
|
||||||
task,
|
this.conn
|
||||||
// debounce the timeout once validated
|
.removeAllListeners ('error')
|
||||||
this.authenticate (debouncedTimeout, reconnectID)
|
.removeAllListeners ('close')
|
||||||
.then (
|
const result = waitForChats && (await waitForChats)
|
||||||
() => {
|
|
||||||
this.conn
|
|
||||||
.removeAllListeners ('error')
|
|
||||||
.removeAllListeners ('close')
|
|
||||||
}
|
|
||||||
)
|
|
||||||
])
|
|
||||||
const [result] = await task
|
|
||||||
|
|
||||||
this.conn.removeEventListener ('message', checkIdleTime)
|
this.conn.removeEventListener ('message', checkIdleTime)
|
||||||
|
|
||||||
resolve (result)
|
resolve (result)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
reject (error)
|
reject (error)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const rejectSafe = error => {
|
const rejectSafe = error => reject (error)
|
||||||
task = task.catch (() => {})
|
|
||||||
reject (error)
|
|
||||||
}
|
|
||||||
this.conn.on('error', rejectSafe)
|
this.conn.on('error', rejectSafe)
|
||||||
this.conn.on('close', () => rejectSafe(new Error('close')))
|
this.conn.on('close', () => rejectSafe(new Error('close')))
|
||||||
}) as Promise<void | { [k: string]: Partial<WAChat> }>
|
}) as Promise<void | { [k: string]: Partial<WAChat> }>
|
||||||
|
|
||||||
return { promise: task, cancel }
|
return { promise: task, cancel: cancel }
|
||||||
}
|
}
|
||||||
|
|
||||||
let promise = Promise.resolve ()
|
let promise = Promise.resolve ()
|
||||||
|
|||||||
@@ -321,6 +321,8 @@ export class WAConnection extends Base {
|
|||||||
on (event: 'connecting', listener: () => void): this
|
on (event: 'connecting', listener: () => void): this
|
||||||
/** when the connection has closed */
|
/** when the connection has closed */
|
||||||
on (event: 'close', listener: (err: {reason?: DisconnectReason | string, isReconnecting: boolean}) => void): this
|
on (event: 'close', listener: (err: {reason?: DisconnectReason | string, isReconnecting: boolean}) => void): this
|
||||||
|
/** when the connection has closed */
|
||||||
|
on (event: 'intermediate-close', listener: (err: {reason?: DisconnectReason | string}) => void): this
|
||||||
/** when a new QR is generated, ready for scanning */
|
/** when a new QR is generated, ready for scanning */
|
||||||
on (event: 'qr', listener: (qr: string) => void): this
|
on (event: 'qr', listener: (qr: string) => void): this
|
||||||
/** when the connection to the phone changes */
|
/** when the connection to the phone changes */
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
WALocationMessage,
|
WALocationMessage,
|
||||||
WAContactMessage,
|
WAContactMessage,
|
||||||
WATextMessage,
|
WATextMessage,
|
||||||
WAMessageContent, WAMetric, WAFlag, WAMessage, BaileysError, MessageLogLevel, WA_MESSAGE_STATUS_TYPE, WAMessageProto, MediaConnInfo, MessageTypeProto
|
WAMessageContent, WAMetric, WAFlag, WAMessage, BaileysError, MessageLogLevel, WA_MESSAGE_STATUS_TYPE, WAMessageProto, MediaConnInfo, MessageTypeProto, URL_REGEX, WAUrlInfo
|
||||||
} from './Constants'
|
} from './Constants'
|
||||||
import { generateMessageID, sha256, hmacSign, aesEncrypWithIV, randomBytes, generateThumbnail, getMediaKeys, decodeMediaMessageBuffer, extensionForMediaMessage, whatsappID, unixTimestampSeconds } from './Utils'
|
import { generateMessageID, sha256, hmacSign, aesEncrypWithIV, randomBytes, generateThumbnail, getMediaKeys, decodeMediaMessageBuffer, extensionForMediaMessage, whatsappID, unixTimestampSeconds } from './Utils'
|
||||||
import { Mutex } from './Mutex'
|
import { Mutex } from './Mutex'
|
||||||
@@ -53,9 +53,14 @@ export class WAConnection extends Base {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case MessageType.text:
|
case MessageType.text:
|
||||||
case MessageType.extendedText:
|
case MessageType.extendedText:
|
||||||
if (typeof message === 'string') {
|
if (typeof message === 'string') message = {text: message} as WATextMessage
|
||||||
m.extendedTextMessage = WAMessageProto.ExtendedTextMessage.create({text: message} as any)
|
|
||||||
} else if ('text' in message) {
|
if ('text' in message) {
|
||||||
|
if (options.detectLinks !== false && message.text.match(URL_REGEX)) {
|
||||||
|
try {
|
||||||
|
message = await this.generateLinkPreview (message.text)
|
||||||
|
} catch { } // ignore if fails
|
||||||
|
}
|
||||||
m.extendedTextMessage = WAMessageProto.ExtendedTextMessage.create(message as any)
|
m.extendedTextMessage = WAMessageProto.ExtendedTextMessage.create(message as any)
|
||||||
} else {
|
} else {
|
||||||
throw new BaileysError ('message needs to be a string or object with property \'text\'', message)
|
throw new BaileysError ('message needs to be a string or object with property \'text\'', message)
|
||||||
@@ -98,7 +103,8 @@ export class WAConnection extends Base {
|
|||||||
const body = Buffer.concat([enc, mac]) // body is enc + mac
|
const body = Buffer.concat([enc, mac]) // body is enc + mac
|
||||||
const fileSha256 = sha256(buffer)
|
const fileSha256 = sha256(buffer)
|
||||||
// url safe Base64 encode the SHA256 hash of the body
|
// url safe Base64 encode the SHA256 hash of the body
|
||||||
const fileEncSha256B64 = sha256(body)
|
const fileEncSha256 = sha256(body)
|
||||||
|
const fileEncSha256B64 = fileEncSha256
|
||||||
.toString('base64')
|
.toString('base64')
|
||||||
.replace(/\+/g, '-')
|
.replace(/\+/g, '-')
|
||||||
.replace(/\//g, '_')
|
.replace(/\//g, '_')
|
||||||
@@ -114,11 +120,14 @@ export class WAConnection extends Base {
|
|||||||
for (let host of json.hosts) {
|
for (let host of json.hosts) {
|
||||||
const hostname = `https://${host.hostname}${MediaPathMap[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`
|
const hostname = `https://${host.hostname}${MediaPathMap[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`
|
||||||
try {
|
try {
|
||||||
const urlFetch = await this.fetchRequest(hostname, 'POST', body)
|
const urlFetch = await this.fetchRequest(hostname, 'POST', body, options.uploadAgent)
|
||||||
mediaUrl = (await urlFetch.json())?.url
|
mediaUrl = (await urlFetch.json())?.url
|
||||||
|
|
||||||
if (mediaUrl) break
|
if (mediaUrl) break
|
||||||
else throw new Error (`upload failed`)
|
else {
|
||||||
|
await this.refreshMediaConn (true)
|
||||||
|
throw new Error (`upload failed`)
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const isLast = host.hostname === json.hosts[json.hosts.length-1].hostname
|
const isLast = host.hostname === json.hosts[json.hosts.length-1].hostname
|
||||||
this.log (`Error in uploading to ${host.hostname}${isLast ? '' : ', retrying...'}`, MessageLogLevel.info)
|
this.log (`Error in uploading to ${host.hostname}${isLast ? '' : ', retrying...'}`, MessageLogLevel.info)
|
||||||
@@ -132,12 +141,13 @@ export class WAConnection extends Base {
|
|||||||
url: mediaUrl,
|
url: mediaUrl,
|
||||||
mediaKey: mediaKey,
|
mediaKey: mediaKey,
|
||||||
mimetype: options.mimetype,
|
mimetype: options.mimetype,
|
||||||
fileEncSha256: sha256(body),//fileEncSha256B64,
|
fileEncSha256: fileEncSha256,
|
||||||
fileSha256: fileSha256,
|
fileSha256: fileSha256,
|
||||||
fileLength: buffer.length,
|
fileLength: buffer.length,
|
||||||
fileName: options.filename || 'file',
|
fileName: options.filename || 'file',
|
||||||
gifPlayback: isGIF || null,
|
gifPlayback: isGIF || undefined,
|
||||||
caption: options.caption,
|
caption: options.caption,
|
||||||
|
ptt: options.ptt
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -244,9 +254,26 @@ export class WAConnection extends Base {
|
|||||||
await fs.writeFile (trueFileName, buffer)
|
await fs.writeFile (trueFileName, buffer)
|
||||||
return trueFileName
|
return trueFileName
|
||||||
}
|
}
|
||||||
|
/** Query a string to check if it has a url, if it does, return required extended text message */
|
||||||
|
async generateLinkPreview (text: string) {
|
||||||
|
const query = ['query', {type: 'url', url: text, epoch: this.msgCount.toString()}, null]
|
||||||
|
const response = await this.query ({json: query, binaryTags: [26, WAFlag.ignore], expect200: true})
|
||||||
|
|
||||||
protected async refreshMediaConn () {
|
if (response[1]) response[1].jpegThumbnail = response[2]
|
||||||
if (!this.mediaConn || (new Date().getTime()-this.mediaConn.fetchDate.getTime()) > this.mediaConn.ttl*1000) {
|
const data = response[1] as WAUrlInfo
|
||||||
|
|
||||||
|
const content = {text} as WATextMessage
|
||||||
|
content.canonicalUrl = data['canonical-url']
|
||||||
|
content.matchedText = data['matched-text']
|
||||||
|
content.jpegThumbnail = data.jpegThumbnail
|
||||||
|
content.description = data.description
|
||||||
|
content.title = data.title
|
||||||
|
content.previewType = 0
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async refreshMediaConn (forceGet = false) {
|
||||||
|
if (!this.mediaConn || (new Date().getTime()-this.mediaConn.fetchDate.getTime()) > this.mediaConn.ttl*1000 || forceGet) {
|
||||||
const result = await this.query({json: ['query', 'mediaConn']})
|
const result = await this.query({json: ['query', 'mediaConn']})
|
||||||
this.mediaConn = result.media_conn
|
this.mediaConn = result.media_conn
|
||||||
this.mediaConn.fetchDate = new Date()
|
this.mediaConn.fetchDate = new Date()
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
import {WAConnection as Base} from './6.MessagesSend'
|
import {WAConnection as Base} from './6.MessagesSend'
|
||||||
import {
|
import { MessageType, WAMessageKey, MessageInfo, WAMessageContent, WAMetric, WAFlag, WANode, WAMessage, WAMessageProto } from './Constants'
|
||||||
MessageType,
|
|
||||||
WAMessageKey,
|
|
||||||
MessageInfo,
|
|
||||||
WATextMessage,
|
|
||||||
WAUrlInfo,
|
|
||||||
WAMessageContent, WAMetric, WAFlag, WANode, WAMessage, WAMessageProto, BaileysError, MessageLogLevel, WA_MESSAGE_STATUS_TYPE
|
|
||||||
} from './Constants'
|
|
||||||
import { whatsappID, delay, toNumber, unixTimestampSeconds } from './Utils'
|
import { whatsappID, delay, toNumber, unixTimestampSeconds } from './Utils'
|
||||||
import { Mutex } from './Mutex'
|
import { Mutex } from './Mutex'
|
||||||
|
|
||||||
@@ -211,23 +204,6 @@ export class WAConnection extends Base {
|
|||||||
const actual = await this.loadMessages (jid, 1, messages[0] && messages[0].key, false)
|
const actual = await this.loadMessages (jid, 1, messages[0] && messages[0].key, false)
|
||||||
return actual.messages[0]
|
return actual.messages[0]
|
||||||
}
|
}
|
||||||
/** Query a string to check if it has a url, if it does, return required extended text message */
|
|
||||||
async generateLinkPreview (text: string) {
|
|
||||||
const query = ['query', {type: 'url', url: text, epoch: this.msgCount.toString()}, null]
|
|
||||||
const response = await this.query ({json: query, binaryTags: [26, WAFlag.ignore], expect200: true})
|
|
||||||
|
|
||||||
if (response[1]) response[1].jpegThumbnail = response[2]
|
|
||||||
const data = response[1] as WAUrlInfo
|
|
||||||
|
|
||||||
const content = {text} as WATextMessage
|
|
||||||
content.canonicalUrl = data['canonical-url']
|
|
||||||
content.matchedText = data['matched-text']
|
|
||||||
content.jpegThumbnail = data.jpegThumbnail
|
|
||||||
content.description = data.description
|
|
||||||
content.title = data.title
|
|
||||||
content.previewType = 0
|
|
||||||
return content
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Search WhatsApp messages with a given text string
|
* Search WhatsApp messages with a given text string
|
||||||
* @param txt the search string
|
* @param txt the search string
|
||||||
|
|||||||
@@ -82,6 +82,8 @@ export type WAConnectOptions = {
|
|||||||
/** agent which can be used for proxying connections */
|
/** agent which can be used for proxying connections */
|
||||||
agent?: Agent
|
agent?: Agent
|
||||||
}
|
}
|
||||||
|
/** from: https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url */
|
||||||
|
export const URL_REGEX = /[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)?/gi
|
||||||
|
|
||||||
export type WAConnectionState = 'open' | 'connecting' | 'close'
|
export type WAConnectionState = 'open' | 'connecting' | 'close'
|
||||||
|
|
||||||
@@ -166,6 +168,7 @@ export interface WAGroupModification {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface WAContact {
|
export interface WAContact {
|
||||||
|
verify?: string
|
||||||
/** name of the contact, the contact has set on their own on WA */
|
/** name of the contact, the contact has set on their own on WA */
|
||||||
notify?: string
|
notify?: string
|
||||||
jid: string
|
jid: string
|
||||||
@@ -302,13 +305,30 @@ export enum Mimetype {
|
|||||||
webp = 'image/webp',
|
webp = 'image/webp',
|
||||||
}
|
}
|
||||||
export interface MessageOptions {
|
export interface MessageOptions {
|
||||||
|
/** the message you want to quote */
|
||||||
quoted?: WAMessage
|
quoted?: WAMessage
|
||||||
|
/** some random context info (can show a forwarded message with this too) */
|
||||||
contextInfo?: WAContextInfo
|
contextInfo?: WAContextInfo
|
||||||
|
/** optional, if you want to manually set the timestamp of the message */
|
||||||
timestamp?: Date
|
timestamp?: Date
|
||||||
|
/** (for media messages) the caption to send with the media (cannot be sent with stickers though) */
|
||||||
caption?: string
|
caption?: string
|
||||||
|
/**
|
||||||
|
* For location & media messages -- has to be a base 64 encoded JPEG if you want to send a custom thumb,
|
||||||
|
* or set to null if you don't want to send a thumbnail.
|
||||||
|
* Do not enter this field if you want to automatically generate a thumb
|
||||||
|
* */
|
||||||
thumbnail?: string
|
thumbnail?: string
|
||||||
|
/** (for media messages) specify the type of media (optional for all media types except documents) */
|
||||||
mimetype?: Mimetype | string
|
mimetype?: Mimetype | string
|
||||||
|
/** (for media messages) file name for the media */
|
||||||
filename?: string
|
filename?: string
|
||||||
|
/** For audio messages, if set to true, will send as a `voice note` */
|
||||||
|
ptt?: boolean
|
||||||
|
/** Optional agent for media uploads */
|
||||||
|
uploadAgent?: Agent
|
||||||
|
/** If set to true (default), automatically detects if you're sending a link & attaches the preview*/
|
||||||
|
detectLinks?: boolean
|
||||||
}
|
}
|
||||||
export interface WABroadcastListInfo {
|
export interface WABroadcastListInfo {
|
||||||
status: number
|
status: number
|
||||||
@@ -388,6 +408,7 @@ export type BaileysEvent =
|
|||||||
'open' |
|
'open' |
|
||||||
'connecting' |
|
'connecting' |
|
||||||
'close' |
|
'close' |
|
||||||
|
'intermediate-close' |
|
||||||
'qr' |
|
'qr' |
|
||||||
'connection-phone-change' |
|
'connection-phone-change' |
|
||||||
'user-presence-update' |
|
'user-presence-update' |
|
||||||
|
|||||||
Reference in New Issue
Block a user