diff --git a/docs/site/content/en/docs/how-to/engines/index.md b/docs/site/content/en/docs/how-to/engines/index.md index d1b830b4..62efef5d 100644 --- a/docs/site/content/en/docs/how-to/engines/index.md +++ b/docs/site/content/en/docs/how-to/engines/index.md @@ -128,26 +128,26 @@ please [create an issue](https://github.com/devlikeapro/whatsapp-http-api/issues | **Screenshot** | | | | | `POST /api/screenshot` | ✔️ | ➖ | ✔️ | -| **Chatting** | WEBJS | NOWEB | VENOM | -|-----------------------------------------------------|:-----:|:-----:|:-----:| -| `GET /api/checkNumberStatus` | ✔️ | ✔️ | ✔️ | -| `GET /api/sendContactVcard` | ➖ | ➖ | ✔️ | -| `GET /api/sendText` | ✔️ | ✔️ | ✔️ | -| `POST /api/sendText` | ✔️ | ✔️ | ✔️ | -| `POST /api/sendPoll` | ➖ | ✔️ | ➖ | -| `POST /api/sendLocation` | ✔️ | ✔️ | ✔️ | -| `POST /api/sendLinkPreview` | ➖ | ✔️ | ✔️ | +| **Chatting** | WEBJS | NOWEB | VENOM | +|------------------------------------------------------|:-----:|:-----:|:-----:| +| `GET /api/checkNumberStatus` | ✔️ | ✔️ | ✔️ | +| `GET /api/sendContactVcard` | ➖ | ✔️ | ➖ | +| `GET /api/sendText` | ✔️ | ✔️ | ✔️ | +| `POST /api/sendText` | ✔️ | ✔️ | ✔️ | +| `POST /api/sendPoll` | ➖ | ✔️ | ➖ | +| `POST /api/sendLocation` | ✔️ | ✔️ | ✔️ | +| `POST /api/sendLinkPreview` | ➖ | ✔️ | ✔️ | | `POST /api/sendImage` ![](/images/versions/plus.png) | ✔️ | ✔️ | ✔️ | -| `POST /api/sendFile` ![](/images/versions/plus.png) | ✔️ | ✔️ | ✔️ | +| `POST /api/sendFile` ![](/images/versions/plus.png) | ✔️ | ✔️ | ✔️ | | `POST /api/sendVoice` ![](/images/versions/plus.png) | ✔️ | ✔️ | ✔️ | | `POST /api/sendVideo` ![](/images/versions/plus.png) | ✔️ | ✔️ | ➖ | -| `POST /api/reply` | ✔️ | ✔️ | ✔️ | -| `POST /api/sendSeen` | ✔️ | ✔️ | ✔️ | -| `POST /api/startTyping` | ✔️ | ✔️ | ✔️ | -| `POST /api/stopTyping` | ✔️ | ✔️ | ➖ | -| `POST /api/reaction` | ✔️ | ✔️ | ➖ | -| `POST /api/star` | ✔️ | ✔️ | ➖ | -| `GET /api/messages` | ✔️ | ➖ | ✔️ | +| `POST /api/reply` | ✔️ | ✔️ | ✔️ | +| `POST /api/sendSeen` | ✔️ | ✔️ | ✔️ | +| `POST /api/startTyping` | ✔️ | ✔️ | ✔️ | +| `POST /api/stopTyping` | ✔️ | ✔️ | ➖ | +| `POST /api/reaction` | ✔️ | ✔️ | ➖ | +| `POST /api/star` | ✔️ | ✔️ | ➖ | +| `GET /api/messages` | ✔️ | ➖ | ✔️ | | | WEBJS | NOWEB | VENOM | |-------------------------------------------------------------------|:-----:|:-----:|:-----:| diff --git a/docs/site/content/en/docs/how-to/send-messages/index.md b/docs/site/content/en/docs/how-to/send-messages/index.md index 7a3ef156..a77e2c35 100644 --- a/docs/site/content/en/docs/how-to/send-messages/index.md +++ b/docs/site/content/en/docs/how-to/send-messages/index.md @@ -141,6 +141,58 @@ Use `PUT /api/star` method to star or unstar a message. } ``` +### Send contact (vcard) +Use `POST /api/sendContactVcard` to send contact (vcard). + +You can use fields this way: +```json +{ + "session": "default", + "chatId": "79111111@c.us", + "contacts": [ + { + "fullName": "John Doe", + "organization": "Company Name", + "phoneNumber": "+91 11111 11111", + "whatsappId": "911111111111" + } + ] +} +``` + +Or provide a vCard file content: +```json +{ + "session": "default", + "chatId": "79111111@c.us", + "contacts": [ + { + "vcard": "BEGIN:VCARD\nVERSION:3.0\nFN:Jane Doe\nORG:Company Name;\nTEL;type=CELL;type=VOICE;waid=911111111111:+91 11111 11111\nEND:VCARD" + } + ] +} +``` + +Or even combine it: +```json + { + "chatId": "79111111@c.us", + "contacts": [ + { + "vcard": "BEGIN:VCARD\nVERSION:3.0\nFN:Jane Doe\nORG:Company Name;\nTEL;type=CELL;type=VOICE;waid=911111111111:+91 11111 11111\nEND:VCARD" + }, + { + "fullName": "John Doe", + "organization": "Company Name", + "phoneNumber": "+91 11111 11111", + "whatsappId": "911111111111" + } + ], + "session": "default" +} +``` + + ### Send image ![](/images/versions/plus.png) diff --git a/docs/site/content/en/docs/overview/changelog.md b/docs/site/content/en/docs/overview/changelog.md index 8b5017db..c46ea9f4 100644 --- a/docs/site/content/en/docs/overview/changelog.md +++ b/docs/site/content/en/docs/overview/changelog.md @@ -24,29 +24,35 @@ You even can **subscribe to get new updates** there! ---- -- Handles `caption` right in `POST /api/sendFile` - - Issue: [#94](https://github.com/devlikeapro/whatsapp-http-api/issues/94) - - Issue: [#133](https://github.com/devlikeapro/whatsapp-http-api/issues/133) +Add `POST /api/sendContactVcard` support for **NOWEB** engine. +- Read more about [Send Contact vCard]({{< relref "/docs/how-to/send-messages#send-contact-vcard" >}}) +- Issue: [#276](https://github.com/devlikeapro/whatsapp-http-api/issues/256) ---- -- Add `message.reaction` webhook in **WEBJS** and **NOWEB** engines - - Read more about [message.reaction]({{< relref "/docs/how-to/webhooks#messagereaction" >}}) event - - Issue: [#275](https://github.com/devlikeapro/whatsapp-http-api/issues/275) - -**NOWEB** engine note - reactions were sent in `'message'` and `'message.any'` events, not it's available **only** in `'message.reaction'`! +Handles `caption` and `filename` right in `POST /api/sendFile` +- Issue: [#94](https://github.com/devlikeapro/whatsapp-http-api/issues/94) +- Issue: [#133](https://github.com/devlikeapro/whatsapp-http-api/issues/133) ---- -- Add security settings for who can send messages `PUT /api/{session}/groups/{groupId}/settings/security/messages-admin-only` - - Read [Security - who can send messages]({{< relref "/docs/how-to/groups##security---who-can-send-messages" >}}) - - Issue: [#274](https://github.com/devlikeapro/whatsapp-http-api/issues/274) +Add `message.reaction` webhook in **WEBJS** and **NOWEB** engines +- Read more about [message.reaction]({{< relref "/docs/how-to/webhooks#messagereaction" >}}) event +- Issue: [#275](https://github.com/devlikeapro/whatsapp-http-api/issues/275) + +👉 **NOWEB** engine note - reactions were sent in `'message'` and `'message.any'` events, not it's available **only** in `'message.reaction'`! ---- -- Add star and unstar message endpoint `PUT /api/star` - - Read [Star and unstar message]({{< relref "/docs/how-to/send-messages#star-and-unstar-message" >}}) documentation - - Issue: [#273](https://github.com/devlikeapro/whatsapp-http-api/issues/240) +Add security settings for who can send messages `PUT /api/{session}/groups/{groupId}/settings/security/messages-admin-only` +- Read [Security - who can send messages]({{< relref "/docs/how-to/groups##security---who-can-send-messages" >}}) +- Issue: [#274](https://github.com/devlikeapro/whatsapp-http-api/issues/274) + +---- + +Add star and unstar message endpoint `PUT /api/star` +- Read [Star and unstar message]({{< relref "/docs/how-to/send-messages#star-and-unstar-message" >}}) documentation +- Issue: [#273](https://github.com/devlikeapro/whatsapp-http-api/issues/240) ---- @@ -59,6 +65,8 @@ You even can **subscribe to get new updates** there! } ``` +- `POST /api/sendContactVcard` doesn't work in **VENOM** anymore (use **NOWEB** engine). + ## 2024.2 - Add support for [MongoDB as storage for Session data]({{< relref "/docs/how-to/storages" >}}) - Support persistent file storage for media files - [now you can save media files between container restarts]({{< relref "/docs/how-to/storages#media" >}}) diff --git a/src/api/groups.controller.ts b/src/api/groups.controller.ts index f0da8681..7e4f81d5 100644 --- a/src/api/groups.controller.ts +++ b/src/api/groups.controller.ts @@ -11,7 +11,6 @@ import { ApiOperation, ApiSecurity, ApiTags } from '@nestjs/swagger'; import { SessionManager } from '../core/abc/manager.abc'; import { WhatsappSession } from '../core/abc/session.abc'; -import { MessageContactVcardRequest } from '../structures/chatting.dto'; import { CreateGroupRequest, DescriptionRequest, diff --git a/src/core/engines/noweb/session.noweb.core.ts b/src/core/engines/noweb/session.noweb.core.ts index 7f49d24c..f27893b5 100644 --- a/src/core/engines/noweb/session.noweb.core.ts +++ b/src/core/engines/noweb/session.noweb.core.ts @@ -15,6 +15,7 @@ import makeWASocket, { } from '@adiwajshing/baileys'; import { UnprocessableEntityException } from '@nestjs/common'; import * as Buffer from 'buffer'; +import { request } from 'express'; import * as fs from 'fs/promises'; import { Agent } from 'https'; import * as lodash from 'lodash'; @@ -24,6 +25,7 @@ import { flipObject, splitAt } from '../../../helpers'; import { ChatRequest, CheckNumberStatusQuery, + MessageContactVcardRequest, MessageDestination, MessageFileRequest, MessageImageRequest, @@ -77,6 +79,7 @@ import { AvailableInPlusVersion, NotImplementedByEngineError, } from '../../exceptions'; +import { toVcard } from '../../helpers'; import { createAgentProxy } from '../../helpers.proxy'; import { QR } from '../../QR'; import { NowebAuthFactoryCore } from './NowebAuthFactoryCore'; @@ -349,6 +352,16 @@ export class WhatsappSessionNoWebCore extends WhatsappSession { return this.sock.sendMessage(chatId, message); } + async sendContactVCard(request: MessageContactVcardRequest) { + const chatId = this.ensureSuffix(request.chatId); + const contacts = request.contacts.map((el) => ({ vcard: toVcard(el) })); + await this.sock.sendMessage(chatId, { + contacts: { + contacts: contacts, + }, + }); + } + async sendPoll(request: MessagePollRequest) { const requestPoll = request.poll; const poll = { diff --git a/src/core/engines/venom/session.venom.core.ts b/src/core/engines/venom/session.venom.core.ts index 4ab10414..6ef17756 100644 --- a/src/core/engines/venom/session.venom.core.ts +++ b/src/core/engines/venom/session.venom.core.ts @@ -6,7 +6,6 @@ import { ChatRequest, CheckNumberStatusQuery, GetMessageQuery, - MessageContactVcardRequest, MessageFileRequest, MessageImageRequest, MessageLinkPreviewRequest, @@ -164,14 +163,6 @@ export class WhatsappSessionVenomCore extends WhatsappSession { } } - sendContactVCard(request: MessageContactVcardRequest) { - return this.whatsapp.sendContactVcard( - request.chatId, - request.contactsId, - request.name, - ); - } - sendText(request: MessageTextRequest) { return this.whatsapp.sendText( this.ensureSuffix(request.chatId), diff --git a/src/core/helpers.ts b/src/core/helpers.ts new file mode 100644 index 00000000..fd886435 --- /dev/null +++ b/src/core/helpers.ts @@ -0,0 +1,21 @@ +export function toVcard(data): string { + if (data.vcard) { + return data.vcard; + } + const parts = []; + parts.push('BEGIN:VCARD'); + parts.push('VERSION:3.0'); + parts.push(`FN:${data.fullName}`); + if (data.organization) { + parts.push(`ORG:${data.organization};`); + } + if (data.whatsappId) { + parts.push( + `TEL;type=CELL;type=VOICE;waid=${data.whatsappId}:${data.phoneNumber}`, + ); + } else { + parts.push(`TEL;type=CELL;type=VOICE:${data.phoneNumber}`); + } + parts.push('END:VCARD'); + return parts.join('\n'); +} diff --git a/src/structures/chatting.dto.ts b/src/structures/chatting.dto.ts index 07546d64..013d6380 100644 --- a/src/structures/chatting.dto.ts +++ b/src/structures/chatting.dto.ts @@ -85,9 +85,59 @@ export class MessageRequest extends SessionBaseRequest { messageId: string; } +export class VCardContact { + @ApiProperty({ + example: + 'BEGIN:VCARD\nVERSION:3.0\nFN:Jane Doe\nORG:Company Name;\nTEL;type=CELL;type=VOICE;waid=911111111111:+91 11111 11111\nEND:VCARD', + description: 'The vcard string', + }) + vcard: string; +} + +export class Contact { + @ApiProperty({ + example: 'John Doe', + description: 'The full name of the contact', + }) + fullName: string; + + @ApiProperty({ + example: 'Company Name', + description: 'The organization of the contact', + required: false, + }) + organization: string; + + @ApiProperty({ + example: '+91 11111 11111', + description: 'The phone number of the contact', + }) + phoneNumber: string; + + @ApiProperty({ + example: '911111111111', + description: 'The whatsapp id of the contact. DO NOT add + or @c.us', + required: false, + }) + whatsappId: string; + + vcard: string = null; +} + +@ApiExtraModels(Contact, VCardContact) export class MessageContactVcardRequest extends ChatRequest { - contactsId: string; - name: string; + @ApiProperty({ + type: 'array', + oneOf: [ + { + $ref: getSchemaPath(VCardContact), + }, + { + $ref: getSchemaPath(Contact), + }, + ], + }) + contacts: (VCardContact | Contact)[]; } export class MessageTextRequest extends ChatRequest {