feat(business): change profile/cover photo and manage quick replies (#1724)

This commit is contained in:
vini
2025-09-07 08:08:26 -03:00
committed by GitHub
parent 084761dc31
commit 50fc83b008
8 changed files with 217 additions and 8 deletions
+141 -2
View File
@@ -1,4 +1,6 @@
import type { GetCatalogOptions, ProductCreate, ProductUpdate, SocketConfig } from '../Types'
import type { GetCatalogOptions, ProductCreate, ProductUpdate, SocketConfig, WAMediaUpload } from '../Types'
import type { UpdateBussinesProfileProps } from '../Types/Bussines'
import { getRawMediaUploadData } from '../Utils'
import {
parseCatalogNode,
parseCollectionsNode,
@@ -15,6 +17,140 @@ export const makeBusinessSocket = (config: SocketConfig) => {
const sock = makeMessagesRecvSocket(config)
const { authState, query, waUploadToServer } = sock
const updateBussinesProfile = async (args: UpdateBussinesProfileProps) => {
const node: BinaryNode[] = []
const simpleFields: (keyof UpdateBussinesProfileProps)[] = ['address', 'email', 'description']
node.push(
...simpleFields
.filter(key => args[key])
.map(key => ({
tag: key,
attrs: {},
content: args[key] as string
}))
)
if (args.websites) {
node.push(
...args.websites.map(website => ({
tag: 'website',
attrs: {},
content: website
}))
)
}
if (args.hours) {
node.push({
tag: 'business_hours',
attrs: { timezone: args.hours.timezone },
content: args.hours.days.map(config => {
const base = {
tag: 'business_hours_config',
attrs: { day_of_week: config.day, mode: config.mode }
}
if (config.mode === 'specific_hours') {
return {
...base,
attrs: {
...base.attrs,
open_time: config.openTimeInMinutes,
close_time: config.closeTimeInMinutes
}
}
}
return base
})
})
}
const result = await query({
tag: 'iq',
attrs: {
to: S_WHATSAPP_NET,
type: 'set',
xmlns: 'w:biz'
},
content: [
{
tag: 'business_profile',
attrs: {
v: '3',
mutation_type: 'delta'
},
content: node
}
]
})
return result
}
const updateCoverPhoto = async (photo: WAMediaUpload) => {
const { fileSha256, filePath } = await getRawMediaUploadData(photo, 'biz-cover-photo')
const fileSha256B64 = fileSha256.toString('base64')
const { meta_hmac, fbid, ts } = await waUploadToServer(filePath, {
fileEncSha256B64: fileSha256B64,
mediaType: 'biz-cover-photo'
})
await query({
tag: 'iq',
attrs: {
to: S_WHATSAPP_NET,
type: 'set',
xmlns: 'w:biz'
},
content: [
{
tag: 'business_profile',
attrs: {
v: '3',
mutation_type: 'delta'
},
content: [
{
tag: 'cover_photo',
attrs: { id: String(fbid), op: 'update', token: meta_hmac!, ts: String(ts) }
}
]
}
]
})
return fbid!
}
const removeCoverPhoto = async (id: string) => {
return await query({
tag: 'iq',
attrs: {
to: S_WHATSAPP_NET,
type: 'set',
xmlns: 'w:biz'
},
content: [
{
tag: 'business_profile',
attrs: {
v: '3',
mutation_type: 'delta'
},
content: [
{
tag: 'cover_photo',
attrs: { op: 'delete', id }
}
]
}
]
})
}
const getCatalog = async ({ jid, limit, cursor }: GetCatalogOptions) => {
jid = jid || authState.creds.me?.id
jid = jidNormalizedUser(jid)
@@ -277,6 +413,9 @@ export const makeBusinessSocket = (config: SocketConfig) => {
getCollections,
productCreate,
productDelete,
productUpdate
productUpdate,
updateBussinesProfile,
updateCoverPhoto,
removeCoverPhoto
}
}
+28 -1
View File
@@ -26,6 +26,7 @@ import type {
WAReadReceiptsValue
} from '../Types'
import { ALL_WA_PATCH_NAMES } from '../Types'
import type { QuickReplyAction } from '../Types/Bussines.js'
import type { LabelActionBody } from '../Types/Label'
import { SyncState } from '../Types/State'
import {
@@ -997,6 +998,30 @@ export const makeChatsSocket = (config: SocketConfig) => {
)
}
/**
* Add or Edit Quick Reply
*/
const addOrEditQuickReply = (quickReply: QuickReplyAction) => {
return chatModify(
{
quickReply
},
''
)
}
/**
* Remove Quick Reply
*/
const removeQuickReply = (timestamp: string) => {
return chatModify(
{
quickReply: { timestamp, deleted: true }
},
''
)
}
/**
* queries need to be fired on connection open
* help ensure parity with WA Web
@@ -1200,6 +1225,8 @@ export const makeChatsSocket = (config: SocketConfig) => {
removeChatLabel,
addMessageLabel,
removeMessageLabel,
star
star,
addOrEditQuickReply,
removeQuickReply
}
}