Skip to content

Commit fb63774

Browse files
Merge pull request #237 from gabrielpastori1/add-send-presence
Add sendPresence
2 parents 9a5dbe0 + 42dd280 commit fb63774

File tree

7 files changed

+91
-3
lines changed

7 files changed

+91
-3
lines changed

.vscode/settings.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
"editor.smoothScrolling": true,
66
"editor.tabSize": 2,
77
"editor.codeActionsOnSave": {
8-
"source.fixAll.eslint": true,
9-
"source.fixAll": true
8+
"source.fixAll.eslint": "explicit",
9+
"source.fixAll": "explicit"
1010
},
1111
"prisma-smart-formatter.typescript.defaultFormatter": "esbenp.prettier-vscode",
1212
"prisma-smart-formatter.prisma.defaultFormatter": "Prisma.prisma"

src/validate/validate.schema.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,16 @@ export const textMessageSchema: JSONSchema7 = {
149149
required: ['textMessage', 'number'],
150150
};
151151

152+
export const presenceSchema: JSONSchema7 = {
153+
$id: v4(),
154+
type: 'object',
155+
properties: {
156+
number: { ...numberDefinition },
157+
options: { ...optionsSchema, required: ['presence', 'delay'] },
158+
},
159+
required: ['options', 'number'],
160+
};
161+
152162
export const pollMessageSchema: JSONSchema7 = {
153163
$id: v4(),
154164
type: 'object',

src/whatsapp/controllers/chat.controller.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
ProfilePictureDto,
1010
ProfileStatusDto,
1111
ReadMessageDto,
12+
SendPresenceDto,
1213
WhatsAppNumberDto,
1314
} from '../dto/chat.dto';
1415
import { InstanceDto } from '../dto/instance.dto';
@@ -77,6 +78,11 @@ export class ChatController {
7778
return await this.waMonitor.waInstances[instanceName].fetchChats();
7879
}
7980

81+
public async sendPresence({ instanceName }: InstanceDto, data: SendPresenceDto) {
82+
logger.verbose('requested sendPresence from ' + instanceName + ' instance');
83+
return await this.waMonitor.waInstances[instanceName].sendPresence(data);
84+
}
85+
8086
public async fetchPrivacySettings({ instanceName }: InstanceDto) {
8187
logger.verbose('requested fetchPrivacySettings from ' + instanceName + ' instance');
8288
return await this.waMonitor.waInstances[instanceName].fetchPrivacySettings();

src/whatsapp/dto/chat.dto.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { proto, WAPrivacyOnlineValue, WAPrivacyValue, WAReadReceiptsValue } from '@whiskeysockets/baileys';
1+
import { proto, WAPresence, WAPrivacyOnlineValue, WAPrivacyValue, WAReadReceiptsValue } from '@whiskeysockets/baileys';
22

33
export class OnWhatsAppDto {
44
constructor(public readonly jid: string, public readonly exists: boolean, public readonly name?: string) {}
@@ -83,3 +83,20 @@ export class DeleteMessage {
8383
remoteJid: string;
8484
participant?: string;
8585
}
86+
export class Options {
87+
delay?: number;
88+
presence?: WAPresence;
89+
}
90+
class OptionsMessage {
91+
options: Options;
92+
}
93+
export class Metadata extends OptionsMessage {
94+
number: string;
95+
}
96+
97+
export class SendPresenceDto extends Metadata {
98+
options: {
99+
presence: WAPresence;
100+
delay: number;
101+
};
102+
}

src/whatsapp/dto/sendMessage.dto.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,13 @@ class PollMessage {
4646
values: string[];
4747
messageSecret?: Uint8Array;
4848
}
49+
4950
export class SendTextDto extends Metadata {
5051
textMessage: TextMessage;
5152
}
53+
export class SendPresence extends Metadata {
54+
textMessage: TextMessage;
55+
}
5256

5357
export class SendStatusDto extends Metadata {
5458
statusMessage: StatusMessage;

src/whatsapp/routers/chat.router.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
deleteMessageSchema,
88
messageUpSchema,
99
messageValidateSchema,
10+
presenceSchema,
1011
privacySettingsSchema,
1112
profileNameSchema,
1213
profilePictureSchema,
@@ -26,6 +27,7 @@ import {
2627
ProfilePictureDto,
2728
ProfileStatusDto,
2829
ReadMessageDto,
30+
SendPresenceDto,
2931
WhatsAppNumberDto,
3032
} from '../dto/chat.dto';
3133
import { InstanceDto } from '../dto/instance.dto';
@@ -228,6 +230,22 @@ export class ChatRouter extends RouterBroker {
228230

229231
return res.status(HttpStatus.OK).json(response);
230232
})
233+
.post(this.routerPath('sendPresence'), ...guards, async (req, res) => {
234+
logger.verbose('request received in sendPresence');
235+
logger.verbose('request body: ');
236+
logger.verbose(req.body);
237+
238+
logger.verbose('request query: ');
239+
logger.verbose(req.query);
240+
const response = await this.dataValidate<null>({
241+
request: req,
242+
schema: presenceSchema,
243+
ClassRef: SendPresenceDto,
244+
execute: (instance, data) => chatController.sendPresence(instance, data),
245+
});
246+
247+
return res.status(HttpStatus.CREATED).json(response);
248+
})
231249
// Profile routes
232250
.get(this.routerPath('fetchPrivacySettings'), ...guards, async (req, res) => {
233251
logger.verbose('request received in fetchPrivacySettings');

src/whatsapp/services/whatsapp.service.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ import {
8484
OnWhatsAppDto,
8585
PrivacySettingDto,
8686
ReadMessageDto,
87+
SendPresenceDto,
8788
WhatsAppNumberDto,
8889
} from '../dto/chat.dto';
8990
import {
@@ -2409,6 +2410,38 @@ export class WAStartupService {
24092410
return this.stateConnection;
24102411
}
24112412

2413+
public async sendPresence(data: SendPresenceDto) {
2414+
try {
2415+
const { number } = data;
2416+
2417+
this.logger.verbose(`Check if number "${number}" is WhatsApp`);
2418+
const isWA = (await this.whatsappNumber({ numbers: [number] }))?.shift();
2419+
2420+
this.logger.verbose(`Exists: "${isWA.exists}" | jid: ${isWA.jid}`);
2421+
if (!isWA.exists && !isJidGroup(isWA.jid) && !isWA.jid.includes('@broadcast')) {
2422+
throw new BadRequestException(isWA);
2423+
}
2424+
2425+
const sender = isWA.jid;
2426+
2427+
this.logger.verbose('Sending presence');
2428+
await this.client.presenceSubscribe(sender);
2429+
this.logger.verbose('Subscribing to presence');
2430+
2431+
await this.client.sendPresenceUpdate(data.options?.presence ?? 'composing', sender);
2432+
this.logger.verbose('Sending presence update: ' + data.options?.presence ?? 'composing');
2433+
2434+
await delay(data.options.delay);
2435+
this.logger.verbose('Set delay: ' + data.options.delay);
2436+
2437+
await this.client.sendPresenceUpdate('paused', sender);
2438+
this.logger.verbose('Sending presence update: paused');
2439+
} catch (error) {
2440+
this.logger.error(error);
2441+
throw new BadRequestException(error.toString());
2442+
}
2443+
}
2444+
24122445
// Send Message Controller
24132446
public async textMessage(data: SendTextDto, isChatwoot = false) {
24142447
this.logger.verbose('Sending text message');

0 commit comments

Comments
 (0)