mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
Presence fixes
This commit is contained in:
@@ -11,6 +11,17 @@ WAConnectionTest('Messages', conn => {
|
||||
const message = await sendAndRetreiveMessage(conn, 'hello fren', MessageType.text)
|
||||
assert.strictEqual(message.message.conversation || message.message.extendedTextMessage?.text, 'hello fren')
|
||||
})
|
||||
it('should send a pending message', async () => {
|
||||
const message = await sendAndRetreiveMessage(conn, 'hello fren', MessageType.text, { waitForAck: false })
|
||||
|
||||
await new Promise(resolve => conn.once('message-status-update', update => {
|
||||
if (update.ids.includes(message.key.id)) {
|
||||
assert.strictEqual(update.type, WA_MESSAGE_STATUS_TYPE.SERVER_ACK)
|
||||
resolve()
|
||||
}
|
||||
}))
|
||||
|
||||
})
|
||||
it('should forward a message', async () => {
|
||||
let {messages} = await conn.loadMessages (testJid, 1)
|
||||
await conn.forwardMessage (testJid, messages[0], true)
|
||||
|
||||
@@ -136,14 +136,17 @@ WAConnectionTest('Misc', (conn) => {
|
||||
await delay (500)
|
||||
}
|
||||
})
|
||||
// open the other phone and look at the updates to really verify stuff
|
||||
it('should send presence updates', async () => {
|
||||
conn.shouldLogMessages = true
|
||||
conn.requestPresenceUpdate(testJid)
|
||||
|
||||
it('should update presence', async () => {
|
||||
const presences = Object.values(Presence)
|
||||
for (const i in presences) {
|
||||
const response = await conn.updatePresence(testJid, presences[i])
|
||||
assert.strictEqual(response.status, 200)
|
||||
|
||||
await delay(1500)
|
||||
const sequence = [ Presence.available, Presence.composing, Presence.paused, Presence.recording, Presence.paused, Presence.unavailable ]
|
||||
for (const presence of sequence) {
|
||||
await delay(5000)
|
||||
await conn.updatePresence(presence !== Presence.unavailable ? testJid : null, presence)
|
||||
//console.log(conn.messageLog.slice(-1))
|
||||
console.log('sent update ', presence)
|
||||
}
|
||||
})
|
||||
it('should generate link previews correctly', async () => {
|
||||
|
||||
@@ -210,7 +210,7 @@ export class WAConnection extends EventEmitter {
|
||||
* @param timeoutMs timeout after which the query will be failed (set to null to disable a timeout)
|
||||
* @param tag the tag to attach to the message
|
||||
*/
|
||||
async query(q: WAQuery) {
|
||||
async query(q: WAQuery): Promise<any> {
|
||||
let {json, binaryTags, tag, timeoutMs, expect200, waitForOpen, longTag, requiresPhoneConnection, startDebouncedTimeout} = q
|
||||
requiresPhoneConnection = requiresPhoneConnection !== false
|
||||
waitForOpen = waitForOpen !== false
|
||||
|
||||
@@ -51,18 +51,15 @@ export class WAConnection extends Base {
|
||||
* @param jid the ID of the person/group who you are updating
|
||||
* @param type your presence
|
||||
*/
|
||||
updatePresence = (jid: string | null, type: Presence) =>
|
||||
this.query(
|
||||
{
|
||||
json: [
|
||||
'action',
|
||||
{ epoch: this.msgCount.toString(), type: 'set' },
|
||||
[['presence', { type: type, to: jid }, null]],
|
||||
],
|
||||
binaryTags: [WAMetric.group, WAFlag.acknowledge],
|
||||
expect200: true
|
||||
}
|
||||
) as Promise<{status: number}>
|
||||
updatePresence = (jid: string | null, type: Presence) => this.sendBinary(
|
||||
[ 'action',
|
||||
{epoch: this.msgCount.toString(), type: 'set'},
|
||||
[ ['presence', { type: type, to: jid }, null] ]
|
||||
],
|
||||
[WAMetric.presence, WAFlag[type] ], // weird stuff WA does
|
||||
undefined,
|
||||
true
|
||||
)
|
||||
/** Request an update on the presence of a user */
|
||||
requestPresenceUpdate = async (jid: string) => this.query({ json: ['action', 'presence', 'subscribe', jid] })
|
||||
/** Query the status of the person (see groupMetadata() for groups) */
|
||||
|
||||
@@ -29,7 +29,7 @@ export class WAConnection extends Base {
|
||||
options: MessageOptions = {},
|
||||
) {
|
||||
const waMessage = await this.prepareMessage (id, message, type, options)
|
||||
await this.relayWAMessage (waMessage)
|
||||
await this.relayWAMessage (waMessage, { waitForAck: options.waitForAck !== false })
|
||||
return waMessage
|
||||
}
|
||||
/** Prepares a message for sending via sendWAMessage () */
|
||||
@@ -217,12 +217,26 @@ export class WAConnection extends Base {
|
||||
return WAMessageProto.WebMessageInfo.create (messageJSON)
|
||||
}
|
||||
/** Relay (send) a WAMessage; more advanced functionality to send a built WA Message, you may want to stick with sendMessage() */
|
||||
async relayWAMessage(message: WAMessage) {
|
||||
async relayWAMessage(message: WAMessage, { waitForAck } = { waitForAck: true }) {
|
||||
const json = ['action', {epoch: this.msgCount.toString(), type: 'relay'}, [['message', null, message]]]
|
||||
const flag = message.key.remoteJid === this.user?.jid ? WAFlag.acknowledge : WAFlag.ignore // acknowledge when sending message to oneself
|
||||
await this.query({json, binaryTags: [WAMetric.message, flag], tag: message.key.id, expect200: true})
|
||||
|
||||
message.status = WA_MESSAGE_STATUS_TYPE.SERVER_ACK
|
||||
const mID = message.key.id
|
||||
message.status = WA_MESSAGE_STATUS_TYPE.PENDING
|
||||
const promise = this.query({
|
||||
json,
|
||||
binaryTags: [WAMetric.message, flag],
|
||||
tag: mID,
|
||||
expect200: true
|
||||
})
|
||||
.then(() => message.status = WA_MESSAGE_STATUS_TYPE.SERVER_ACK)
|
||||
|
||||
if (waitForAck) {
|
||||
await promise
|
||||
} else {
|
||||
promise
|
||||
.then(() => this.emit('message-status-update', { ids: [ mID ], to: message.key.remoteJid, type: WA_MESSAGE_STATUS_TYPE.SERVER_ACK }))
|
||||
.catch(() => this.emit('message-status-update', { ids: [ mID ], to: message.key.remoteJid, type: WA_MESSAGE_STATUS_TYPE.ERROR }))
|
||||
}
|
||||
await this.chatAddMessageAppropriate (message)
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -299,14 +299,14 @@ export class WAConnection extends Base {
|
||||
return waMessage
|
||||
}
|
||||
/**
|
||||
* Forward a message like WA does
|
||||
* @param id the id to forward the message to
|
||||
* Generate forwarded message content like WA does
|
||||
* @param message the message to forward
|
||||
* @param forceForward will show the message as forwarded even if it is from you
|
||||
*/
|
||||
async forwardMessage(id: string, message: WAMessage, forceForward: boolean=false) {
|
||||
const content = message.message
|
||||
if (!content) throw new Error ('no content in message')
|
||||
generateForwardMessageContent (message: WAMessage, forceForward: boolean=false) {
|
||||
let content = message.message
|
||||
if (!content) throw new BaileysError ('no content in message', { status: 400 })
|
||||
content = JSON.parse(JSON.stringify(content)) // hacky copy
|
||||
|
||||
let key = Object.keys(content)[0]
|
||||
|
||||
@@ -320,13 +320,20 @@ export class WAConnection extends Base {
|
||||
}
|
||||
if (score > 0) content[key].contextInfo = { forwardingScore: score, isForwarded: true }
|
||||
else content[key].contextInfo = {}
|
||||
|
||||
const waMessage = this.prepareMessageFromContent (id, content, {})
|
||||
return content
|
||||
}
|
||||
/**
|
||||
* Forward a message like WA
|
||||
* @param jid the chat ID to forward to
|
||||
* @param message the message to forward
|
||||
* @param forceForward will show the message as forwarded even if it is from you
|
||||
*/
|
||||
async forwardMessage(jid: string, message: WAMessage, forceForward: boolean=false) {
|
||||
const content = this.generateForwardMessageContent(message, forceForward)
|
||||
const waMessage = this.prepareMessageFromContent (jid, content, {})
|
||||
await this.relayWAMessage (waMessage)
|
||||
return waMessage
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Modify a given chat (archive, pin etc.)
|
||||
* @param jid the ID of the person/group you are modifiying
|
||||
|
||||
@@ -253,22 +253,24 @@ export enum WAMetric {
|
||||
export const STORIES_JID = 'status@broadcast'
|
||||
|
||||
export enum WAFlag {
|
||||
available = 160,
|
||||
ignore = 1 << 7,
|
||||
acknowledge = 1 << 6,
|
||||
available = 1 << 5,
|
||||
unavailable = 1 << 4,
|
||||
expires = 1 << 3,
|
||||
skipOffline = 1 << 2,
|
||||
composing = 1 << 2,
|
||||
recording = 1 << 2,
|
||||
paused = 1 << 2
|
||||
}
|
||||
/** Tag used with binary queries */
|
||||
export type WATag = [WAMetric, WAFlag]
|
||||
/** set of statuses visible to other people; see updatePresence() in WhatsAppWeb.Send */
|
||||
export enum Presence {
|
||||
available = 'available', // "online"
|
||||
unavailable = 'unavailable', // "offline"
|
||||
available = 'available', // "online"
|
||||
composing = 'composing', // "typing..."
|
||||
recording = 'recording', // "recording..."
|
||||
paused = 'paused', // I have no clue
|
||||
paused = 'paused', // stop typing
|
||||
}
|
||||
/** Set of message types that are supported by the library */
|
||||
export enum MessageType {
|
||||
@@ -348,6 +350,8 @@ export interface MessageOptions {
|
||||
duration?: number
|
||||
/** Fetches new media options for every media file */
|
||||
forceNewMediaOptions?: boolean
|
||||
/** Wait for the message to be sent to the server (default true) */
|
||||
waitForAck?: boolean
|
||||
}
|
||||
export interface WABroadcastListInfo {
|
||||
status: number
|
||||
|
||||
Reference in New Issue
Block a user