mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
Merge branch 'master' into call
This commit is contained in:
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
github: [purpshell, auties00, edgardmessias]
|
||||||
101
README.md
101
README.md
@@ -376,65 +376,6 @@ const sentMsg = await sock.sendMessage(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// send a buttons message!
|
|
||||||
const buttons = [
|
|
||||||
{buttonId: 'id1', buttonText: {displayText: 'Button 1'}, type: 1},
|
|
||||||
{buttonId: 'id2', buttonText: {displayText: 'Button 2'}, type: 1},
|
|
||||||
{buttonId: 'id3', buttonText: {displayText: 'Button 3'}, type: 1}
|
|
||||||
]
|
|
||||||
|
|
||||||
const buttonMessage = {
|
|
||||||
text: "Hi it's button message",
|
|
||||||
footer: 'Hello World',
|
|
||||||
buttons: buttons,
|
|
||||||
headerType: 1
|
|
||||||
}
|
|
||||||
|
|
||||||
const sendMsg = await sock.sendMessage(id, buttonMessage)
|
|
||||||
|
|
||||||
//send a template message!
|
|
||||||
const templateButtons = [
|
|
||||||
{index: 1, urlButton: {displayText: '⭐ Star Baileys on GitHub!', url: 'https://github.com/adiwajshing/Baileys'}},
|
|
||||||
{index: 2, callButton: {displayText: 'Call me!', phoneNumber: '+1 (234) 5678-901'}},
|
|
||||||
{index: 3, quickReplyButton: {displayText: 'This is a reply, just like normal buttons!', id: 'id-like-buttons-message'}},
|
|
||||||
]
|
|
||||||
|
|
||||||
const templateMessage = {
|
|
||||||
text: "Hi it's a template message",
|
|
||||||
footer: 'Hello World',
|
|
||||||
templateButtons: templateButtons
|
|
||||||
}
|
|
||||||
|
|
||||||
const sendMsg = await sock.sendMessage(id, templateMessage)
|
|
||||||
|
|
||||||
// send a list message!
|
|
||||||
const sections = [
|
|
||||||
{
|
|
||||||
title: "Section 1",
|
|
||||||
rows: [
|
|
||||||
{title: "Option 1", rowId: "option1"},
|
|
||||||
{title: "Option 2", rowId: "option2", description: "This is a description"}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Section 2",
|
|
||||||
rows: [
|
|
||||||
{title: "Option 3", rowId: "option3"},
|
|
||||||
{title: "Option 4", rowId: "option4", description: "This is a description V2"}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
const listMessage = {
|
|
||||||
text: "This is a list",
|
|
||||||
footer: "nice footer, link: https://google.com",
|
|
||||||
title: "Amazing boldfaced list title",
|
|
||||||
buttonText: "Required, text on the button to view the list",
|
|
||||||
sections
|
|
||||||
}
|
|
||||||
|
|
||||||
const sendMsg = await sock.sendMessage(id, listMessage)
|
|
||||||
|
|
||||||
const reactionMessage = {
|
const reactionMessage = {
|
||||||
react: {
|
react: {
|
||||||
text: "💖", // use an empty string to remove the reaction
|
text: "💖", // use an empty string to remove the reaction
|
||||||
@@ -489,39 +430,6 @@ await sock.sendMessage(
|
|||||||
{ audio: { url: "./Media/audio.mp3" }, mimetype: 'audio/mp4' }
|
{ audio: { url: "./Media/audio.mp3" }, mimetype: 'audio/mp4' }
|
||||||
{ url: "Media/audio.mp3" }, // can send mp3, mp4, & ogg
|
{ url: "Media/audio.mp3" }, // can send mp3, mp4, & ogg
|
||||||
)
|
)
|
||||||
|
|
||||||
// send a buttons message with image header!
|
|
||||||
const buttons = [
|
|
||||||
{buttonId: 'id1', buttonText: {displayText: 'Button 1'}, type: 1},
|
|
||||||
{buttonId: 'id2', buttonText: {displayText: 'Button 2'}, type: 1},
|
|
||||||
{buttonId: 'id3', buttonText: {displayText: 'Button 3'}, type: 1}
|
|
||||||
]
|
|
||||||
|
|
||||||
const buttonMessage = {
|
|
||||||
image: {url: 'https://example.com/image.jpeg'},
|
|
||||||
caption: "Hi it's button message",
|
|
||||||
footer: 'Hello World',
|
|
||||||
buttons: buttons,
|
|
||||||
headerType: 4
|
|
||||||
}
|
|
||||||
|
|
||||||
const sendMsg = await sock.sendMessage(id, buttonMessage)
|
|
||||||
|
|
||||||
//send a template message with an image **attached**!
|
|
||||||
const templateButtons = [
|
|
||||||
{index: 1, urlButton: {displayText: '⭐ Star Baileys on GitHub!', url: 'https://github.com/adiwajshing/Baileys'}},
|
|
||||||
{index: 2, callButton: {displayText: 'Call me!', phoneNumber: '+1 (234) 5678-901'}},
|
|
||||||
{index: 3, quickReplyButton: {displayText: 'This is a reply, just like normal buttons!', id: 'id-like-buttons-message'}},
|
|
||||||
]
|
|
||||||
|
|
||||||
const buttonMessage = {
|
|
||||||
text: "Hi it's a template message",
|
|
||||||
footer: 'Hello World',
|
|
||||||
templateButtons: templateButtons,
|
|
||||||
image: {url: 'https://example.com/image.jpeg'}
|
|
||||||
}
|
|
||||||
|
|
||||||
const sendMsg = await sock.sendMessage(id, templateMessage)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Notes
|
### Notes
|
||||||
@@ -698,6 +606,15 @@ WA uses an encrypted form of communication to send chat/app updates. This has be
|
|||||||
},
|
},
|
||||||
'123456@s.whatsapp.net')
|
'123456@s.whatsapp.net')
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- Star/unstar a message
|
||||||
|
``` ts
|
||||||
|
await sock.chatModify({
|
||||||
|
star: {
|
||||||
|
messages: [{ id: 'messageID', fromMe: true // or `false` }],
|
||||||
|
star: true // - true: Star Message; false: Unstar Message
|
||||||
|
}},'123456@s.whatsapp.net');
|
||||||
|
```
|
||||||
|
|
||||||
**Note:** if you mess up one of your updates, WA can log you out of all your devices and you'll have to log in again.
|
**Note:** if you mess up one of your updates, WA can log you out of all your devices and you'll have to log in again.
|
||||||
|
|
||||||
|
|||||||
@@ -777,6 +777,18 @@ export const makeChatsSocket = (config: SocketConfig) => {
|
|||||||
return appPatch(patch)
|
return appPatch(patch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Star or Unstar a message
|
||||||
|
*/
|
||||||
|
const star = (jid: string, messages: { id: string, fromMe?: boolean }[], star: boolean) => {
|
||||||
|
return chatModify({
|
||||||
|
star: {
|
||||||
|
messages,
|
||||||
|
star
|
||||||
|
}
|
||||||
|
}, jid)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds label for the chats
|
* Adds label for the chats
|
||||||
*/
|
*/
|
||||||
@@ -999,6 +1011,7 @@ export const makeChatsSocket = (config: SocketConfig) => {
|
|||||||
addChatLabel,
|
addChatLabel,
|
||||||
removeChatLabel,
|
removeChatLabel,
|
||||||
addMessageLabel,
|
addMessageLabel,
|
||||||
removeMessageLabel
|
removeMessageLabel,
|
||||||
|
star
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -398,7 +398,6 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
for(const { attrs } of blocklists) {
|
for(const { attrs } of blocklists) {
|
||||||
const blocklist = [attrs.jid]
|
const blocklist = [attrs.jid]
|
||||||
const type = (attrs.action === 'block') ? 'add' : 'remove'
|
const type = (attrs.action === 'block') ? 'add' : 'remove'
|
||||||
|
|
||||||
ev.emit('blocklist.update', { blocklist, type })
|
ev.emit('blocklist.update', { blocklist, type })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -541,7 +540,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
|
|
||||||
const handleReceipt = async(node: BinaryNode) => {
|
const handleReceipt = async(node: BinaryNode) => {
|
||||||
const { attrs, content } = node
|
const { attrs, content } = node
|
||||||
const isNodeFromMe = areJidsSameUser(attrs.participant || attrs.from, authState.creds.me?.id)
|
const isLid = attrs.from.includes('lid')
|
||||||
|
const isNodeFromMe = areJidsSameUser(attrs.participant || attrs.from, isLid ? authState.creds.me?.lid : authState.creds.me?.id)
|
||||||
const remoteJid = !isNodeFromMe || isJidGroup(attrs.from) ? attrs.from : attrs.recipient
|
const remoteJid = !isNodeFromMe || isJidGroup(attrs.from) ? attrs.from : attrs.recipient
|
||||||
const fromMe = !attrs.recipient || (attrs.type === 'retry' && isNodeFromMe)
|
const fromMe = !attrs.recipient || (attrs.type === 'retry' && isNodeFromMe)
|
||||||
|
|
||||||
@@ -664,9 +664,17 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
const { fullMessage: msg, category, author, decrypt } = decryptMessageNode(
|
const { fullMessage: msg, category, author, decrypt } = decryptMessageNode(
|
||||||
node,
|
node,
|
||||||
authState.creds.me!.id,
|
authState.creds.me!.id,
|
||||||
|
authState.creds.me!.lid || '',
|
||||||
signalRepository,
|
signalRepository,
|
||||||
logger,
|
logger,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(msg.message?.protocolMessage?.type === proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER) {
|
||||||
|
if(node.attrs.sender_pn) {
|
||||||
|
ev.emit('chats.phoneNumberShare', { lid: node.attrs.from, jid: node.attrs.sender_pn })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(shouldIgnoreJid(msg.key.remoteJid!)) {
|
if(shouldIgnoreJid(msg.key.remoteJid!)) {
|
||||||
logger.debug({ key: msg.key }, 'ignored message')
|
logger.debug({ key: msg.key }, 'ignored message')
|
||||||
await sendMessageAck(node)
|
await sendMessageAck(node)
|
||||||
|
|||||||
@@ -312,12 +312,13 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
|||||||
const statusJid = 'status@broadcast'
|
const statusJid = 'status@broadcast'
|
||||||
const isGroup = server === 'g.us'
|
const isGroup = server === 'g.us'
|
||||||
const isStatus = jid === statusJid
|
const isStatus = jid === statusJid
|
||||||
|
const isLid = server === 'lid'
|
||||||
|
|
||||||
msgId = msgId || generateMessageID()
|
msgId = msgId || generateMessageID()
|
||||||
useUserDevicesCache = useUserDevicesCache !== false
|
useUserDevicesCache = useUserDevicesCache !== false
|
||||||
|
|
||||||
const participants: BinaryNode[] = []
|
const participants: BinaryNode[] = []
|
||||||
const destinationJid = (!isStatus) ? jidEncode(user, isGroup ? 'g.us' : 's.whatsapp.net') : statusJid
|
const destinationJid = (!isStatus) ? jidEncode(user, isLid ? 'lid' : isGroup ? 'g.us' : 's.whatsapp.net') : statusJid
|
||||||
const binaryNodeContent: BinaryNode[] = []
|
const binaryNodeContent: BinaryNode[] = []
|
||||||
const devices: JidWithDevice[] = []
|
const devices: JidWithDevice[] = []
|
||||||
|
|
||||||
@@ -377,7 +378,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
|||||||
devices.push(...additionalDevices)
|
devices.push(...additionalDevices)
|
||||||
}
|
}
|
||||||
|
|
||||||
const patched = await patchMessageBeforeSending(message, devices.map(d => jidEncode(d.user, 's.whatsapp.net', d.device)))
|
const patched = await patchMessageBeforeSending(message, devices.map(d => jidEncode(d.user, isLid ? 'lid' : 's.whatsapp.net', d.device)))
|
||||||
const bytes = encodeWAMessage(patched)
|
const bytes = encodeWAMessage(patched)
|
||||||
|
|
||||||
const { ciphertext, senderKeyDistributionMessage } = await signalRepository.encryptGroupMessage(
|
const { ciphertext, senderKeyDistributionMessage } = await signalRepository.encryptGroupMessage(
|
||||||
@@ -391,7 +392,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
|||||||
const senderKeyJids: string[] = []
|
const senderKeyJids: string[] = []
|
||||||
// ensure a connection is established with every device
|
// ensure a connection is established with every device
|
||||||
for(const { user, device } of devices) {
|
for(const { user, device } of devices) {
|
||||||
const jid = jidEncode(user, 's.whatsapp.net', device)
|
const jid = jidEncode(user, isLid ? 'lid' : 's.whatsapp.net', device)
|
||||||
if(!senderKeyMap[jid] || !!participant) {
|
if(!senderKeyMap[jid] || !!participant) {
|
||||||
senderKeyJids.push(jid)
|
senderKeyJids.push(jid)
|
||||||
// store that this person has had the sender keys sent to them
|
// store that this person has had the sender keys sent to them
|
||||||
@@ -444,8 +445,8 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
|||||||
const meJids: string[] = []
|
const meJids: string[] = []
|
||||||
const otherJids: string[] = []
|
const otherJids: string[] = []
|
||||||
for(const { user, device } of devices) {
|
for(const { user, device } of devices) {
|
||||||
const jid = jidEncode(user, 's.whatsapp.net', device)
|
|
||||||
const isMe = user === meUser
|
const isMe = user === meUser
|
||||||
|
const jid = jidEncode(isMe && isLid ? authState.creds?.me?.lid!.split(':')[0] || user : user, isLid ? 'lid' : 's.whatsapp.net', device)
|
||||||
if(isMe) {
|
if(isMe) {
|
||||||
meJids.push(jid)
|
meJids.push(jid)
|
||||||
} else {
|
} else {
|
||||||
@@ -642,9 +643,10 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
|||||||
relayMessage,
|
relayMessage,
|
||||||
sendReceipt,
|
sendReceipt,
|
||||||
sendReceipts,
|
sendReceipts,
|
||||||
|
getButtonArgs,
|
||||||
readMessages,
|
readMessages,
|
||||||
refreshMediaConn,
|
refreshMediaConn,
|
||||||
waUploadToServer,
|
waUploadToServer,
|
||||||
fetchPrivacySettings,
|
fetchPrivacySettings,
|
||||||
updateMediaMessage: async(message: proto.IWebMessageInfo) => {
|
updateMediaMessage: async(message: proto.IWebMessageInfo) => {
|
||||||
const content = assertMediaContent(message.message)
|
const content = assertMediaContent(message.message)
|
||||||
|
|||||||
@@ -623,13 +623,15 @@ export const makeSocket = (config: SocketConfig) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
// login complete
|
// login complete
|
||||||
ws.on('CB:success', async() => {
|
ws.on('CB:success', async(node: BinaryNode) => {
|
||||||
await uploadPreKeysToServerIfRequired()
|
await uploadPreKeysToServerIfRequired()
|
||||||
await sendPassiveIq('active')
|
await sendPassiveIq('active')
|
||||||
|
|
||||||
logger.info('opened connection to WA')
|
logger.info('opened connection to WA')
|
||||||
clearTimeout(qrTimer) // will never happen in all likelyhood -- but just in case WA sends success on first try
|
clearTimeout(qrTimer) // will never happen in all likelyhood -- but just in case WA sends success on first try
|
||||||
|
|
||||||
|
ev.emit('creds.update', { me: { id: authState.creds.me!.id, lid: node.attrs.lid } })
|
||||||
|
|
||||||
ev.emit('connection.update', { connection: 'open' })
|
ev.emit('connection.update', { connection: 'open' })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
export interface Contact {
|
export interface Contact {
|
||||||
id: string
|
id: string
|
||||||
|
lid?: string
|
||||||
/** name of the contact, you have saved on your WA */
|
/** name of the contact, you have saved on your WA */
|
||||||
name?: string
|
name?: 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 */
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export type BaileysEventMap = {
|
|||||||
'chats.upsert': Chat[]
|
'chats.upsert': Chat[]
|
||||||
/** update the given chats */
|
/** update the given chats */
|
||||||
'chats.update': ChatUpdate[]
|
'chats.update': ChatUpdate[]
|
||||||
|
'chats.phoneNumberShare': {lid: string, jid: string}
|
||||||
/** delete chats with given ID */
|
/** delete chats with given ID */
|
||||||
'chats.delete': string[]
|
'chats.delete': string[]
|
||||||
/** presence of contact in a chat updated */
|
/** presence of contact in a chat updated */
|
||||||
@@ -54,6 +55,7 @@ export type BaileysEventMap = {
|
|||||||
|
|
||||||
'blocklist.set': { blocklist: string[] }
|
'blocklist.set': { blocklist: string[] }
|
||||||
'blocklist.update': { blocklist: string[], type: 'add' | 'remove' }
|
'blocklist.update': { blocklist: string[], type: 'add' | 'remove' }
|
||||||
|
|
||||||
/** Receive an update on a call, including when the call was received, rejected, accepted */
|
/** Receive an update on a call, including when the call was received, rejected, accepted */
|
||||||
'call': WACallEvent[]
|
'call': WACallEvent[]
|
||||||
'labels.edit': Label
|
'labels.edit': Label
|
||||||
|
|||||||
@@ -96,6 +96,14 @@ export type PollMessageOptions = {
|
|||||||
messageSecret?: Uint8Array
|
messageSecret?: Uint8Array
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SharePhoneNumber = {
|
||||||
|
sharePhoneNumber: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
type RequestPhoneNumber = {
|
||||||
|
requestPhoneNumber: boolean
|
||||||
|
}
|
||||||
|
|
||||||
export type MediaType = keyof typeof MEDIA_HKDF_KEY_MAPPING
|
export type MediaType = keyof typeof MEDIA_HKDF_KEY_MAPPING
|
||||||
export type AnyMediaMessageContent = (
|
export type AnyMediaMessageContent = (
|
||||||
({
|
({
|
||||||
@@ -169,7 +177,7 @@ export type AnyRegularMessageContent = (
|
|||||||
businessOwnerJid?: string
|
businessOwnerJid?: string
|
||||||
body?: string
|
body?: string
|
||||||
footer?: string
|
footer?: string
|
||||||
}
|
} | SharePhoneNumber | RequestPhoneNumber
|
||||||
) & ViewOnce
|
) & ViewOnce
|
||||||
|
|
||||||
export type AnyMessageContent = AnyRegularMessageContent | {
|
export type AnyMessageContent = AnyRegularMessageContent | {
|
||||||
|
|||||||
@@ -583,6 +583,19 @@ export const chatModificationToAppPatch = (
|
|||||||
apiVersion: 5,
|
apiVersion: 5,
|
||||||
operation: OP.SET
|
operation: OP.SET
|
||||||
}
|
}
|
||||||
|
} else if('star' in mod) {
|
||||||
|
const key = mod.star.messages[0]
|
||||||
|
patch = {
|
||||||
|
syncAction: {
|
||||||
|
starAction: {
|
||||||
|
starred: !!mod.star.star
|
||||||
|
}
|
||||||
|
},
|
||||||
|
index: ['star', jid, key.id, key.fromMe ? '1' : '0', '0'],
|
||||||
|
type: 'regular_low',
|
||||||
|
apiVersion: 2,
|
||||||
|
operation: OP.SET
|
||||||
|
}
|
||||||
} else if('delete' in mod) {
|
} else if('delete' in mod) {
|
||||||
patch = {
|
patch = {
|
||||||
syncAction: {
|
syncAction: {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Boom } from '@hapi/boom'
|
|||||||
import { Logger } from 'pino'
|
import { Logger } from 'pino'
|
||||||
import { proto } from '../../WAProto'
|
import { proto } from '../../WAProto'
|
||||||
import { SignalRepository, WAMessageKey } from '../Types'
|
import { SignalRepository, WAMessageKey } from '../Types'
|
||||||
import { areJidsSameUser, BinaryNode, isJidBroadcast, isJidGroup, isJidStatusBroadcast, isJidUser } from '../WABinary'
|
import { areJidsSameUser, BinaryNode, isJidBroadcast, isJidGroup, isJidStatusBroadcast, isJidUser, isLidUser } from '../WABinary'
|
||||||
import { unpadRandomMax16 } from './generics'
|
import { unpadRandomMax16 } from './generics'
|
||||||
|
|
||||||
const NO_MESSAGE_FOUND_ERROR_TEXT = 'Message absent from node'
|
const NO_MESSAGE_FOUND_ERROR_TEXT = 'Message absent from node'
|
||||||
@@ -15,7 +15,8 @@ type MessageType = 'chat' | 'peer_broadcast' | 'other_broadcast' | 'group' | 'di
|
|||||||
*/
|
*/
|
||||||
export function decodeMessageNode(
|
export function decodeMessageNode(
|
||||||
stanza: BinaryNode,
|
stanza: BinaryNode,
|
||||||
meId: string
|
meId: string,
|
||||||
|
meLid: string
|
||||||
) {
|
) {
|
||||||
let msgType: MessageType
|
let msgType: MessageType
|
||||||
let chatId: string
|
let chatId: string
|
||||||
@@ -27,6 +28,7 @@ export function decodeMessageNode(
|
|||||||
const recipient: string | undefined = stanza.attrs.recipient
|
const recipient: string | undefined = stanza.attrs.recipient
|
||||||
|
|
||||||
const isMe = (jid: string) => areJidsSameUser(jid, meId)
|
const isMe = (jid: string) => areJidsSameUser(jid, meId)
|
||||||
|
const isMeLid = (jid: string) => areJidsSameUser(jid, meLid)
|
||||||
|
|
||||||
if(isJidUser(from)) {
|
if(isJidUser(from)) {
|
||||||
if(recipient) {
|
if(recipient) {
|
||||||
@@ -39,6 +41,19 @@ export function decodeMessageNode(
|
|||||||
chatId = from
|
chatId = from
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msgType = 'chat'
|
||||||
|
author = from
|
||||||
|
} else if(isLidUser(from)) {
|
||||||
|
if(recipient) {
|
||||||
|
if(!isMeLid(from)) {
|
||||||
|
throw new Boom('receipient present, but msg not from me', { data: stanza })
|
||||||
|
}
|
||||||
|
|
||||||
|
chatId = recipient
|
||||||
|
} else {
|
||||||
|
chatId = from
|
||||||
|
}
|
||||||
|
|
||||||
msgType = 'chat'
|
msgType = 'chat'
|
||||||
author = from
|
author = from
|
||||||
} else if(isJidGroup(from)) {
|
} else if(isJidGroup(from)) {
|
||||||
@@ -67,7 +82,7 @@ export function decodeMessageNode(
|
|||||||
throw new Boom('Unknown message type', { data: stanza })
|
throw new Boom('Unknown message type', { data: stanza })
|
||||||
}
|
}
|
||||||
|
|
||||||
const fromMe = isMe(stanza.attrs.participant || stanza.attrs.from)
|
const fromMe = (isLidUser(from) ? isMeLid : isMe)(stanza.attrs.participant || stanza.attrs.from)
|
||||||
const pushname = stanza.attrs.notify
|
const pushname = stanza.attrs.notify
|
||||||
|
|
||||||
const key: WAMessageKey = {
|
const key: WAMessageKey = {
|
||||||
@@ -98,10 +113,11 @@ export function decodeMessageNode(
|
|||||||
export const decryptMessageNode = (
|
export const decryptMessageNode = (
|
||||||
stanza: BinaryNode,
|
stanza: BinaryNode,
|
||||||
meId: string,
|
meId: string,
|
||||||
|
meLid: string,
|
||||||
repository: SignalRepository,
|
repository: SignalRepository,
|
||||||
logger: Logger
|
logger: Logger
|
||||||
) => {
|
) => {
|
||||||
const { fullMessage, author, sender } = decodeMessageNode(stanza, meId)
|
const { fullMessage, author, sender } = decodeMessageNode(stanza, meId, meLid)
|
||||||
return {
|
return {
|
||||||
fullMessage,
|
fullMessage,
|
||||||
category: stanza.attrs.category,
|
category: stanza.attrs.category,
|
||||||
@@ -183,4 +199,4 @@ export const decryptMessageNode = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -449,6 +449,12 @@ export const generateWAMessageContent = async(
|
|||||||
selectableOptionsCount: message.poll.selectableCount,
|
selectableOptionsCount: message.poll.selectableCount,
|
||||||
options: message.poll.values.map(optionName => ({ optionName })),
|
options: message.poll.values.map(optionName => ({ optionName })),
|
||||||
}
|
}
|
||||||
|
} else if('sharePhoneNumber' in message) {
|
||||||
|
m.protocolMessage = {
|
||||||
|
type: proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER
|
||||||
|
}
|
||||||
|
} else if('requestPhoneNumber' in message) {
|
||||||
|
m.requestPhoneNumberMessage = {}
|
||||||
} else {
|
} else {
|
||||||
m = await prepareWAMessageMedia(
|
m = await prepareWAMessageMedia(
|
||||||
message,
|
message,
|
||||||
|
|||||||
@@ -263,6 +263,22 @@ const processMessage = async(
|
|||||||
ephemeralSettingTimestamp: toNumber(message.messageTimestamp),
|
ephemeralSettingTimestamp: toNumber(message.messageTimestamp),
|
||||||
ephemeralExpiration: protocolMsg.ephemeralExpiration || null
|
ephemeralExpiration: protocolMsg.ephemeralExpiration || null
|
||||||
})
|
})
|
||||||
|
break
|
||||||
|
case proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_RESPONSE_MESSAGE:
|
||||||
|
const response = protocolMsg.peerDataOperationRequestResponseMessage!
|
||||||
|
if(response) {
|
||||||
|
const { peerDataOperationResult } = response
|
||||||
|
for(const result of peerDataOperationResult!) {
|
||||||
|
const { placeholderMessageResendResponse: retryResponse } = result
|
||||||
|
if(retryResponse) {
|
||||||
|
const webMessageInfo = proto.WebMessageInfo.decode(retryResponse.webMessageInfoBytes!)
|
||||||
|
ev.emit('messages.update', [
|
||||||
|
{ key: webMessageInfo.key, update: { message: webMessageInfo.message } }
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
} else if(content?.reactionMessage) {
|
} else if(content?.reactionMessage) {
|
||||||
@@ -387,4 +403,4 @@ const processMessage = async(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default processMessage
|
export default processMessage
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ export const decodeDecompressedBinaryNode = (
|
|||||||
const device = readByte()
|
const device = readByte()
|
||||||
const user = readString(readByte())
|
const user = readString(readByte())
|
||||||
|
|
||||||
return jidEncode(user, 's.whatsapp.net', device, agent)
|
return jidEncode(user, agent === 0 ? 's.whatsapp.net' : 'lid', device)
|
||||||
}
|
}
|
||||||
|
|
||||||
const readString = (tag: number): string => {
|
const readString = (tag: number): string => {
|
||||||
@@ -262,4 +262,4 @@ export const decodeDecompressedBinaryNode = (
|
|||||||
export const decodeBinaryNode = (buff: Buffer): BinaryNode => {
|
export const decodeBinaryNode = (buff: Buffer): BinaryNode => {
|
||||||
const decompBuff = decompressingIfRequired(buff)
|
const decompBuff = decompressingIfRequired(buff)
|
||||||
return decodeDecompressedBinaryNode(decompBuff, constants)
|
return decodeDecompressedBinaryNode(decompBuff, constants)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,10 +52,10 @@ export const encodeBinaryNode = (
|
|||||||
pushBytes(bytes)
|
pushBytes(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
const writeJid = ({ agent, device, user, server }: FullJid) => {
|
const writeJid = ({ domainType, device, user, server }: FullJid) => {
|
||||||
if(typeof agent !== 'undefined' || typeof device !== 'undefined') {
|
if(typeof device !== 'undefined') {
|
||||||
pushByte(TAGS.AD_JID)
|
pushByte(TAGS.AD_JID)
|
||||||
pushByte(agent || 0)
|
pushByte(domainType || 0)
|
||||||
pushByte(device || 0)
|
pushByte(device || 0)
|
||||||
writeString(user)
|
writeString(user)
|
||||||
} else {
|
} else {
|
||||||
@@ -233,4 +233,4 @@ export const encodeBinaryNode = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
return Buffer.from(buffer)
|
return Buffer.from(buffer)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ export const SERVER_JID = 'server@c.us'
|
|||||||
export const PSA_WID = '0@c.us'
|
export const PSA_WID = '0@c.us'
|
||||||
export const STORIES_JID = 'status@broadcast'
|
export const STORIES_JID = 'status@broadcast'
|
||||||
|
|
||||||
export type JidServer = 'c.us' | 'g.us' | 'broadcast' | 's.whatsapp.net' | 'call'
|
export type JidServer = 'c.us' | 'g.us' | 'broadcast' | 's.whatsapp.net' | 'call' | 'lid'
|
||||||
|
|
||||||
export type JidWithDevice = {
|
export type JidWithDevice = {
|
||||||
user: string
|
user: string
|
||||||
@@ -13,7 +13,7 @@ export type JidWithDevice = {
|
|||||||
|
|
||||||
export type FullJid = JidWithDevice & {
|
export type FullJid = JidWithDevice & {
|
||||||
server: JidServer | string
|
server: JidServer | string
|
||||||
agent?: number
|
domainType?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export const jidEncode = (user: string | number | null, server: JidServer, device?: number, agent?: number) => {
|
export const jidEncode = (user: string | number | null, server: JidServer, device?: number, agent?: number) => {
|
||||||
@@ -30,12 +30,12 @@ export const jidDecode = (jid: string | undefined): FullJid | undefined => {
|
|||||||
const userCombined = jid!.slice(0, sepIdx)
|
const userCombined = jid!.slice(0, sepIdx)
|
||||||
|
|
||||||
const [userAgent, device] = userCombined.split(':')
|
const [userAgent, device] = userCombined.split(':')
|
||||||
const [user, agent] = userAgent.split('_')
|
const user = userAgent.split('_')[0]
|
||||||
|
|
||||||
return {
|
return {
|
||||||
server,
|
server,
|
||||||
user,
|
user,
|
||||||
agent: agent ? +agent : undefined,
|
domainType: server === 'lid' ? 1 : 0,
|
||||||
device: device ? +device : undefined
|
device: device ? +device : undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,6 +46,8 @@ export const areJidsSameUser = (jid1: string | undefined, jid2: string | undefin
|
|||||||
)
|
)
|
||||||
/** is the jid a user */
|
/** is the jid a user */
|
||||||
export const isJidUser = (jid: string | undefined) => (jid?.endsWith('@s.whatsapp.net'))
|
export const isJidUser = (jid: string | undefined) => (jid?.endsWith('@s.whatsapp.net'))
|
||||||
|
/** is the jid a group */
|
||||||
|
export const isLidUser = (jid: string | undefined) => (jid?.endsWith('@lid'))
|
||||||
/** is the jid a broadcast */
|
/** is the jid a broadcast */
|
||||||
export const isJidBroadcast = (jid: string | undefined) => (jid?.endsWith('@broadcast'))
|
export const isJidBroadcast = (jid: string | undefined) => (jid?.endsWith('@broadcast'))
|
||||||
/** is the jid a group */
|
/** is the jid a group */
|
||||||
@@ -61,4 +63,4 @@ export const jidNormalizedUser = (jid: string | undefined) => {
|
|||||||
|
|
||||||
const { user, server } = result
|
const { user, server } = result
|
||||||
return jidEncode(user, server === 'c.us' ? 's.whatsapp.net' : server as JidServer)
|
return jidEncode(user, server === 'c.us' ? 's.whatsapp.net' : server as JidServer)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user