feature(feature/pin-message): initial/final commit (#959)

This commit is contained in:
Rajeh Taher
2024-08-14 12:09:29 +03:00
committed by GitHub
parent 2dc1afa4ff
commit 020add8b9b
3 changed files with 37 additions and 7 deletions

View File

@@ -4,7 +4,7 @@ import NodeCache from 'node-cache'
import { proto } from '../../WAProto' import { proto } from '../../WAProto'
import { DEFAULT_CACHE_TTLS, WA_DEFAULT_EPHEMERAL } from '../Defaults' import { DEFAULT_CACHE_TTLS, WA_DEFAULT_EPHEMERAL } from '../Defaults'
import { AnyMessageContent, MediaConnInfo, MessageReceiptType, MessageRelayOptions, MiscMessageGenerationOptions, SocketConfig, WAMessageKey } from '../Types' import { AnyMessageContent, MediaConnInfo, MessageReceiptType, MessageRelayOptions, MiscMessageGenerationOptions, SocketConfig, WAMessageKey } from '../Types'
import { aggregateMessageKeysNotFromMe, assertMediaContent, bindWaitForEvent, decryptMediaRetryData, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, generateMessageIDV2, generateWAMessage, getStatusCodeForMediaRetry, getUrlFromDirectPath, getWAUploadToServer, parseAndInjectE2ESessions, unixTimestampSeconds } from '../Utils' import { aggregateMessageKeysNotFromMe, assertMediaContent, bindWaitForEvent, decryptMediaRetryData, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, generateMessageIDV2, generateWAMessage, getStatusCodeForMediaRetry, getUrlFromDirectPath, getWAUploadToServer, normalizeMessageContent, parseAndInjectE2ESessions, unixTimestampSeconds } from '../Utils'
import { getUrlInfo } from '../Utils/link-preview' import { getUrlInfo } from '../Utils/link-preview'
import { areJidsSameUser, BinaryNode, BinaryNodeAttributes, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, isJidUser, jidDecode, jidEncode, jidNormalizedUser, JidWithDevice, S_WHATSAPP_NET } from '../WABinary' import { areJidsSameUser, BinaryNode, BinaryNodeAttributes, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, isJidUser, jidDecode, jidEncode, jidNormalizedUser, JidWithDevice, S_WHATSAPP_NET } from '../WABinary'
import { makeGroupsSocket } from './groups' import { makeGroupsSocket } from './groups'
@@ -362,6 +362,8 @@ export const makeMessagesSocket = (config: SocketConfig) => {
} }
} }
const extraAttrs = {}
if(participant) { if(participant) {
// when the retry request is not for a group // when the retry request is not for a group
// only send to the specific device that asked for a retry // only send to the specific device that asked for a retry
@@ -377,6 +379,14 @@ export const makeMessagesSocket = (config: SocketConfig) => {
await authState.keys.transaction( await authState.keys.transaction(
async() => { async() => {
const mediaType = getMediaType(message) const mediaType = getMediaType(message)
if(mediaType) {
extraAttrs['mediatype'] = mediaType
}
if(normalizeMessageContent(message)?.pinInChatMessage) {
extraAttrs['decrypt-fail'] = 'hide'
}
if(isGroup || isStatus) { if(isGroup || isStatus) {
const [groupData, senderKeyMap] = await Promise.all([ const [groupData, senderKeyMap] = await Promise.all([
(async() => { (async() => {
@@ -445,7 +455,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
await assertSessions(senderKeyJids, false) await assertSessions(senderKeyJids, false)
const result = await createParticipantNodes(senderKeyJids, senderKeyMsg, mediaType ? { mediatype: mediaType } : undefined) const result = await createParticipantNodes(senderKeyJids, senderKeyMsg, extraAttrs)
shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || result.shouldIncludeDeviceIdentity shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || result.shouldIncludeDeviceIdentity
participants.push(...result.nodes) participants.push(...result.nodes)
@@ -496,8 +506,8 @@ export const makeMessagesSocket = (config: SocketConfig) => {
{ nodes: meNodes, shouldIncludeDeviceIdentity: s1 }, { nodes: meNodes, shouldIncludeDeviceIdentity: s1 },
{ nodes: otherNodes, shouldIncludeDeviceIdentity: s2 } { nodes: otherNodes, shouldIncludeDeviceIdentity: s2 }
] = await Promise.all([ ] = await Promise.all([
createParticipantNodes(meJids, meMsg, mediaType ? { mediatype: mediaType } : undefined), createParticipantNodes(meJids, meMsg, extraAttrs),
createParticipantNodes(otherJids, message, mediaType ? { mediatype: mediaType } : undefined) createParticipantNodes(otherJids, message, extraAttrs)
]) ])
participants.push(...meNodes) participants.push(...meNodes)
participants.push(...otherNodes) participants.push(...otherNodes)
@@ -674,7 +684,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
} }
content.directPath = media.directPath content.directPath = media.directPath
content.url = getUrlFromDirectPath(content.directPath!) content.url = getUrlFromDirectPath(content.directPath)
logger.debug({ directPath: media.directPath, key: result.key }, 'media update successful') logger.debug({ directPath: media.directPath, key: result.key }, 'media update successful')
} catch(err) { } catch(err) {
@@ -745,6 +755,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
) )
const isDeleteMsg = 'delete' in content && !!content.delete const isDeleteMsg = 'delete' in content && !!content.delete
const isEditMsg = 'edit' in content && !!content.edit const isEditMsg = 'edit' in content && !!content.edit
const isPinMsg = 'pin' in content && !!content.pin
const additionalAttributes: BinaryNodeAttributes = { } const additionalAttributes: BinaryNodeAttributes = { }
// required for delete // required for delete
if(isDeleteMsg) { if(isDeleteMsg) {
@@ -756,6 +767,8 @@ export const makeMessagesSocket = (config: SocketConfig) => {
} }
} else if(isEditMsg) { } else if(isEditMsg) {
additionalAttributes.edit = '1' additionalAttributes.edit = '1'
} else if(isPinMsg) {
additionalAttributes.edit = '2'
} }
if('cachedGroupMetadata' in options) { if('cachedGroupMetadata' in options) {

View File

@@ -156,6 +156,14 @@ export type AnyRegularMessageContent = (
| { | {
listReply: Omit<proto.Message.IListResponseMessage, 'contextInfo'> listReply: Omit<proto.Message.IListResponseMessage, 'contextInfo'>
} }
| {
pin: WAMessageKey
type: proto.PinInChat.Type
/**
* 24 hours, 7 days, 30 days
*/
time?: 86400 | 604800 | 2592000
}
| { | {
product: WASendableProduct product: WASendableProduct
businessOwnerJid?: string businessOwnerJid?: string

View File

@@ -124,7 +124,7 @@ export const prepareWAMessageMedia = async(
!!uploadData.media.url && !!uploadData.media.url &&
!!options.mediaCache && ( !!options.mediaCache && (
// generate the key // generate the key
mediaType + ':' + uploadData.media.url!.toString() mediaType + ':' + uploadData.media.url.toString()
) )
if(mediaType === 'document' && !uploadData.fileName) { if(mediaType === 'document' && !uploadData.fileName) {
@@ -394,6 +394,15 @@ export const generateWAMessageContent = async(
(message.disappearingMessagesInChat ? WA_DEFAULT_EPHEMERAL : 0) : (message.disappearingMessagesInChat ? WA_DEFAULT_EPHEMERAL : 0) :
message.disappearingMessagesInChat message.disappearingMessagesInChat
m = prepareDisappearingMessageSettingContent(exp) m = prepareDisappearingMessageSettingContent(exp)
} else if('pin' in message) {
m.pinInChatMessage = {}
m.messageContextInfo = {}
m.pinInChatMessage.key = message.pin
m.pinInChatMessage.type = message.type
m.pinInChatMessage.senderTimestampMs = Date.now()
m.messageContextInfo.messageAddOnDurationInSecs = message.type === 1 ? message.time || 86400 : 0
} else if('buttonReply' in message) { } else if('buttonReply' in message) {
switch (message.type) { switch (message.type) {
case 'template': case 'template':
@@ -678,7 +687,7 @@ export const extractMessageContent = (content: WAMessageContent | undefined | nu
content = normalizeMessageContent(content) content = normalizeMessageContent(content)
if(content?.buttonsMessage) { if(content?.buttonsMessage) {
return extractFromTemplateMessage(content.buttonsMessage!) return extractFromTemplateMessage(content.buttonsMessage)
} }
if(content?.templateMessage?.hydratedFourRowTemplate) { if(content?.templateMessage?.hydratedFourRowTemplate) {