diff --git a/src/Socket/groups.ts b/src/Socket/groups.ts index 155739999a0..651e650301e 100644 --- a/src/Socket/groups.ts +++ b/src/Socket/groups.ts @@ -307,11 +307,13 @@ export const extractGroupMetadata = (result: BinaryNode) => { let descId: string | undefined let descOwner: string | undefined let descOwnerPn: string | undefined + let descOwnerUsername: string | undefined let descTime: number | undefined if (descChild) { desc = getBinaryNodeChildString(descChild, 'body') descOwner = descChild.attrs.participant ? jidNormalizedUser(descChild.attrs.participant) : undefined descOwnerPn = descChild.attrs.participant_pn ? jidNormalizedUser(descChild.attrs.participant_pn) : undefined + descOwnerUsername = descChild.attrs.participant_username || undefined descTime = +descChild.attrs.t! descId = descChild.attrs.id } @@ -326,16 +328,19 @@ export const extractGroupMetadata = (result: BinaryNode) => { subject: group.attrs.subject!, subjectOwner: group.attrs.s_o, subjectOwnerPn: group.attrs.s_o_pn, + subjectOwnerUsername: group.attrs.s_o_username, subjectTime: +group.attrs.s_t!, size: group.attrs.size ? +group.attrs.size : getBinaryNodeChildren(group, 'participant').length, creation: +group.attrs.creation!, owner: group.attrs.creator ? jidNormalizedUser(group.attrs.creator) : undefined, ownerPn: group.attrs.creator_pn ? jidNormalizedUser(group.attrs.creator_pn) : undefined, + ownerUsername: group.attrs.creator_username || undefined, owner_country_code: group.attrs.creator_country_code, desc, descId, descOwner, descOwnerPn, + descOwnerUsername, descTime, linkedParent: getBinaryNodeChild(group, 'linked_parent')?.attrs.jid || undefined, restrict: !!getBinaryNodeChild(group, 'locked'), @@ -350,6 +355,7 @@ export const extractGroupMetadata = (result: BinaryNode) => { id: attrs.jid!, phoneNumber: isLidUser(attrs.jid) && isPnUser(attrs.phone_number) ? attrs.phone_number : undefined, lid: isPnUser(attrs.jid) && isLidUser(attrs.lid) ? attrs.lid : undefined, + username: attrs.participant_username || attrs.username || undefined, admin: (attrs.type || null) as GroupParticipant['admin'] } }), diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 9e905277959..d346e758ce9 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -553,6 +553,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { const actingParticipantLid = fullNode.attrs.participant const actingParticipantPn = fullNode.attrs.participant_pn + const actingParticipantUsername = fullNode.attrs.participant_username const affectedParticipantLid = getBinaryNodeChild(child, 'participant')?.attrs?.jid || actingParticipantLid! const affectedParticipantPn = getBinaryNodeChild(child, 'participant')?.attrs?.phone_number || actingParticipantPn! @@ -576,7 +577,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { { ...metadata, author: actingParticipantLid, - authorPn: actingParticipantPn + authorPn: actingParticipantPn, + authorUsername: actingParticipantUsername } ]) break @@ -608,6 +610,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { id: attrs.jid!, phoneNumber: isLidUser(attrs.jid) && isPnUser(attrs.phone_number) ? attrs.phone_number : undefined, lid: isPnUser(attrs.jid) && isLidUser(attrs.lid) ? attrs.lid : undefined, + username: attrs.participant_username || attrs.username || undefined, admin: (attrs.type || null) as GroupParticipant['admin'] } }) @@ -1133,6 +1136,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { fromMe, participant: node.attrs.participant, participantAlt, + participantUsername: node.attrs.participant_username, addressingMode, id: node.attrs.id, ...(msg.key || {}) diff --git a/src/Types/Contact.ts b/src/Types/Contact.ts index 315f7e15edc..836185b8125 100644 --- a/src/Types/Contact.ts +++ b/src/Types/Contact.ts @@ -9,6 +9,8 @@ export interface Contact { name?: string /** name of the contact, the contact has set on their own on WA */ notify?: string + /** username associated with this contact, when provided by WA */ + username?: string /** I have no idea */ verifiedName?: string // Baileys Added diff --git a/src/Types/Events.ts b/src/Types/Events.ts index 7fb2f337876..4bcaffaacd4 100644 --- a/src/Types/Events.ts +++ b/src/Types/Events.ts @@ -67,6 +67,7 @@ export type BaileysEventMap = { id: string author: string authorPn?: string + authorUsername?: string participants: GroupParticipant[] action: ParticipantAction } @@ -74,6 +75,7 @@ export type BaileysEventMap = { id: string author: string authorPn?: string + authorUsername?: string participant: string participantPn?: string action: RequestJoinAction diff --git a/src/Types/GroupMetadata.ts b/src/Types/GroupMetadata.ts index 97bbe1a8587..4465e47efda 100644 --- a/src/Types/GroupMetadata.ts +++ b/src/Types/GroupMetadata.ts @@ -20,17 +20,20 @@ export interface GroupMetadata { addressingMode?: WAMessageAddressingMode owner: string | undefined ownerPn?: string | undefined + ownerUsername?: string | undefined owner_country_code?: string | undefined subject: string /** group subject owner */ subjectOwner?: string subjectOwnerPn?: string + subjectOwnerUsername?: string /** group subject modification date */ subjectTime?: number creation?: number desc?: string descOwner?: string descOwnerPn?: string + descOwnerUsername?: string descId?: string descTime?: number /** if this group is part of a community, it returns the jid of the community to which it belongs */ @@ -56,6 +59,7 @@ export interface GroupMetadata { /** the person who added you to group or changed some setting in group */ author?: string authorPn?: string + authorUsername?: string } export interface WAGroupCreateResponse { diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 696a0ccee36..111bf336baa 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -19,7 +19,9 @@ export type WAContactMessage = proto.Message.IContactMessage export type WAContactsArrayMessage = proto.Message.IContactsArrayMessage export type WAMessageKey = proto.IMessageKey & { remoteJidAlt?: string + remoteJidUsername?: string participantAlt?: string + participantUsername?: string server_id?: string addressingMode?: string isViewOnce?: boolean // TODO: remove out of the message key, place in WebMessageInfo diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index daeb1a9a955..f76b145a8d2 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -936,6 +936,7 @@ export const processSyncAction = ( action.lidContactAction.firstName || action.lidContactAction.username || undefined, + username: action.lidContactAction.username || undefined, lid: id!, phoneNumber: undefined } diff --git a/src/Utils/decode-wa-message.ts b/src/Utils/decode-wa-message.ts index dc13fa4ef0f..f9aca9d53e2 100644 --- a/src/Utils/decode-wa-message.ts +++ b/src/Utils/decode-wa-message.ts @@ -196,10 +196,14 @@ export function decodeMessageNode(stanza: BinaryNode, meId: string, meLid: strin const key: WAMessageKey = { remoteJid: chatId, remoteJidAlt: !isJidGroup(chatId) ? addressingContext.senderAlt : undefined, + remoteJidUsername: !isJidGroup(chatId) + ? stanza.attrs.peer_recipient_username || stanza.attrs.recipient_username + : undefined, fromMe, id: msgId, participant, participantAlt: isJidGroup(chatId) ? addressingContext.senderAlt : undefined, + participantUsername: stanza.attrs.participant ? stanza.attrs.participant_username : undefined, addressingMode: addressingContext.addressingMode, ...(msgType === 'newsletter' && stanza.attrs.server_id ? { server_id: stanza.attrs.server_id } : {}) } diff --git a/src/Utils/history.ts b/src/Utils/history.ts index 7edb9c81bbc..ce8c4be4ca5 100644 --- a/src/Utils/history.ts +++ b/src/Utils/history.ts @@ -69,6 +69,7 @@ export const processHistoryMessage = (item: proto.IHistorySync, logger?: ILogger contacts.push({ id: chat.id!, name: chat.displayName || chat.name || chat.username || undefined, + username: chat.username || undefined, lid: chat.lidJid || chat.accountLid || undefined, phoneNumber: chat.pnJid || undefined }) diff --git a/src/Utils/process-message.ts b/src/Utils/process-message.ts index 84399445d79..1b1dc56c9d5 100644 --- a/src/Utils/process-message.ts +++ b/src/Utils/process-message.ts @@ -519,12 +519,19 @@ const processMessage = async ( id: jid, author: message.key.participant!, authorPn: message.key.participantAlt!, + authorUsername: message.key.participantUsername!, participants, action }) const emitGroupUpdate = (update: Partial) => { ev.emit('groups.update', [ - { id: jid, ...update, author: message.key.participant ?? undefined, authorPn: message.key.participantAlt } + { + id: jid, + ...update, + author: message.key.participant ?? undefined, + authorPn: message.key.participantAlt, + authorUsername: message.key.participantUsername + } ]) } @@ -533,6 +540,7 @@ const processMessage = async ( id: jid, author: message.key.participant!, authorPn: message.key.participantAlt!, + authorUsername: message.key.participantUsername!, participant: participant.lid, participantPn: participant.pn, action, diff --git a/src/Utils/sync-action-utils.ts b/src/Utils/sync-action-utils.ts index 14ecd31004a..ba0f17fbcdb 100644 --- a/src/Utils/sync-action-utils.ts +++ b/src/Utils/sync-action-utils.ts @@ -46,6 +46,7 @@ export const processContactAction = ( { id, name: action.fullName || action.firstName || action.username || undefined, + username: action.username || undefined, lid: lidJid || undefined, phoneNumber } diff --git a/src/WAUSync/Protocols/USyncContactProtocol.ts b/src/WAUSync/Protocols/USyncContactProtocol.ts index 13472e11d95..539b01ae15d 100644 --- a/src/WAUSync/Protocols/USyncContactProtocol.ts +++ b/src/WAUSync/Protocols/USyncContactProtocol.ts @@ -13,11 +13,37 @@ export class USyncContactProtocol implements USyncQueryProtocol { } getUserElement(user: USyncUser): BinaryNode { - //TODO: Implement type / username fields (not yet supported) + if (user.phone) { + return { + tag: 'contact', + attrs: {}, + content: user.phone + } + } + + if (user.username) { + return { + tag: 'contact', + attrs: { + username: user.username, + ...(user.usernameKey ? { pin: user.usernameKey } : {}), + ...(user.lid ? { lid: user.lid } : {}) + } + } + } + + if (user.type) { + return { + tag: 'contact', + attrs: { + type: user.type + } + } + } + return { tag: 'contact', - attrs: {}, - content: user.phone + attrs: {} } } diff --git a/src/WAUSync/Protocols/USyncUsernameProtocol.ts b/src/WAUSync/Protocols/USyncUsernameProtocol.ts new file mode 100644 index 00000000000..dff58c9aa55 --- /dev/null +++ b/src/WAUSync/Protocols/USyncUsernameProtocol.ts @@ -0,0 +1,28 @@ +import type { USyncQueryProtocol } from '../../Types/USync' +import { assertNodeErrorFree, type BinaryNode } from '../../WABinary' +import { USyncUser } from '../USyncUser' + +export class USyncUsernameProtocol implements USyncQueryProtocol { + name = 'username' + + getQueryElement(): BinaryNode { + return { + tag: 'username', + attrs: {} + } + } + + getUserElement(user: USyncUser): BinaryNode | null { + void user + return null + } + + parser(node: BinaryNode): string | null { + if (node.tag === 'username') { + assertNodeErrorFree(node) + return typeof node.content === 'string' ? node.content : null + } + + return null + } +} diff --git a/src/WAUSync/Protocols/index.ts b/src/WAUSync/Protocols/index.ts index c6e6442a0f9..2e5afaaa0e5 100644 --- a/src/WAUSync/Protocols/index.ts +++ b/src/WAUSync/Protocols/index.ts @@ -2,3 +2,4 @@ export * from './USyncDeviceProtocol' export * from './USyncContactProtocol' export * from './USyncStatusProtocol' export * from './USyncDisappearingModeProtocol' +export * from './USyncUsernameProtocol' diff --git a/src/WAUSync/USyncQuery.ts b/src/WAUSync/USyncQuery.ts index fdf9d78ec4d..2a2952137a6 100644 --- a/src/WAUSync/USyncQuery.ts +++ b/src/WAUSync/USyncQuery.ts @@ -6,7 +6,8 @@ import { USyncContactProtocol, USyncDeviceProtocol, USyncDisappearingModeProtocol, - USyncStatusProtocol + USyncStatusProtocol, + USyncUsernameProtocol } from './Protocols' import { USyncUser } from './USyncUser' @@ -130,4 +131,9 @@ export class USyncQuery { this.protocols.push(new USyncLIDProtocol()) return this } + + withUsernameProtocol() { + this.protocols.push(new USyncUsernameProtocol()) + return this + } } diff --git a/src/WAUSync/USyncUser.ts b/src/WAUSync/USyncUser.ts index 8cfc364bd68..2ae1e3a354f 100644 --- a/src/WAUSync/USyncUser.ts +++ b/src/WAUSync/USyncUser.ts @@ -2,6 +2,8 @@ export class USyncUser { id?: string lid?: string phone?: string + username?: string + usernameKey?: string type?: string personaId?: string @@ -20,6 +22,16 @@ export class USyncUser { return this } + withUsername(username: string) { + this.username = username + return this + } + + withUsernameKey(usernameKey: string) { + this.usernameKey = usernameKey + return this + } + withType(type: string) { this.type = type return this