mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
Product Message + Message Info
This commit is contained in:
@@ -33,6 +33,7 @@ export enum MessageType {
|
|||||||
sticker = 'stickerMessage',
|
sticker = 'stickerMessage',
|
||||||
document = 'documentMessage',
|
document = 'documentMessage',
|
||||||
audio = 'audioMessage',
|
audio = 'audioMessage',
|
||||||
|
product = 'productMessage'
|
||||||
}
|
}
|
||||||
export enum ChatModification {
|
export enum ChatModification {
|
||||||
archive='archive',
|
archive='archive',
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ import { validateJIDForSending, generateThumbnail, getMediaKeys } from './Utils'
|
|||||||
import { proto } from '../../WAMessage/WAMessage'
|
import { proto } from '../../WAMessage/WAMessage'
|
||||||
|
|
||||||
export default class WhatsAppWebMessages extends WhatsAppWebBase {
|
export default class WhatsAppWebMessages extends WhatsAppWebBase {
|
||||||
|
/** Get the message info, who has read it, who its been delivered to */
|
||||||
|
async messageInfo (jid: string, messageID: string) {
|
||||||
|
const query = ['query', {type: 'message_info', index: messageID, jid: jid, epoch: this.msgCount.toString()}, null]
|
||||||
|
return this.queryExpecting200 (query, [22, WAFlag.ignore])
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Send a read receipt to the given ID for a certain message
|
* Send a read receipt to the given ID for a certain message
|
||||||
* @param jid the ID of the person/group whose message you want to mark read
|
* @param jid the ID of the person/group whose message you want to mark read
|
||||||
@@ -67,6 +72,15 @@ export default class WhatsAppWebMessages extends WhatsAppWebBase {
|
|||||||
response.stamp = strStamp
|
response.stamp = strStamp
|
||||||
return response as {status: number, stamp: string}
|
return response as {status: number, stamp: string}
|
||||||
}
|
}
|
||||||
|
async loadMessage (jid: string, messageID: string) {
|
||||||
|
const messages = await this.loadConversation (jid, 1, {id: messageID, fromMe: false}, false)
|
||||||
|
var index = null
|
||||||
|
if (messages.length > 0) {
|
||||||
|
index = {id: messages[0].key.id, fromMe: false}
|
||||||
|
}
|
||||||
|
const actual = await this.loadConversation (jid, 1, index)
|
||||||
|
return actual[0]
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
|
|||||||
@@ -171,8 +171,8 @@ WAClientTest('Groups', (client) => {
|
|||||||
await client.groupRemove(gid, [testJid])
|
await client.groupRemove(gid, [testJid])
|
||||||
})
|
})
|
||||||
it('should leave the group', async () => {
|
it('should leave the group', async () => {
|
||||||
// await client.groupLeave(gid)
|
await client.groupLeave(gid)
|
||||||
await client.groupCreatorAndParticipants ('919324993767-1593506879@g.us')
|
await client.groupCreatorAndParticipants (gid)
|
||||||
})
|
})
|
||||||
it('should archive the group', async () => {
|
it('should archive the group', async () => {
|
||||||
await client.archiveChat(gid)
|
await client.archiveChat(gid)
|
||||||
|
|||||||
@@ -87,13 +87,10 @@ export async function generateThumbnail(buffer: Buffer, mediaType: MessageType,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Decode a media message (video, image, document, audio) & save it to the given file
|
* Decode a media message (video, image, document, audio) & return decrypted buffer
|
||||||
* @param message the media message you want to decode
|
* @param message the media message you want to decode
|
||||||
* @param filename the name of the file where the media will be saved
|
|
||||||
* @param attachExtension should the correct extension be applied automatically to the file
|
|
||||||
*/
|
*/
|
||||||
export async function decodeMediaMessage(message: WAMessageContent, filename: string, attachExtension: boolean=true) {
|
export async function decodeMediaMessageBuffer(message: WAMessageContent) {
|
||||||
const getExtension = (mimetype) => mimetype.split(';')[0].split('/')[1]
|
|
||||||
/*
|
/*
|
||||||
One can infer media type from the key in the message
|
One can infer media type from the key in the message
|
||||||
it is usually written as [mediaType]Message. Eg. imageMessage, audioMessage etc.
|
it is usually written as [mediaType]Message. Eg. imageMessage, audioMessage etc.
|
||||||
@@ -106,15 +103,17 @@ export async function decodeMediaMessage(message: WAMessageContent, filename: st
|
|||||||
throw new Error('cannot decode text message')
|
throw new Error('cannot decode text message')
|
||||||
}
|
}
|
||||||
if (type === MessageType.location || type === MessageType.liveLocation) {
|
if (type === MessageType.location || type === MessageType.liveLocation) {
|
||||||
fs.writeFileSync(filename + '.jpeg', message[type].jpegThumbnail)
|
return new Buffer(message[type].jpegThumbnail)
|
||||||
return { filename: filename + '.jpeg' }
|
|
||||||
}
|
}
|
||||||
const messageContent = message[type] as
|
let messageContent: proto.IVideoMessage | proto.IImageMessage | proto.IAudioMessage | proto.IDocumentMessage
|
||||||
| proto.VideoMessage
|
if (message.productMessage) {
|
||||||
| proto.ImageMessage
|
const product = message.productMessage.product?.productImage
|
||||||
| proto.AudioMessage
|
if (!product) throw new Error ('product has no image')
|
||||||
| proto.DocumentMessage
|
messageContent = product
|
||||||
|
} else {
|
||||||
|
messageContent = message[type]
|
||||||
|
}
|
||||||
|
|
||||||
// download the message
|
// download the message
|
||||||
const fetched = await fetch(messageContent.url, { headers: { Origin: 'https://web.whatsapp.com' } })
|
const fetched = await fetch(messageContent.url, { headers: { Origin: 'https://web.whatsapp.com' } })
|
||||||
const buffer = await fetched.buffer()
|
const buffer = await fetched.buffer()
|
||||||
@@ -146,13 +145,38 @@ export async function decodeMediaMessage(message: WAMessageContent, filename: st
|
|||||||
const decrypted = decryptedMedia (allTypes[i] as MessageType)
|
const decrypted = decryptedMedia (allTypes[i] as MessageType)
|
||||||
|
|
||||||
if (i > 0) { console.log (`decryption of ${type} media with HKDF key of ${allTypes[i]}`) }
|
if (i > 0) { console.log (`decryption of ${type} media with HKDF key of ${allTypes[i]}`) }
|
||||||
|
return decrypted
|
||||||
const trueFileName = attachExtension ? (filename + '.' + getExtension(messageContent.mimetype)) : filename
|
|
||||||
fs.writeFileSync(trueFileName, decrypted)
|
|
||||||
return trueFileName
|
|
||||||
} catch {
|
} catch {
|
||||||
if (i === 0) { console.log (`decryption of ${type} media with original HKDF key failed`) }
|
if (i === 0) { console.log (`decryption of ${type} media with original HKDF key failed`) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new Error('HMAC sign does not match for ' + buffer.length)
|
throw new Error('HMAC sign does not match for ' + buffer.length)
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Decode a media message (video, image, document, audio) & save it to the given file
|
||||||
|
* @param message the media message you want to decode
|
||||||
|
* @param filename the name of the file where the media will be saved
|
||||||
|
* @param attachExtension should the correct extension be applied automatically to the file
|
||||||
|
*/
|
||||||
|
export async function decodeMediaMessage(message: WAMessageContent, filename: string, attachExtension: boolean=true) {
|
||||||
|
const getExtension = (mimetype) => mimetype.split(';')[0].split('/')[1]
|
||||||
|
|
||||||
|
const buffer = await decodeMediaMessageBuffer (message)
|
||||||
|
const type = Object.keys(message)[0] as MessageType
|
||||||
|
let extension
|
||||||
|
if (type === MessageType.location || type === MessageType.liveLocation) {
|
||||||
|
extension = '.jpeg'
|
||||||
|
} else {
|
||||||
|
const messageContent = message[type] as
|
||||||
|
| proto.VideoMessage
|
||||||
|
| proto.ImageMessage
|
||||||
|
| proto.AudioMessage
|
||||||
|
| proto.DocumentMessage
|
||||||
|
extension = getExtension (messageContent.mimetype)
|
||||||
|
}
|
||||||
|
|
||||||
|
const trueFileName = attachExtension ? (filename + '.' + extension) : filename
|
||||||
|
fs.writeFileSync(trueFileName, buffer)
|
||||||
|
return trueFileName
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,8 +40,14 @@ const list = wsMessages.map ((item, i) => {
|
|||||||
const [tag, json, binaryTags] = decrypt (buffer)
|
const [tag, json, binaryTags] = decrypt (buffer)
|
||||||
return {tag, json: JSON.stringify(json), binaryTags}
|
return {tag, json: JSON.stringify(json), binaryTags}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error (`received error in decoding ${i}: ${error}`)
|
try {
|
||||||
return null
|
const [tag, json, binaryTags] = decrypt (item.data)
|
||||||
|
return {tag, json: JSON.stringify(json), binaryTags}
|
||||||
|
} catch (error) {
|
||||||
|
console.log ('error in decoding: ' + error)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const str = JSON.stringify (list, null, '\t')
|
const str = JSON.stringify (list, null, '\t')
|
||||||
|
|||||||
Reference in New Issue
Block a user