feat: Added fetch profile endpoint in chat controller and link preview option in send text message

This commit is contained in:
Davidson Gomes 2023-07-23 22:24:21 -03:00
parent 9f52f20660
commit 798eb90bed
7 changed files with 176 additions and 35 deletions

View File

@ -3,6 +3,11 @@
### Features
* Added connection functionality via pairing code
* Added fetch profile endpoint in chat controller
### Fixed
* Added link preview option in send text message
# 1.3.2 (2023-07-21 17:19)

View File

@ -588,6 +588,17 @@ export const profilePictureSchema: JSONSchema7 = {
},
};
export const profileSchema: JSONSchema7 = {
type: 'object',
properties: {
wuid: { type: 'string' },
name: { type: 'string' },
picture: { type: 'string' },
status: { type: 'string' },
isBusiness: { type: 'boolean' },
},
};
export const messageValidateSchema: JSONSchema7 = {
$id: v4(),
type: 'object',

View File

@ -48,6 +48,14 @@ export class ChatController {
return await this.waMonitor.waInstances[instanceName].profilePicture(data.number);
}
public async fetchProfile({ instanceName }: InstanceDto, data: NumberDto) {
logger.verbose('requested fetchProfile from ' + instanceName + ' instance');
return await this.waMonitor.waInstances[instanceName].fetchProfile(
instanceName,
data.number,
);
}
public async fetchContacts({ instanceName }: InstanceDto, query: ContactQuery) {
logger.verbose('requested fetchContacts from ' + instanceName + ' instance');
return await this.waMonitor.waInstances[instanceName].fetchContacts(query);

View File

@ -210,30 +210,41 @@ export class InstanceController {
this.logger.verbose('state: ' + state);
switch (state) {
case 'close':
this.logger.verbose('connecting');
await instance.connectToWhatsapp();
let pairingCode = null;
if (number) {
this.logger.verbose('creating pairing code');
await delay(5000);
pairingCode = await instance.client.requestPairingCode(number);
}
if (pairingCode) {
return {
pairingCode,
};
}
await delay(2000);
return instance.qrCode;
case 'connecting':
return instance.qrCode;
default:
return await this.connectionState({ instanceName });
if (state == 'open') {
return await this.connectionState({ instanceName });
}
if (state == 'connecting') {
return instance.qrCode;
}
if (state == 'close') {
this.logger.verbose('connecting');
await instance.connectToWhatsapp();
let pairingCode = null;
if (number) {
this.logger.verbose('creating pairing code');
await delay(5000);
pairingCode = await instance.client.requestPairingCode(number);
}
if (pairingCode) {
return {
pairingCode,
};
}
await delay(2000);
return instance.qrCode;
}
return {
instance: {
instanceName: instanceName,
status: state,
},
qrcode: instance?.qrCode,
};
} catch (error) {
this.logger.error(error);
}

View File

@ -26,6 +26,19 @@ export class NumberDto {
number: string;
}
export class NumberBusiness {
wid?: string;
jid?: string;
exists?: boolean;
isBusiness: boolean;
name?: string;
message?: string;
description?: string;
email?: string;
website?: string[];
address?: string;
}
export class ProfileNameDto {
name: string;
}

View File

@ -8,6 +8,7 @@ import {
privacySettingsSchema,
profileNameSchema,
profilePictureSchema,
profileSchema,
profileStatusSchema,
readMessageSchema,
whatsappNumberSchema,
@ -129,6 +130,23 @@ export class ChatRouter extends RouterBroker {
return res.status(HttpStatus.OK).json(response);
})
.post(this.routerPath('fetchProfile'), ...guards, async (req, res) => {
logger.verbose('request received in fetchProfile');
logger.verbose('request body: ');
logger.verbose(req.body);
logger.verbose('request query: ');
logger.verbose(req.query);
const response = await this.dataValidate<NumberDto>({
request: req,
schema: profileSchema,
ClassRef: NumberDto,
execute: (instance, data) => chatController.fetchProfile(instance, data),
});
return res.status(HttpStatus.OK).json(response);
})
.post(this.routerPath('findContacts'), ...guards, async (req, res) => {
logger.verbose('request received in findContacts');
logger.verbose('request body: ');

View File

@ -84,6 +84,7 @@ import { arrayUnique, isBase64, isURL } from 'class-validator';
import {
ArchiveChatDto,
DeleteMessage,
NumberBusiness,
OnWhatsAppDto,
PrivacySettingDto,
ReadMessageDto,
@ -1449,6 +1450,78 @@ export class WAStartupService {
}
}
public async getStatus(number: string) {
const jid = this.createJid(number);
this.logger.verbose('Getting profile status with jid:' + jid);
try {
this.logger.verbose('Getting status');
return {
wuid: jid,
status: (await this.client.fetchStatus(jid))?.status,
};
} catch (error) {
this.logger.verbose('Status not found');
return {
wuid: jid,
status: null,
};
}
}
public async fetchProfile(instanceName: string, number?: string) {
const jid = number ? this.createJid(number) : this.client?.user?.id;
this.logger.verbose('Getting profile with jid: ' + jid);
try {
this.logger.verbose('Getting profile info');
const info = await waMonitor.instanceInfo(instanceName);
const business = await this.fetchBusinessProfile(jid);
if (number) {
const info = (await this.whatsappNumber({ numbers: [jid] }))?.shift();
const picture = await this.profilePicture(jid);
const status = await this.getStatus(jid);
return {
wuid: jid,
name: info?.name,
numberExists: info?.exists,
picture: picture?.profilePictureUrl,
status: status?.status,
isBusiness: business.isBusiness,
email: business?.email,
description: business?.description,
website: business?.website?.shift(),
};
} else {
const info = await waMonitor.instanceInfo(instanceName);
return {
wuid: jid,
name: info?.instance?.profileName,
numberExists: true,
picture: info?.instance?.profilePictureUrl,
status: info?.instance?.profileStatus,
isBusiness: business.isBusiness,
email: business?.email,
description: business?.description,
website: business?.website?.shift(),
};
}
} catch (error) {
this.logger.verbose('Profile not found');
return {
wuid: jid,
name: null,
picture: null,
status: null,
os: null,
isBusiness: false,
};
}
}
private async sendMessageWithTyping<T = proto.IMessage>(
number: string,
message: T,
@ -1485,7 +1558,9 @@ export class WAStartupService {
this.logger.verbose('Sending presence update: paused');
}
let linkPreview = (options?.linkPreview != false) ? undefined : false;
const linkPreview = options?.linkPreview != false ? undefined : false;
console.log('linkPreview', linkPreview);
let quoted: WAMessage;
@ -2468,29 +2543,29 @@ export class WAStartupService {
}
}
public async fetchBusinessProfile(number: string) {
public async fetchBusinessProfile(number: string): Promise<NumberBusiness> {
this.logger.verbose('Fetching business profile');
try {
let jid;
if (!number) {
jid = this.instance.wuid;
} else {
jid = this.createJid(number);
}
const jid = number ? this.createJid(number) : this.instance.wuid;
const profile = await this.client.getBusinessProfile(jid);
this.logger.verbose('Trying to get business profile');
if (!profile) {
const info = await this.whatsappNumber({ numbers: [jid] });
return {
exists: false,
message: 'Business profile not found',
isBusiness: false,
message: 'Not is business profile',
...info?.shift(),
};
}
this.logger.verbose('Business profile fetched');
return profile;
return {
isBusiness: true,
...profile,
};
} catch (error) {
throw new InternalServerErrorException(
'Error updating profile name',