diff --git a/src/api/contacts.controller.ts b/src/api/contacts.controller.ts
new file mode 100644
index 00000000..d85aa59a
--- /dev/null
+++ b/src/api/contacts.controller.ts
@@ -0,0 +1,54 @@
+import {Body, Controller, Get, Post, Query} from '@nestjs/common';
+import {ApiOperation, ApiSecurity, ApiTags} from "@nestjs/swagger";
+import {SessionManager} from "../core/abc/manager.abc";
+import {ContactQuery, ContactRequest} from "../structures/contacts.dto";
+import {SessionQuery} from "../structures/base.dto";
+
+@ApiSecurity('api_key')
+@Controller('api/contacts')
+@ApiTags('contacts')
+export class ContactsController {
+ constructor(private manager: SessionManager) {
+ }
+
+ @Get('/')
+ @ApiOperation({summary: 'Get contact basic info'})
+ get(@Query() query: ContactQuery) {
+ const whatsapp = this.manager.getSession(query.session)
+ return whatsapp.getContact(query)
+ }
+
+ @Get('/all')
+ @ApiOperation({summary: 'Get all contacts'})
+ getAll(@Query() query: SessionQuery) {
+ const whatsapp = this.manager.getSession(query.session)
+ return whatsapp.getContacts()
+ }
+
+ @Get('/about')
+ @ApiOperation({summary: 'Gets the Contact\'s current "about" info. Returns null if you don\'t have permission to read their status.'})
+ getAbout(@Query() query: ContactQuery) {
+ const whatsapp = this.manager.getSession(query.session)
+ return whatsapp.getContactAbout(query)
+ }
+
+ @Get('/profile-picture')
+ @ApiOperation({summary: 'Returns the contact\'s profile picture URL, if privacy settings allow it.'})
+ getProfilePicture(@Query() query: ContactQuery) {
+ const whatsapp = this.manager.getSession(query.session)
+ return whatsapp.getContactProfilePicture(query)
+ }
+
+ @Post('/block')
+ @ApiOperation({summary:"Block contact"})
+ block(@Body() request: ContactRequest) {
+ const whatsapp = this.manager.getSession(request.session)
+ return whatsapp.blockContact(request)
+ }
+ @Post('/unblock')
+ @ApiOperation({summary:"Unblock contact"})
+ unblock(@Body() request: ContactRequest) {
+ const whatsapp = this.manager.getSession(request.session)
+ return whatsapp.unblockContact(request)
+ }
+}
diff --git a/src/api/screenshot.controller.ts b/src/api/screenshot.controller.ts
index 8ee95893..7aef0bc8 100644
--- a/src/api/screenshot.controller.ts
+++ b/src/api/screenshot.controller.ts
@@ -2,8 +2,8 @@ import {Controller, Get, Query, Res} from '@nestjs/common';
import {ApiSecurity, ApiTags} from "@nestjs/swagger";
import {Readable} from "stream";
import {Response} from 'express';
-import {SessionQuery} from "../structures/chatting.dto";
import {SessionManager} from "../core/abc/manager.abc";
+import {SessionQuery} from "../structures/base.dto";
@ApiSecurity('api_key')
diff --git a/src/core/abc/session.abc.ts b/src/core/abc/session.abc.ts
index 91a07726..bece051f 100644
--- a/src/core/abc/session.abc.ts
+++ b/src/core/abc/session.abc.ts
@@ -16,6 +16,8 @@ import {
} from "../../structures/chatting.dto";
import {MediaStorage} from "./storage.abc";
import {MessageId} from "whatsapp-web.js";
+import {ContactQuery, ContactRequest} from "../../structures/contacts.dto";
+import {NotImplementedByEngineError} from "../exceptions";
export abstract class WhatsappSession {
public status: WhatsappStatus;
@@ -26,7 +28,7 @@ export abstract class WhatsappSession {
this.log = log
}
- getBrowserExecutablePath(){
+ getBrowserExecutablePath() {
return "/usr/bin/google-chrome-stable"
}
@@ -103,6 +105,34 @@ export abstract class WhatsappSession {
abstract setReaction(request: MessageReactionRequest)
+ /**
+ * Contacts methods
+ */
+ public getContact(query: ContactQuery) {
+ throw new NotImplementedByEngineError()
+ }
+
+ public getContacts() {
+ throw new NotImplementedByEngineError()
+ }
+
+ public getContactAbout(query: ContactQuery) {
+ throw new NotImplementedByEngineError()
+ }
+
+ public getContactProfilePicture(query: ContactQuery) {
+ throw new NotImplementedByEngineError()
+ }
+
+ public blockContact(request: ContactRequest) {
+ throw new NotImplementedByEngineError()
+ }
+
+ public unblockContact(request: ContactRequest) {
+ throw new NotImplementedByEngineError()
+ }
+
+
/**
* END - Methods for API
*/
diff --git a/src/core/app.module.core.ts b/src/core/app.module.core.ts
index f089c7a4..d10da38e 100644
--- a/src/core/app.module.core.ts
+++ b/src/core/app.module.core.ts
@@ -5,6 +5,7 @@ import {WhatsappConfigService} from "../config.service";
import {ServeStaticModule} from "@nestjs/serve-static";
import {SessionsController} from "../api/sessions.controller";
import {ChattingController} from "../api/chatting.controller";
+import {ContactsController} from "../api/contacts.controller";
import {VersionController} from "../api/version.controller";
import {PassportModule} from "@nestjs/passport";
import {SessionManager} from "./abc/manager.abc";
@@ -30,6 +31,7 @@ export const IMPORTS = [
export const CONTROLLERS = [
SessionsController,
ChattingController,
+ ContactsController,
ScreenshotController,
VersionController,
]
diff --git a/src/core/session.venom.core.ts b/src/core/session.venom.core.ts
index 689b1190..8966dad1 100644
--- a/src/core/session.venom.core.ts
+++ b/src/core/session.venom.core.ts
@@ -20,6 +20,7 @@ import {NotImplementedByEngineError} from "./exceptions";
import {MediaStorage} from "./abc/storage.abc";
import {UnprocessableEntityException} from "@nestjs/common/exceptions/unprocessable-entity.exception";
import {ConsoleLogger} from "@nestjs/common";
+import {ContactQuery} from "../structures/contacts.dto";
class QR {
private base64: string;
diff --git a/src/core/session.webjs.core.ts b/src/core/session.webjs.core.ts
index f39c3a9d..970a724c 100644
--- a/src/core/session.webjs.core.ts
+++ b/src/core/session.webjs.core.ts
@@ -1,5 +1,5 @@
import {UnprocessableEntityException} from "@nestjs/common/exceptions/unprocessable-entity.exception";
-import {Buttons, Chat, Client, Events, Message} from "whatsapp-web.js";
+import {Buttons, Chat, Client, Contact, Events, Message} from "whatsapp-web.js";
import {Message as MessageInstance} from "whatsapp-web.js/src/structures"
import {WAEvents, WhatsappStatus} from "../structures/enums.dto";
import {WhatsappSession} from "./abc/session.abc";
@@ -19,6 +19,7 @@ import {
MessageVoiceRequest
} from "../structures/chatting.dto";
import {AvailableInPlusVersion, NotImplementedByEngineError} from "./exceptions";
+import {ContactQuery, ContactRequest} from "../structures/contacts.dto";
// eslint-disable-next-line @typescript-eslint/no-var-requires
const qrcode = require('qrcode-terminal');
@@ -144,6 +145,38 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
return message.react(request.reaction)
}
+
+ /**
+ * Contacts methods
+ */
+ getContact(query: ContactQuery) {
+ return this.whatsapp.getContactById(this.ensureSuffix(query.contactId)).then(this.toWAContact)
+ }
+
+ getContacts() {
+ return this.whatsapp.getContacts().then(contacts => contacts.map(this.toWAContact))
+ }
+
+ public async getContactAbout(query: ContactQuery) {
+ const contact = await this.whatsapp.getContactById(this.ensureSuffix(query.contactId))
+ return {"about": await contact.getAbout()}
+ }
+
+ public async getContactProfilePicture(query: ContactQuery) {
+ const contact = await this.whatsapp.getContactById(this.ensureSuffix(query.contactId))
+ return {"profilePictureURL": await contact.getProfilePicUrl()}
+ }
+
+ public async blockContact(request: ContactRequest) {
+ const contact = await this.whatsapp.getContactById(this.ensureSuffix(request.contactId))
+ await contact.block()
+ }
+
+ public async unblockContact(request: ContactRequest) {
+ const contact = await this.whatsapp.getContactById(this.ensureSuffix(request.contactId))
+ await contact.unblock()
+ }
+
/**
* END - Methods for API
*/
@@ -192,6 +225,12 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
})
}
+ protected toWAContact(contact: Contact) {
+ // @ts-ignore
+ contact.id = contact.id._serialized
+ return contact
+ }
+
protected async downloadMedia(message: Message) {
if (!message.hasMedia) {
return message
@@ -202,6 +241,5 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
return message
}
-
}
diff --git a/src/core/swagger.module.core.ts b/src/core/swagger.module.core.ts
index e92b0dfd..f593e515 100644
--- a/src/core/swagger.module.core.ts
+++ b/src/core/swagger.module.core.ts
@@ -3,7 +3,7 @@ import {INestApplication} from "@nestjs/common";
import {VERSION} from "../version";
export class SwaggerModuleCore {
- configure(app: INestApplication){
+ configure(app: INestApplication) {
this.setUpAuth(app)
const options = new DocumentBuilder()
@@ -11,10 +11,16 @@ export class SwaggerModuleCore {
.setDescription('WhatsApp HTTP API that you can configure in a click!')
.setExternalDoc("Documentation", "https://waha.devlike.pro/")
.setVersion(VERSION.version)
- .addTag('sessions', 'Control your WhatsApp sessions')
+ .addTag('sessions', 'Control WhatsApp sessions')
.addTag('screenshot', 'Get screenshot of WhatsApp and show QR code')
.addTag('chatting', 'Chat methods')
- .addTag('other', 'Other endpoints')
+ .addTag(
+ 'contacts',
+ `Contacts methods.
+ Use phone number (without +) or phone number and \`@c.us\` at the end as \`contactId\`.
+ 'E.g: \`12312312310\` OR \`12312312310@c.us\`
`
+ )
+ .addTag('other', 'Other methods')
.addApiKey({
type: 'apiKey',
description: 'Your secret api key',
@@ -27,6 +33,7 @@ export class SwaggerModuleCore {
SwaggerModule.setup('', app, document);
}
+
protected setUpAuth(app: INestApplication) {
return undefined
}
diff --git a/src/structures/base.dto.ts b/src/structures/base.dto.ts
new file mode 100644
index 00000000..5c906927
--- /dev/null
+++ b/src/structures/base.dto.ts
@@ -0,0 +1,19 @@
+import {IsNotEmpty} from "class-validator";
+
+export const WHATSAPP_DEFAULT_SESSION_NAME = "default"
+
+/**
+ * Queries
+ */
+export class SessionQuery {
+ @IsNotEmpty()
+ session: string = WHATSAPP_DEFAULT_SESSION_NAME;
+}
+
+/**
+ * Requests
+ */
+
+export class SessionBaseRequest {
+ session = WHATSAPP_DEFAULT_SESSION_NAME
+}
diff --git a/src/structures/chatting.dto.ts b/src/structures/chatting.dto.ts
index 21766054..ab9d892d 100644
--- a/src/structures/chatting.dto.ts
+++ b/src/structures/chatting.dto.ts
@@ -1,17 +1,11 @@
import {IsNotEmpty, IsString} from "class-validator";
import {ApiExtraModels, ApiProperty, getSchemaPath} from "@nestjs/swagger";
-
-export const WHATSAPP_DEFAULT_SESSION_NAME = "default"
+import {SessionBaseRequest, SessionQuery} from "./base.dto";
/**
* Queries
*/
-export class SessionQuery {
- @IsNotEmpty()
- session: string = WHATSAPP_DEFAULT_SESSION_NAME;
-}
-
export class CheckNumberStatusQuery extends SessionQuery {
@IsString()
phone: string
@@ -28,11 +22,6 @@ export class MessageTextQuery extends SessionQuery {
/**
* Requests
*/
-
-export class SessionBaseRequest {
- session = WHATSAPP_DEFAULT_SESSION_NAME
-}
-
export class ChatRequest extends SessionBaseRequest {
@ApiProperty({
example: '11111111111@c.us',
diff --git a/src/structures/contacts.dto.ts b/src/structures/contacts.dto.ts
new file mode 100644
index 00000000..af418984
--- /dev/null
+++ b/src/structures/contacts.dto.ts
@@ -0,0 +1,22 @@
+import {IsString} from "class-validator";
+import {SessionBaseRequest, SessionQuery, WHATSAPP_DEFAULT_SESSION_NAME} from "./base.dto";
+
+
+/**
+ * Queries
+ */
+
+export class ContactQuery extends SessionQuery {
+ @IsString()
+ contactId: string
+}
+
+
+/**
+ * Requests
+ */
+
+export class ContactRequest extends SessionBaseRequest {
+ @IsString()
+ contactId: string
+}