diff --git a/src/Socket/groups.ts b/src/Socket/groups.ts index 226df38922c..e9e24aac8ab 100644 --- a/src/Socket/groups.ts +++ b/src/Socket/groups.ts @@ -1,6 +1,6 @@ import { proto } from '../../WAProto' import { GroupMetadata, GroupParticipant, ParticipantAction, SocketConfig, WAMessageKey, WAMessageStubType } from '../Types' -import { generateMessageID, unixTimestampSeconds } from '../Utils' +import { generateMessageID, generateMessageIDV2, unixTimestampSeconds } from '../Utils' import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, getBinaryNodeChildString, jidEncode, jidNormalizedUser } from '../WABinary' import { makeChatsSocket } from './chats' @@ -272,7 +272,7 @@ export const makeGroupsSocket = (config: SocketConfig) => { { key: { remoteJid: inviteMessage.groupJid, - id: generateMessageID(), + id: generateMessageIDV2(sock.user?.id), fromMe: false, participant: key.remoteJid, }, diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 070a1f8f361..320cca28e49 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -4,7 +4,7 @@ import NodeCache from 'node-cache' import { proto } from '../../WAProto' import { DEFAULT_CACHE_TTLS, WA_DEFAULT_EPHEMERAL } from '../Defaults' import { AnyMessageContent, MediaConnInfo, MessageReceiptType, MessageRelayOptions, MiscMessageGenerationOptions, SocketConfig, WAMessageKey } from '../Types' -import { aggregateMessageKeysNotFromMe, assertMediaContent, bindWaitForEvent, decryptMediaRetryData, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, generateMessageID, generateWAMessage, getStatusCodeForMediaRetry, getUrlFromDirectPath, getWAUploadToServer, parseAndInjectE2ESessions, unixTimestampSeconds } from '../Utils' +import { aggregateMessageKeysNotFromMe, assertMediaContent, bindWaitForEvent, decryptMediaRetryData, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, generateMessageID, generateMessageIDV2, generateWAMessage, getStatusCodeForMediaRetry, getUrlFromDirectPath, getWAUploadToServer, parseAndInjectE2ESessions, unixTimestampSeconds } from '../Utils' import { getUrlInfo } from '../Utils/link-preview' import { areJidsSameUser, BinaryNode, BinaryNodeAttributes, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, isJidUser, jidDecode, jidEncode, jidNormalizedUser, JidWithDevice, S_WHATSAPP_NET } from '../WABinary' import { makeGroupsSocket } from './groups' @@ -314,7 +314,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { const isStatus = jid === statusJid const isLid = server === 'lid' - msgId = msgId || generateMessageID() + msgId = msgId || generateMessageIDV2(sock.user?.id) useUserDevicesCache = useUserDevicesCache !== false const participants: BinaryNode[] = [] @@ -740,6 +740,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { upload: waUploadToServer, mediaCache: config.mediaCache, options: config.options, + messageId: generateMessageIDV2(sock.user?.id), ...options, } ) diff --git a/src/Utils/generics.ts b/src/Utils/generics.ts index 17696aeadcb..82a9d8193fc 100644 --- a/src/Utils/generics.ts +++ b/src/Utils/generics.ts @@ -1,12 +1,12 @@ import { Boom } from '@hapi/boom' import axios, { AxiosRequestConfig } from 'axios' -import { randomBytes } from 'crypto' +import { createHash, randomBytes } from 'crypto' import { platform, release } from 'os' import { Logger } from 'pino' import { proto } from '../../WAProto' import { version as baileysVersion } from '../Defaults/baileys-version.json' import { BaileysEventEmitter, BaileysEventMap, DisconnectReason, WACallUpdateType, WAVersion } from '../Types' -import { BinaryNode, getAllBinaryNodeChildren } from '../WABinary' +import { BinaryNode, getAllBinaryNodeChildren, jidDecode } from '../WABinary' const PLATFORM_MAP = { 'aix': 'AIX', @@ -170,6 +170,27 @@ export async function promiseTimeout(ms: number | undefined, promise: (resolv return p as Promise } +// inspired from whatsmeow code +// https://github.com/tulir/whatsmeow/blob/64bc969fbe78d31ae0dd443b8d4c80a5d026d07a/send.go#L42 +export const generateMessageIDV2 = (userId?: string): string => { + const data = Buffer.alloc(8 + 20 + 16) + data.writeBigUInt64BE(BigInt(Math.floor(Date.now() / 1000))) + + if (userId) { + const id = jidDecode(userId) + if (id?.user) { + data.write(id.user, 8) + data.write('@c.us', 8 + id.user.length) + } + } + + const random = randomBytes(16) + random.copy(data, 28) + + const hash = createHash('sha256').update(data).digest() + return '3EB0' + hash.toString('hex').toUpperCase().substring(0, 18) +} + // generate a random ID to attach to a message export const generateMessageID = () => '3EB0' + randomBytes(18).toString('hex').toUpperCase()