usync, chat: get bot profile info and get bot list

This commit is contained in:
Rajeh Taher
2025-03-19 00:44:43 +02:00
parent add437047a
commit 98ecd2a653
4 changed files with 123 additions and 3 deletions

View File

@@ -2,7 +2,7 @@ import NodeCache from '@cacheable/node-cache'
import { Boom } from '@hapi/boom'
import { proto } from '../../WAProto'
import { DEFAULT_CACHE_TTLS, PROCESSABLE_HISTORY_TYPES } from '../Defaults'
import { ALL_WA_PATCH_NAMES, ChatModification, ChatMutation, LTHashState, MessageUpsertType, PresenceData, SocketConfig, WABusinessHoursConfig, WABusinessProfile, WAMediaUpload, WAMessage, WAPatchCreate, WAPatchName, WAPresence, WAPrivacyCallValue, WAPrivacyGroupAddValue, WAPrivacyMessagesValue, WAPrivacyOnlineValue, WAPrivacyValue, WAReadReceiptsValue } from '../Types'
import { ALL_WA_PATCH_NAMES, BotListInfo, ChatModification, ChatMutation, LTHashState, MessageUpsertType, PresenceData, SocketConfig, WABusinessHoursConfig, WABusinessProfile, WAMediaUpload, WAMessage, WAPatchCreate, WAPatchName, WAPresence, WAPrivacyCallValue, WAPrivacyGroupAddValue, WAPrivacyMessagesValue, WAPrivacyOnlineValue, WAPrivacyValue, WAReadReceiptsValue } from '../Types'
import { LabelActionBody } from '../Types/Label'
import { chatModificationToAppPatch, ChatMutationMap, decodePatches, decodeSyncdSnapshot, encodeSyncdPatch, extractSyncdPatches, generateProfilePicture, getHistoryMsg, newLTHashState, processSyncAction } from '../Utils'
import { makeMutex } from '../Utils/make-mutex'
@@ -10,7 +10,6 @@ import processMessage from '../Utils/process-message'
import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, reduceBinaryNodeToDictionary, S_WHATSAPP_NET } from '../WABinary'
import { USyncQuery, USyncUser } from '../WAUSync'
import { makeUSyncSocket } from './usync'
const MAX_SYNC_ATTEMPTS = 2
export const makeChatsSocket = (config: SocketConfig) => {
@@ -144,6 +143,39 @@ export const makeChatsSocket = (config: SocketConfig) => {
})
}
const getBotListV2 = async() => {
const resp = await query({
tag: 'iq',
attrs: {
xmlns: 'bot',
to: S_WHATSAPP_NET,
type: 'get'
},
content: [{
tag: 'bot',
attrs: {
v: '2'
}
}]
})
const botNode = getBinaryNodeChild(resp, 'bot')
const botList: BotListInfo[] = []
for(const section of getBinaryNodeChildren(botNode, 'section')) {
if(section.attrs.type === 'all') {
for(const bot of getBinaryNodeChildren(section, 'bot')) {
botList.push({
jid: bot.attrs.jid,
personaId: bot.attrs['persona_id']
})
}
}
}
return botList
}
const onWhatsApp = async(...jids: string[]) => {
const usyncQuery = new USyncQuery()
.withContactProtocol()
@@ -979,6 +1011,7 @@ export const makeChatsSocket = (config: SocketConfig) => {
return {
...sock,
getBotListV2,
processingMutex,
fetchPrivacySettings,
upsertMessage,

View File

@@ -31,6 +31,11 @@ export interface PresenceData {
lastSeen?: number
}
export type BotListInfo = {
jid: string
personaId: string
}
export type ChatMutation = {
syncAction: proto.ISyncActionData
index: string[]

View File

@@ -0,0 +1,77 @@
import { USyncQueryProtocol } from '../../Types/USync'
import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, getBinaryNodeChildString } from '../../WABinary'
import { USyncUser } from '../USyncUser'
export type BotProfileCommand = {
name: string
description: string
}
export type BotProfileInfo = {
jid: string
name: string
attributes: string
description: string
category: string
isDefault: boolean
prompts: string[]
personaId: string
commands: BotProfileCommand[]
commandsDescription: string
}
export class USyncBotProfileProtocol implements USyncQueryProtocol {
name = 'bot'
getQueryElement(): BinaryNode {
return {
tag: 'bot',
attrs: { },
content: [{ tag: 'profile', attrs: { v: '1' } }]
}
}
getUserElement(user: USyncUser): BinaryNode {
return {
tag: 'bot',
attrs: { },
content: [{ tag: 'profile', attrs: { 'persona_id': user.personaId } }]
}
}
parser(node: BinaryNode): BotProfileInfo {
const botNode = getBinaryNodeChild(node, 'bot')
const profile = getBinaryNodeChild(botNode, 'profile')
const commandsNode = getBinaryNodeChild(profile, 'commands')
const promptsNode = getBinaryNodeChild(profile, 'prompts')
const commands: BotProfileCommand[] = []
const prompts: string[] = []
for(const command of getBinaryNodeChildren(commandsNode, 'command')) {
commands.push({
name: getBinaryNodeChildString(command, 'name')!,
description: getBinaryNodeChildString(command, 'description')!
})
}
for(const prompt of getBinaryNodeChildren(promptsNode, 'prompt')) {
prompts.push(`${getBinaryNodeChildString(prompt, 'emoji')!} ${getBinaryNodeChildString(prompt, 'text')!}`)
}
return {
isDefault: !!getBinaryNodeChild(profile, 'default'),
jid: node.attrs.jid,
name: getBinaryNodeChildString(profile, 'name')!,
attributes: getBinaryNodeChildString(profile, 'attributes')!,
description: getBinaryNodeChildString(profile, 'description')!,
category: getBinaryNodeChildString(profile, 'category')!,
personaId: profile!.attrs['persona_id'],
commandsDescription: getBinaryNodeChildString(commandsNode, 'description')!,
commands,
prompts
}
}
}

View File

@@ -3,6 +3,7 @@ export class USyncUser {
lid: string
phone: string
type: string
personaId: string
withId(id: string) {
this.id = id
@@ -24,4 +25,8 @@ export class USyncUser {
return this
}
}
withPersonaId(personaId: string) {
this.personaId = personaId
return this
}
}