Merge pull request #1201 from wayre/catalogProducts

Feat: Adicionei suporte para obter o Catálogos de Produtos e as Coleções de Produtos para a versão 2.2.3
This commit is contained in:
Davidson Gomes 2025-02-04 09:59:59 -03:00 committed by GitHub
commit b143363c5d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 182 additions and 0 deletions

View File

@ -3,6 +3,8 @@ import {
BlockUserDto, BlockUserDto,
DeleteMessage, DeleteMessage,
getBase64FromMediaMessageDto, getBase64FromMediaMessageDto,
getCatalogDto,
getCollectionsDto,
MarkChatUnreadDto, MarkChatUnreadDto,
NumberDto, NumberDto,
PrivacySettingDto, PrivacySettingDto,
@ -109,4 +111,12 @@ export class ChatController {
public async blockUser({ instanceName }: InstanceDto, data: BlockUserDto) { public async blockUser({ instanceName }: InstanceDto, data: BlockUserDto) {
return await this.waMonitor.waInstances[instanceName].blockUser(data); return await this.waMonitor.waInstances[instanceName].blockUser(data);
} }
public async fetchCatalog({ instanceName }: InstanceDto, data: getCatalogDto) {
return await this.waMonitor.waInstances[instanceName].fetchCatalog(instanceName, data);
}
public async fetchCatalogCollections({ instanceName }: InstanceDto, data: getCollectionsDto) {
return await this.waMonitor.waInstances[instanceName].fetchCatalogCollections(instanceName, data);
}
} }

View File

@ -126,3 +126,14 @@ export class BlockUserDto {
number: string; number: string;
status: 'block' | 'unblock'; status: 'block' | 'unblock';
} }
export class getCatalogDto {
number?: string;
limit?: number;
cursor?: string;
}
export class getCollectionsDto {
number?: string;
limit?: number;
}

View File

@ -4,6 +4,8 @@ import {
BlockUserDto, BlockUserDto,
DeleteMessage, DeleteMessage,
getBase64FromMediaMessageDto, getBase64FromMediaMessageDto,
getCatalogDto,
getCollectionsDto,
LastMessage, LastMessage,
MarkChatUnreadDto, MarkChatUnreadDto,
NumberBusiness, NumberBusiness,
@ -91,6 +93,7 @@ import makeWASocket, {
BufferedEventData, BufferedEventData,
BufferJSON, BufferJSON,
CacheStore, CacheStore,
CatalogCollection,
Chat, Chat,
ConnectionState, ConnectionState,
Contact, Contact,
@ -100,6 +103,7 @@ import makeWASocket, {
fetchLatestBaileysVersion, fetchLatestBaileysVersion,
generateWAMessageFromContent, generateWAMessageFromContent,
getAggregateVotesInPollMessage, getAggregateVotesInPollMessage,
GetCatalogOptions,
getContentType, getContentType,
getDevice, getDevice,
GroupMetadata, GroupMetadata,
@ -113,6 +117,7 @@ import makeWASocket, {
MiscMessageGenerationOptions, MiscMessageGenerationOptions,
ParticipantAction, ParticipantAction,
prepareWAMessageMedia, prepareWAMessageMedia,
Product,
proto, proto,
UserFacingSocketConfig, UserFacingSocketConfig,
WABrowserDescription, WABrowserDescription,
@ -4628,4 +4633,118 @@ export class BaileysStartupService extends ChannelStartupService {
return response; return response;
} }
//Catalogs and collections
public async fetchCatalog(instanceName: string, data: getCatalogDto) {
const jid = data.number ? createJid(data.number) : this.client?.user?.id;
const limit = data.limit || 10;
const cursor = data.cursor || null;
const onWhatsapp = (await this.whatsappNumber({ numbers: [jid] }))?.shift();
if (!onWhatsapp.exists) {
throw new BadRequestException(onWhatsapp);
}
try {
const info = (await this.whatsappNumber({ numbers: [jid] }))?.shift();
const business = await this.fetchBusinessProfile(info?.jid);
const catalog = await this.getCatalog({ jid: info?.jid, limit, cursor });
return {
wuid: info?.jid || jid,
name: info?.name,
numberExists: info?.exists,
isBusiness: business.isBusiness,
catalogLength: catalog?.products.length,
catalog: catalog?.products,
};
} catch (error) {
console.log(error);
return {
wuid: jid,
name: null,
isBusiness: false,
};
}
}
public async getCatalog({
jid,
limit,
cursor,
}: GetCatalogOptions): Promise<{ products: Product[]; nextPageCursor: string | undefined }> {
try {
jid = jid ? createJid(jid) : this.instance.wuid;
const catalog = await this.client.getCatalog({ jid, limit: limit, cursor: cursor });
if (!catalog) {
return {
products: undefined,
nextPageCursor: undefined,
};
}
return catalog;
} catch (error) {
throw new InternalServerErrorException('Error getCatalog', error.toString());
}
}
public async fetchCatalogCollections(instanceName: string, data: getCollectionsDto) {
const jid = data.number ? createJid(data.number) : this.client?.user?.id;
const limit = data.limit || 10;
const onWhatsapp = (await this.whatsappNumber({ numbers: [jid] }))?.shift();
if (!onWhatsapp.exists) {
throw new BadRequestException(onWhatsapp);
}
try {
const info = (await this.whatsappNumber({ numbers: [jid] }))?.shift();
const business = await this.fetchBusinessProfile(info?.jid);
const catalogCollections = await this.getCollections(info?.jid, limit);
return {
wuid: info?.jid || jid,
name: info?.name,
numberExists: info?.exists,
isBusiness: business.isBusiness,
catalogLength: catalogCollections?.length,
catalogCollections: catalogCollections,
};
} catch (error) {
console.log(error);
return {
wuid: jid,
name: null,
isBusiness: false,
};
}
}
public async getCollections(jid?: string | undefined, limit?: number): Promise<CatalogCollection[]> {
try {
jid = jid ? createJid(jid) : this.instance.wuid;
const result = await this.client.getCollections(jid, limit);
if (!result) {
return [
{
id: undefined,
name: undefined,
products: [],
status: undefined,
},
];
}
return result.collections;
} catch (error) {
throw new InternalServerErrorException('Error getCatalog', error.toString());
}
}
} }

View File

@ -22,6 +22,8 @@ import { Contact, Message, MessageUpdate } from '@prisma/client';
import { import {
archiveChatSchema, archiveChatSchema,
blockUserSchema, blockUserSchema,
catalogSchema,
collectionsSchema,
contactValidateSchema, contactValidateSchema,
deleteMessageSchema, deleteMessageSchema,
markChatUnreadSchema, markChatUnreadSchema,
@ -267,6 +269,28 @@ export class ChatRouter extends RouterBroker {
}); });
return res.status(HttpStatus.CREATED).json(response); return res.status(HttpStatus.CREATED).json(response);
})
.post(this.routerPath('fetchCatalog'), ...guards, async (req, res) => {
const response = await this.dataValidate<NumberDto>({
request: req,
schema: catalogSchema,
ClassRef: NumberDto,
execute: (instance, data) => chatController.fetchCatalog(instance, data),
});
return res.status(HttpStatus.OK).json(response);
})
.post(this.routerPath('fetchCollections'), ...guards, async (req, res) => {
const response = await this.dataValidate<NumberDto>({
request: req,
schema: collectionsSchema,
ClassRef: NumberDto,
execute: (instance, data) => chatController.fetchCatalogCollections(instance, data),
});
return res.status(HttpStatus.OK).json(response);
}); });
} }

View File

@ -315,3 +315,21 @@ export const profileSchema: JSONSchema7 = {
isBusiness: { type: 'boolean' }, isBusiness: { type: 'boolean' },
}, },
}; };
export const catalogSchema: JSONSchema7 = {
type: 'object',
properties: {
number: { type: 'string' },
limit: { type: 'number' },
cursor: { type: 'string' },
},
};
export const collectionsSchema: JSONSchema7 = {
type: 'object',
properties: {
number: { type: 'string' },
limit: { type: 'number' },
cursor: { type: 'string' },
},
};