Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
abfcbc7397 | ||
|
|
96f2982325 | ||
|
|
3a521bc06c | ||
|
|
6fbaec0083 | ||
|
|
cae94c7b5c | ||
|
|
bce012f692 | ||
|
|
b23b639a8b | ||
|
|
5a628907ed | ||
|
|
6da479c0d7 | ||
|
|
cbb321df6d | ||
|
|
0a7beb6909 |
No files matched your search
@@ -1,4 +1,5 @@
|
||||
.yarn
|
||||
example.ts
|
||||
.*sessions
|
||||
tokens
|
||||
files
|
||||
|
||||
@@ -116,6 +116,9 @@ Fired on all message creations, including your own. The payload is the same as f
|
||||
```
|
||||
|
||||
### message.ack
|
||||
Receive events when server or recipient gets the message, read or played it.
|
||||
|
||||
[See details on Webhooks page ->]({{< relref "webhooks#messageack" >}}).
|
||||
|
||||
```json
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@ images: [ ]
|
||||
weight: 125
|
||||
---
|
||||
|
||||
## Endpoints
|
||||
## Sessions
|
||||
|
||||
### Start
|
||||
|
||||
@@ -129,6 +129,38 @@ In order to log out the session - call `POST /api/sessions/logout`
|
||||
```
|
||||
|
||||
|
||||
## Authentication
|
||||
### Get QR
|
||||
The simplest way to authenticate a new session - get QR code and scan it on your device.
|
||||
```bash
|
||||
GET /api/{session}/auth/qr
|
||||
```
|
||||
You'll get QR image that you can scan and get authenticated
|
||||
|
||||
### Get pairing code
|
||||
{{< alert icon="👉" text="Available in **NOWEB** engine only." />}}
|
||||
|
||||
You can [link a session with phone number](https://faq.whatsapp.com/1324084875126592) - make a request to the endpoint.
|
||||
```bash
|
||||
POST /api/{session}/auth/request-code
|
||||
```
|
||||
|
||||
Body example:
|
||||
```json
|
||||
{
|
||||
"phoneNumber": "12132132130"
|
||||
}
|
||||
```
|
||||
|
||||
You'll get code in the response that you can use on your WhatsApp app to connect the session:
|
||||
```json
|
||||
{
|
||||
"code": "ABCD-ABCD"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## Advanced sessions 
|
||||
|
||||
|
||||
@@ -190,14 +190,32 @@ Fired on all message creations, including your own. The payload is the same as f
|
||||
```
|
||||
|
||||
### message.ack
|
||||
Receive events when server or recipient gets the message, read or played it.
|
||||
|
||||
`ackName` field contains message status (`ack` has the same meaning, but show the value in int, but we keep it for backward compatability, they much to each other)
|
||||
|
||||
Possible message ack statuses:
|
||||
- `ackName: ERROR, ack: -1`
|
||||
- `ackName: PENDING, ack: 0`
|
||||
- `ackName: SERVER, ack: 1`
|
||||
- `ackName: DEVICE, ack: 2`
|
||||
- `ackName: READ, ack: 3`
|
||||
- `ackName: PLAYED, ack: 4`
|
||||
|
||||
|
||||
The payload may have more fields, it depends on the engine you use, but here's a minimum amount that all engines send:
|
||||
```json
|
||||
{
|
||||
"event": "message.ack",
|
||||
"session": "default",
|
||||
"engine": "WEBJS",
|
||||
"payload": {
|
||||
...
|
||||
"id":"true_11111111111@c.us_4CC5EDD64BC22EBA6D639F2AF571346C",
|
||||
"from":"11111111111@c.us",
|
||||
"participant": null,
|
||||
"fromMe":true,
|
||||
"ack":3,
|
||||
"ackName":"READ"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -12,6 +12,13 @@ menu:
|
||||
weight: 199
|
||||
toc: true
|
||||
---
|
||||
## 2023.9
|
||||
September 2023
|
||||
- Add dedicated [Get QR](https://waha.devlike.pro/docs/how-to/sessions/#get-qr) endpoint!
|
||||
- Support [pairing method (NOWEB)](https://waha.devlike.pro/docs/how-to/sessions/#get-pairing-code) - you can connect with a code instead of QR.
|
||||
- Add string field `ackName: DEVICE|READ|...` in [message.ack payload](https://waha.devlike.pro/docs/how-to/webhooks/#messageack)
|
||||
- Support `message.ack` event webhook in **NOWEB** engine
|
||||
|
||||
## 2023.8
|
||||
August 2023
|
||||
- Added [stories (aka status) endpoints](https://waha.devlike.pro/docs/how-to/send-messages/#send-status-aka-stories) to **NOWEB** engine!
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"openapi":"3.0.0","paths":{"/api/sessions/start":{"post":{"operationId":"SessionsController_start","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionStartRequest"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionDTO"}}}}},"tags":["sessions"],"security":[{"api_key":[]}]}},"/api/sessions/stop":{"post":{"operationId":"SessionsController_stop","summary":"Stop session","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionStopRequest"}}}},"responses":{"201":{"description":""}},"tags":["sessions"],"security":[{"api_key":[]}]}},"/api/sessions/logout":{"post":{"operationId":"SessionsController_clean","summary":"Logout from session.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionLogoutRequest"}}}},"responses":{"201":{"description":""}},"tags":["sessions"],"security":[{"api_key":[]}]}},"/api/sessions":{"get":{"operationId":"SessionsController_list","parameters":[{"name":"all","required":false,"in":"query","example":false,"description":"Return all sessions, including those that are in the STOPPED state.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SessionDTO"}}}}}},"tags":["sessions"],"security":[{"api_key":[]}]}},"/api/checkNumberStatus":{"get":{"operationId":"ChattingController_checkNumberStatus","summary":"Check number status","parameters":[{"name":"phone","required":true,"in":"query","schema":{"type":"string"}},{"name":"session","required":true,"in":"query","schema":{"default":"default","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WANumberExistResult"}}}}},"tags":["chatting"],"security":[{"api_key":[]}]}},"/api/sendContactVcard":{"post":{"operationId":"ChattingController_sendContactVcard","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageContactVcardRequest"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["chatting"],"security":[{"api_key":[]}]}},"/api/sendText":{"get":{"operationId":"ChattingController_sendTextGet","summary":"Send a text message","parameters":[{"name":"phone","required":true,"in":"query","schema":{"type":"string"}},{"name":"text","required":true,"in":"query","schema":{"type":"string"}},{"name":"session","required":true,"in":"query","schema":{"default":"default","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["chatting"],"security":[{"api_key":[]}]},"post":{"operationId":"ChattingController_sendText","summary":"Send a text message","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageTextRequest"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WAMessage"}}}}},"tags":["chatting"],"security":[{"api_key":[]}]}},"/api/sendTextButtons":{"post":{"operationId":"ChattingController_sendTextButtons","summary":"Send a text message with buttons","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageTextButtonsRequest"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["chatting"],"security":[{"api_key":[]}]}},"/api/sendLocation":{"post":{"operationId":"ChattingController_sendLocation","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageLocationRequest"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["chatting"],"security":[{"api_key":[]}]}},"/api/sendLinkPreview":{"post":{"operationId":"ChattingController_sendLinkPreview","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageLinkPreviewRequest"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["chatting"],"security":[{"api_key":[]}]}},"/api/sendImage":{"post":{"operationId":"ChattingController_sendImage","summary":"Send an image. Either from an URL or base64 data - look at the request schemas for details.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageImageRequest"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["chatting"],"security":[{"api_key":[]}]}},"/api/sendFile":{"post":{"operationId":"ChattingControllLine truncated
|
||||
{"openapi":"3.0.0","paths":{"/api/{session}/auth/qr":{"get":{"operationId":"AuthController_getQR","summary":"Get QR code for pairing WhatsApp Web.","parameters":[{"name":"session","required":true,"in":"path","description":"WhatsApp session name","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["auth"],"security":[{"api_key":[]}]}},"/api/{session}/auth/request-code":{"post":{"operationId":"AuthController_requestCode","summary":"Request authentication code. NOWEB and NOWEB_MOBILE engines only","parameters":[{"name":"session","required":true,"in":"path","description":"WhatsApp session name","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestCodeRequest"}}}},"responses":{"201":{"description":""}},"tags":["auth"],"security":[{"api_key":[]}]}},"/api/{session}/auth/authorize-code":{"post":{"operationId":"AuthController_authorizeCode","summary":"Send OTP authentication code. NOWEB_MOBILE engine only","parameters":[{"name":"session","required":true,"in":"path","description":"WhatsApp session name","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OTPRequest"}}}},"responses":{"201":{"description":""}},"tags":["auth"],"security":[{"api_key":[]}]}},"/api/sessions/start":{"post":{"operationId":"SessionsController_start","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionStartRequest"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionDTO"}}}}},"tags":["sessions"],"security":[{"api_key":[]}]}},"/api/sessions/stop":{"post":{"operationId":"SessionsController_stop","summary":"Stop session","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionStopRequest"}}}},"responses":{"201":{"description":""}},"tags":["sessions"],"security":[{"api_key":[]}]}},"/api/sessions/logout":{"post":{"operationId":"SessionsController_clean","summary":"Logout from session.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionLogoutRequest"}}}},"responses":{"201":{"description":""}},"tags":["sessions"],"security":[{"api_key":[]}]}},"/api/sessions":{"get":{"operationId":"SessionsController_list","parameters":[{"name":"all","required":false,"in":"query","example":false,"description":"Return all sessions, including those that are in the STOPPED state.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SessionDTO"}}}}}},"tags":["sessions"],"security":[{"api_key":[]}]}},"/api/checkNumberStatus":{"get":{"operationId":"ChattingController_checkNumberStatus","summary":"Check number status","parameters":[{"name":"phone","required":true,"in":"query","schema":{"type":"string"}},{"name":"session","required":true,"in":"query","schema":{"default":"default","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WANumberExistResult"}}}}},"tags":["chatting"],"security":[{"api_key":[]}]}},"/api/sendContactVcard":{"post":{"operationId":"ChattingController_sendContactVcard","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageContactVcardRequest"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["chatting"],"security":[{"api_key":[]}]}},"/api/sendText":{"get":{"operationId":"ChattingController_sendTextGet","summary":"Send a text message","parameters":[{"name":"phone","required":true,"in":"query","schema":{"type":"string"}},{"name":"text","required":true,"in":"query","schema":{"type":"string"}},{"name":"session","required":true,"in":"query","schema":{"default":"default","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["chatting"],"security":[{"api_key":[]}]},"post":{"operationId":"ChattingController_sendText","summary":"Send a text message","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageTextRequest"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WAMessage"}}}}},"tags":["chatting"],"security":[{"api_key":[]}]}},"/api/sendTextButtons":{"post":{"operationId":"ChattingController_sendTextButtons","summary":"Send a text message with buttons","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageTextButtonsRequest"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"taLine truncated
|
||||
@@ -38,6 +38,7 @@
|
||||
"express-basic-auth": "^1.2.1",
|
||||
"file-type": "16.5.4",
|
||||
"https-proxy-agent": "^7.0.0",
|
||||
"libphonenumber-js": "^1.10.36",
|
||||
"link-preview-js": "^3.0.4",
|
||||
"lodash": "^4.17.21",
|
||||
"mime-types": "^2.1.27",
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import { Body, Controller, Get, Post, Res } from '@nestjs/common';
|
||||
import { ApiOperation, ApiSecurity, ApiTags } from '@nestjs/swagger';
|
||||
|
||||
import { SessionManager } from '../core/abc/manager.abc';
|
||||
import { WhatsappSession } from '../core/abc/session.abc';
|
||||
import { OTPRequest, RequestCodeRequest } from '../structures/auth.dto';
|
||||
import { SessionApiParam, SessionParam } from './helpers';
|
||||
import { WAHASessionStatus } from '../structures/enums.dto';
|
||||
import { UnprocessableEntityException } from '@nestjs/common/exceptions/unprocessable-entity.exception';
|
||||
import { Readable } from 'stream';
|
||||
import { Response } from 'express';
|
||||
|
||||
@ApiSecurity('api_key')
|
||||
@Controller('api/:session/auth')
|
||||
@ApiTags('auth')
|
||||
class AuthController {
|
||||
constructor(private manager: SessionManager) {}
|
||||
|
||||
@Get('qr')
|
||||
@SessionApiParam
|
||||
@ApiOperation({
|
||||
summary: 'Get QR code for pairing WhatsApp Web.',
|
||||
})
|
||||
async getQR(@Res() res: Response, @SessionParam session: WhatsappSession) {
|
||||
if (session.status != WAHASessionStatus.SCAN_QR_CODE) {
|
||||
const err = `Can get QR code only in SCAN_QR_CODE status. The current status is '${session.status}'`;
|
||||
throw new UnprocessableEntityException(err);
|
||||
}
|
||||
|
||||
const buffer = await session.getQR();
|
||||
const stream = new Readable();
|
||||
stream.push(buffer);
|
||||
stream.push(null);
|
||||
|
||||
res.set({
|
||||
'Content-Type': 'image/png',
|
||||
'Content-Length': buffer.length,
|
||||
});
|
||||
stream.pipe(res);
|
||||
}
|
||||
|
||||
@Post('request-code')
|
||||
@SessionApiParam
|
||||
@ApiOperation({
|
||||
summary: 'Request authentication code. NOWEB and NOWEB_MOBILE engines only',
|
||||
})
|
||||
requestCode(
|
||||
@SessionParam session: WhatsappSession,
|
||||
@Body() request: RequestCodeRequest,
|
||||
) {
|
||||
return session.requestCode(request.phoneNumber, request.method);
|
||||
}
|
||||
|
||||
@Post('authorize-code')
|
||||
@SessionApiParam
|
||||
@ApiOperation({
|
||||
summary: 'Send OTP authentication code. NOWEB_MOBILE engine only',
|
||||
})
|
||||
authorizeCode(
|
||||
@SessionParam session: WhatsappSession,
|
||||
@Body() request: OTPRequest,
|
||||
) {
|
||||
return session.authorizeCode(request.code);
|
||||
}
|
||||
}
|
||||
|
||||
export { AuthController };
|
||||
@@ -18,8 +18,9 @@ import {
|
||||
MessageTextRequest,
|
||||
MessageVoiceRequest,
|
||||
SendSeenRequest,
|
||||
WANumberExistResult,
|
||||
} from '../structures/chatting.dto';
|
||||
import { WAMessage, WANumberExistResult } from '../structures/responses.dto';
|
||||
import { WAMessage } from '../structures/responses.dto';
|
||||
|
||||
@ApiSecurity('api_key')
|
||||
@Controller('api')
|
||||
|
||||
@@ -3,9 +3,11 @@ import { ApiOperation, ApiSecurity, ApiTags } from '@nestjs/swagger';
|
||||
|
||||
import { SessionManager } from '../core/abc/manager.abc';
|
||||
import { SessionQuery } from '../structures/base.dto';
|
||||
import { CheckNumberStatusQuery } from '../structures/chatting.dto';
|
||||
import {
|
||||
CheckNumberStatusQuery,
|
||||
WANumberExistResult,
|
||||
} from '../structures/chatting.dto';
|
||||
import { ContactQuery, ContactRequest } from '../structures/contacts.dto';
|
||||
import { WANumberExistResult } from '../structures/responses.dto';
|
||||
|
||||
@ApiSecurity('api_key')
|
||||
@Controller('api/contacts')
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ConfigService } from '@nestjs/config';
|
||||
|
||||
import { parseBool } from './helpers';
|
||||
import { WAHAEngine } from './structures/enums.dto';
|
||||
import { WebhookConfig } from './structures/webhooks.dto';
|
||||
import { WebhookConfig } from './structures/webhooks.config.dto';
|
||||
|
||||
@Injectable()
|
||||
export class WhatsappConfigService {
|
||||
|
||||
@@ -33,6 +33,7 @@ import { WAHAChatPresences } from '../../structures/presence.dto';
|
||||
import { ProxyConfig, SessionConfig } from '../../structures/sessions.dto';
|
||||
import { NotImplementedByEngineError } from '../exceptions';
|
||||
import { LocalSessionStorage, MediaStorage } from './storage.abc';
|
||||
import { OTPRequest, RequestCodeRequest } from '../../structures/auth.dto';
|
||||
import {
|
||||
ImageStatus,
|
||||
TextStatus,
|
||||
@@ -147,8 +148,28 @@ export abstract class WhatsappSession {
|
||||
/**
|
||||
* START - Methods for API
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auth methods
|
||||
*/
|
||||
|
||||
public getQR(): Promise<Buffer> {
|
||||
throw new NotImplementedByEngineError();
|
||||
}
|
||||
|
||||
public requestCode(phoneNumber: string, method: string) {
|
||||
throw new NotImplementedByEngineError();
|
||||
}
|
||||
|
||||
public authorizeCode(code: string) {
|
||||
throw new NotImplementedByEngineError();
|
||||
}
|
||||
|
||||
abstract getScreenshot(): Promise<Buffer | string>;
|
||||
|
||||
/**
|
||||
* Other methods
|
||||
*/
|
||||
abstract checkNumberStatus(request: CheckNumberStatusQuery);
|
||||
|
||||
abstract sendText(request: MessageTextRequest);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ConsoleLogger } from '@nestjs/common';
|
||||
|
||||
import { WebhookConfig } from '../../structures/webhooks.dto';
|
||||
import { WebhookConfig } from '../../structures/webhooks.config.dto';
|
||||
import { WhatsappSession } from './session.abc';
|
||||
|
||||
export abstract class WebhookSender {
|
||||
|
||||
@@ -13,6 +13,7 @@ import { VersionController } from '../api/version.controller';
|
||||
import { WhatsappConfigService } from '../config.service';
|
||||
import { SessionManager } from './abc/manager.abc';
|
||||
import { SessionManagerCore } from './manager.core';
|
||||
import { AuthController } from '../api/auth.controller';
|
||||
import { ChatsController } from '../api/chats.controller';
|
||||
import { StatusController } from '../api/status.controller';
|
||||
|
||||
@@ -36,6 +37,7 @@ export const IMPORTS = [
|
||||
PassportModule,
|
||||
];
|
||||
export const CONTROLLERS = [
|
||||
AuthController,
|
||||
SessionsController,
|
||||
ChattingController,
|
||||
ChatsController,
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
SessionStartRequest,
|
||||
SessionStopRequest,
|
||||
} from '../structures/sessions.dto';
|
||||
import { WebhookConfig } from '../structures/webhooks.dto';
|
||||
import { WebhookConfig } from '../structures/webhooks.config.dto';
|
||||
import { SessionManager } from './abc/manager.abc';
|
||||
import {
|
||||
SessionParams,
|
||||
|
||||
+151
-22
@@ -6,19 +6,18 @@ import makeWASocket, {
|
||||
PresenceData,
|
||||
useMultiFileAuthState,
|
||||
} from '@adiwajshing/baileys';
|
||||
import { WABrowserDescription } from '@adiwajshing/baileys';
|
||||
import { UnprocessableEntityException } from '@nestjs/common';
|
||||
import * as fs from 'fs/promises';
|
||||
import { Agent } from 'https';
|
||||
import * as lodash from 'lodash';
|
||||
import { PairingCodeResponse } from 'src/structures/auth.dto';
|
||||
import { Message } from 'whatsapp-web.js';
|
||||
|
||||
import { flipObject } from '../helpers';
|
||||
import { flipObject, splitAt } from '../helpers';
|
||||
import {
|
||||
Button,
|
||||
ChatRequest,
|
||||
CheckNumberStatusQuery,
|
||||
GetMessageQuery,
|
||||
MessageContactVcardRequest,
|
||||
MessageFileRequest,
|
||||
MessageImageRequest,
|
||||
@@ -30,14 +29,17 @@ import {
|
||||
MessageTextRequest,
|
||||
MessageVoiceRequest,
|
||||
SendSeenRequest,
|
||||
WANumberExistResult,
|
||||
} from '../structures/chatting.dto';
|
||||
import { ContactQuery, ContactRequest } from '../structures/contacts.dto';
|
||||
import {
|
||||
ACK_UNKNOWN,
|
||||
SECOND,
|
||||
WAHAEngine,
|
||||
WAHAEvents,
|
||||
WAHAPresenceStatus,
|
||||
WAHASessionStatus,
|
||||
WAMessageAck,
|
||||
} from '../structures/enums.dto';
|
||||
import {
|
||||
CreateGroupRequest,
|
||||
@@ -47,7 +49,7 @@ import {
|
||||
WAHAChatPresences,
|
||||
WAHAPresenceData,
|
||||
} from '../structures/presence.dto';
|
||||
import { WAMessage, WANumberExistResult } from '../structures/responses.dto';
|
||||
import { WAMessage } from '../structures/responses.dto';
|
||||
import { BROADCAST_ID, TextStatus } from '../structures/status.dto';
|
||||
import {
|
||||
ensureSuffix,
|
||||
@@ -60,6 +62,8 @@ import {
|
||||
} from './exceptions';
|
||||
import { createAgentProxy } from './helpers.proxy';
|
||||
import { QR } from './QR';
|
||||
import { WAMessageAckBody } from '../structures/webhooks.dto';
|
||||
import { update } from 'lodash';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const QRCode = require('qrcode');
|
||||
@@ -69,7 +73,9 @@ const logger = require('pino')();
|
||||
export const BaileysEvents = {
|
||||
CONNECTION_UPDATE: 'connection.update',
|
||||
CREDS_UPDATE: 'creds.update',
|
||||
MESSAGES_UPDATE: 'messages.update',
|
||||
MESSAGES_UPSERT: 'messages.upsert',
|
||||
MESSAGE_RECEIPT_UPDATE: 'message-receipt.update',
|
||||
GROUPS_UPSERT: 'groups.upsert',
|
||||
PRESENCE_UPDATE: 'presence.update',
|
||||
};
|
||||
@@ -131,9 +137,12 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
}
|
||||
|
||||
connectStore() {
|
||||
this.log.debug(`Connecting store...`);
|
||||
if (!this.store) {
|
||||
this.log.debug(`Making a new auth store...`);
|
||||
this.store = makeInMemoryStore({});
|
||||
}
|
||||
this.log.debug(`Binding store to socket...`);
|
||||
this.store.bind(this.sock.ev);
|
||||
}
|
||||
|
||||
@@ -146,6 +155,12 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
async buildClient() {
|
||||
this.sock = await this.makeSocket();
|
||||
this.connectStore();
|
||||
this.listenConnectionEvents();
|
||||
this.events.emit(WAHAInternalEvent.engine_start);
|
||||
}
|
||||
|
||||
protected listenConnectionEvents() {
|
||||
this.log.debug(`Start listening ${BaileysEvents.CONNECTION_UPDATE}...`);
|
||||
this.sock.ev.on(BaileysEvents.CONNECTION_UPDATE, async (update) => {
|
||||
const { connection, lastDisconnect, qr } = update;
|
||||
if (connection === 'connecting') {
|
||||
@@ -179,7 +194,6 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
});
|
||||
}
|
||||
});
|
||||
this.events.emit(WAHAInternalEvent.engine_start);
|
||||
}
|
||||
|
||||
stop() {
|
||||
@@ -192,6 +206,42 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
/**
|
||||
* START - Methods for API
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auth methods
|
||||
*/
|
||||
public async getQR(): Promise<Buffer> {
|
||||
return Promise.resolve(this.qr.get());
|
||||
}
|
||||
|
||||
public async requestCode(
|
||||
phoneNumber: string,
|
||||
method: string,
|
||||
): Promise<PairingCodeResponse> {
|
||||
if (method) {
|
||||
const err = `NOWEB engine doesn't support any 'method', remove it and try again`;
|
||||
throw new UnprocessableEntityException(err);
|
||||
}
|
||||
|
||||
if (this.status == WAHASessionStatus.STARTING) {
|
||||
this.log.debug('Waiting for connection update...');
|
||||
await this.sock.waitForConnectionUpdate((update) => !!update.qr);
|
||||
}
|
||||
|
||||
if (this.status != WAHASessionStatus.SCAN_QR_CODE) {
|
||||
const err = `Can request code only in SCAN_QR_CODE status. The current status is ${this.status}`;
|
||||
throw new UnprocessableEntityException(err);
|
||||
}
|
||||
|
||||
this.log.debug('Requesting pairing code...');
|
||||
const code: string = await this.sock.requestPairingCode(phoneNumber);
|
||||
// show it as ABCD-ABCD
|
||||
const parts = splitAt(code, 4);
|
||||
const codeRepr = parts.join('-');
|
||||
this.log.debug(`Your code: ${codeRepr}`);
|
||||
return { code: codeRepr };
|
||||
}
|
||||
|
||||
async getScreenshot(): Promise<Buffer | string> {
|
||||
if (this.status === WAHASessionStatus.STARTING) {
|
||||
throw new UnprocessableEntityException(
|
||||
@@ -208,6 +258,9 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Other methods
|
||||
*/
|
||||
async checkNumberStatus(
|
||||
request: CheckNumberStatusQuery,
|
||||
): Promise<WANumberExistResult> {
|
||||
@@ -470,19 +523,34 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
|
||||
subscribe(event, handler) {
|
||||
if (event === WAHAEvents.MESSAGE) {
|
||||
return this.sock.ev.on(BaileysEvents.MESSAGES_UPSERT, ({ messages }) =>
|
||||
this.sock.ev.on(BaileysEvents.MESSAGES_UPSERT, ({ messages }) =>
|
||||
this.handleIncomingMessages(messages, handler, false),
|
||||
);
|
||||
} else if (event === WAHAEvents.MESSAGE_ANY) {
|
||||
return this.sock.ev.on(BaileysEvents.MESSAGES_UPSERT, ({ messages }) =>
|
||||
this.sock.ev.on(BaileysEvents.MESSAGES_UPSERT, ({ messages }) =>
|
||||
this.handleIncomingMessages(messages, handler, true),
|
||||
);
|
||||
} else if (event === WAHAEvents.MESSAGE_ACK) {
|
||||
// Direct message ack
|
||||
this.sock.ev.on(BaileysEvents.MESSAGES_UPDATE, (events) => {
|
||||
events
|
||||
.filter(isMine)
|
||||
.map(this.convertMessageUpdateToMessageAck)
|
||||
.forEach(handler);
|
||||
});
|
||||
// Group message ack
|
||||
this.sock.ev.on(BaileysEvents.MESSAGE_RECEIPT_UPDATE, (events) => {
|
||||
events
|
||||
.filter(isMine)
|
||||
.map(this.convertMessageReceiptUpdateToMessageAck)
|
||||
.forEach(handler);
|
||||
});
|
||||
} else if (event === WAHAEvents.STATE_CHANGE) {
|
||||
return this.sock.ev.on(BaileysEvents.CONNECTION_UPDATE, handler);
|
||||
this.sock.ev.on(BaileysEvents.CONNECTION_UPDATE, handler);
|
||||
} else if (event === WAHAEvents.GROUP_JOIN) {
|
||||
return this.sock.ev.on(BaileysEvents.GROUPS_UPSERT, handler);
|
||||
this.sock.ev.on(BaileysEvents.GROUPS_UPSERT, handler);
|
||||
} else if (event === WAHAEvents.PRESENCE_UPDATE) {
|
||||
return this.sock.ev.on(BaileysEvents.PRESENCE_UPDATE, (data) =>
|
||||
this.sock.ev.on(BaileysEvents.PRESENCE_UPDATE, (data) =>
|
||||
handler(this.toWahaPresences(data.id, data.presences)),
|
||||
);
|
||||
} else {
|
||||
@@ -506,18 +574,17 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
}
|
||||
|
||||
private processIncomingMessage(message) {
|
||||
return this.downloadMedia(message).then(this.toWAMessage);
|
||||
return this.downloadMedia(message)
|
||||
.then(this.toWAMessage)
|
||||
.catch((error) => {
|
||||
this.log.error('Failed to process incoming message');
|
||||
this.log.error(error);
|
||||
console.trace(error);
|
||||
});
|
||||
}
|
||||
|
||||
protected toWAMessage(message): Promise<WAMessage> {
|
||||
const isGroupMessage = Boolean(message.key.participant);
|
||||
let participant: string;
|
||||
let to: string;
|
||||
if (isGroupMessage) {
|
||||
participant = message.key.participant;
|
||||
to = message.key.remoteJid;
|
||||
}
|
||||
const from = message.key.remoteJid;
|
||||
const destination = getDestination(message);
|
||||
const id = buildMessageId(message.key);
|
||||
let body = message.message.conversation;
|
||||
if (!body) {
|
||||
@@ -528,22 +595,64 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
return Promise.resolve({
|
||||
id: id,
|
||||
timestamp: message.messageTimestamp,
|
||||
from: toCusFormat(from),
|
||||
from: toCusFormat(destination.from),
|
||||
fromMe: message.key.fromMe,
|
||||
body: body,
|
||||
to: toCusFormat(to),
|
||||
participant: toCusFormat(participant),
|
||||
to: toCusFormat(destination.to),
|
||||
participant: toCusFormat(destination.participant),
|
||||
// @ts-ignore
|
||||
hasMedia: Boolean(message.mediaUrl),
|
||||
// @ts-ignore
|
||||
mediaUrl: message.mediaUrl,
|
||||
// @ts-ignore
|
||||
ack: message.ack,
|
||||
// @ts-ignore
|
||||
ackName: WAMessageAck[message.ack] || ACK_UNKNOWN,
|
||||
location: message.location,
|
||||
vCards: message.vCards,
|
||||
_data: message,
|
||||
});
|
||||
}
|
||||
protected convertMessageUpdateToMessageAck(event): WAMessageAckBody {
|
||||
const message = event;
|
||||
const destination = getDestination(message);
|
||||
const id = buildMessageId(message.key);
|
||||
const ack = message.update.status - 1;
|
||||
const body: WAMessageAckBody = {
|
||||
id: id,
|
||||
from: toCusFormat(destination.from),
|
||||
to: toCusFormat(destination.to),
|
||||
participant: toCusFormat(destination.participant),
|
||||
fromMe: message.key.fromMe,
|
||||
ack: ack,
|
||||
ackName: WAMessageAck[ack] || ACK_UNKNOWN,
|
||||
};
|
||||
return body;
|
||||
}
|
||||
protected convertMessageReceiptUpdateToMessageAck(event): WAMessageAckBody {
|
||||
const destination = getDestination(event);
|
||||
const id = buildMessageId(event.key);
|
||||
|
||||
const receipt = event.receipt;
|
||||
let ack;
|
||||
if (receipt.receiptTimestamp) {
|
||||
ack = WAMessageAck.SERVER;
|
||||
} else if (receipt.playedTimestamp) {
|
||||
ack = WAMessageAck.PLAYED;
|
||||
} else if (receipt.readTimestamp) {
|
||||
ack = WAMessageAck.READ;
|
||||
}
|
||||
const body: WAMessageAckBody = {
|
||||
id: id,
|
||||
from: toCusFormat(destination.from),
|
||||
to: toCusFormat(destination.to),
|
||||
participant: toCusFormat(destination.participant),
|
||||
fromMe: event.key.fromMe,
|
||||
ack: ack,
|
||||
ackName: WAMessageAck[ack] || ACK_UNKNOWN,
|
||||
};
|
||||
return body;
|
||||
}
|
||||
|
||||
private toWahaPresences(
|
||||
remoteJid,
|
||||
@@ -638,3 +747,23 @@ function parseMessageId(messageId) {
|
||||
function getId(object) {
|
||||
return object.id;
|
||||
}
|
||||
|
||||
function isMine(message) {
|
||||
return message?.key?.fromMe;
|
||||
}
|
||||
|
||||
function getDestination(message) {
|
||||
const isGroupMessage = Boolean(message.key.participant);
|
||||
let participant: string;
|
||||
let to: string;
|
||||
if (isGroupMessage) {
|
||||
participant = message.key.participant;
|
||||
to = message.key.remoteJid;
|
||||
}
|
||||
const from = message.key.remoteJid;
|
||||
return {
|
||||
from: from,
|
||||
to: to,
|
||||
participant: participant,
|
||||
};
|
||||
}
|
||||
@@ -15,13 +15,14 @@ import {
|
||||
MessageReplyRequest,
|
||||
MessageTextButtonsRequest,
|
||||
MessageTextRequest,
|
||||
WANumberExistResult,
|
||||
} from '../structures/chatting.dto';
|
||||
import {
|
||||
WAHAEngine,
|
||||
WAHAEvents,
|
||||
WAHASessionStatus,
|
||||
} from '../structures/enums.dto';
|
||||
import { WAMessage, WANumberExistResult } from '../structures/responses.dto';
|
||||
import { WAMessage } from '../structures/responses.dto';
|
||||
import { WAHAInternalEvent, WhatsappSession } from './abc/session.abc';
|
||||
import { NotImplementedByEngineError } from './exceptions';
|
||||
import { QR } from './QR';
|
||||
|
||||
@@ -28,24 +28,31 @@ import {
|
||||
MessageTextRequest,
|
||||
MessageVoiceRequest,
|
||||
SendSeenRequest,
|
||||
WANumberExistResult,
|
||||
} from '../structures/chatting.dto';
|
||||
import { ContactQuery, ContactRequest } from '../structures/contacts.dto';
|
||||
import {
|
||||
ACK_UNKNOWN,
|
||||
WAHAEngine,
|
||||
WAHAEvents,
|
||||
WAHAPresenceStatus,
|
||||
WAHASessionStatus,
|
||||
WAMessageAck,
|
||||
} from '../structures/enums.dto';
|
||||
import {
|
||||
CreateGroupRequest,
|
||||
ParticipantsRequest,
|
||||
} from '../structures/groups.dto';
|
||||
import { WAMessage, WANumberExistResult } from '../structures/responses.dto';
|
||||
import { WAMessage } from '../structures/responses.dto';
|
||||
import { WAHAInternalEvent, WhatsappSession } from './abc/session.abc';
|
||||
import {
|
||||
AvailableInPlusVersion,
|
||||
NotImplementedByEngineError,
|
||||
} from './exceptions';
|
||||
import { QR } from './QR';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const QRCode = require('qrcode');
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const qrcode = require('qrcode-terminal');
|
||||
@@ -54,6 +61,12 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
engine = WAHAEngine.WEBJS;
|
||||
|
||||
whatsapp: Client;
|
||||
protected qr: QR;
|
||||
|
||||
public constructor(config) {
|
||||
super(config);
|
||||
this.qr = new QR();
|
||||
}
|
||||
|
||||
protected buildClient() {
|
||||
const clientOptions: ClientOptions = {
|
||||
@@ -86,23 +99,12 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
|
||||
async start() {
|
||||
this.whatsapp = this.buildClient();
|
||||
|
||||
this.whatsapp.initialize().catch((error) => {
|
||||
this.status = WAHASessionStatus.FAILED;
|
||||
this.log.error(error);
|
||||
return;
|
||||
});
|
||||
|
||||
// Connect events
|
||||
this.whatsapp.on(Events.QR_RECEIVED, (qr) => {
|
||||
qrcode.generate(qr, { small: true });
|
||||
this.status = WAHASessionStatus.SCAN_QR_CODE;
|
||||
});
|
||||
|
||||
this.whatsapp.on(Events.AUTHENTICATED, () => {
|
||||
this.status = WAHASessionStatus.WORKING;
|
||||
this.log.log(`Session '${this.name}' has been authenticated!`);
|
||||
});
|
||||
this.listenConnectionEvents();
|
||||
this.events.emit(WAHAInternalEvent.engine_start);
|
||||
return this;
|
||||
}
|
||||
@@ -111,9 +113,36 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
return this.whatsapp.destroy();
|
||||
}
|
||||
|
||||
protected listenConnectionEvents() {
|
||||
this.whatsapp.on(Events.QR_RECEIVED, (qr) => {
|
||||
this.log.debug('QR received');
|
||||
// Convert to image and save
|
||||
QRCode.toDataURL(qr).then((url) => {
|
||||
this.qr.save(url);
|
||||
});
|
||||
// Print in terminal
|
||||
qrcode.generate(qr, { small: true });
|
||||
this.status = WAHASessionStatus.SCAN_QR_CODE;
|
||||
});
|
||||
|
||||
this.whatsapp.on(Events.AUTHENTICATED, () => {
|
||||
this.status = WAHASessionStatus.WORKING;
|
||||
this.qr.save('');
|
||||
this.log.log(`Session '${this.name}' has been authenticated!`);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* START - Methods for API
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auth methods
|
||||
*/
|
||||
public async getQR(): Promise<Buffer> {
|
||||
return Promise.resolve(this.qr.get());
|
||||
}
|
||||
|
||||
async getScreenshot(): Promise<Buffer | string> {
|
||||
if (this.status === WAHASessionStatus.FAILED) {
|
||||
throw new UnprocessableEntityException(
|
||||
@@ -478,8 +507,8 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
hasMedia: Boolean(message.mediaUrl),
|
||||
// @ts-ignore
|
||||
mediaUrl: message.mediaUrl,
|
||||
// @ts-ignore
|
||||
ack: message.ack,
|
||||
ackName: WAMessageAck[message.ack] || ACK_UNKNOWN,
|
||||
location: message.location,
|
||||
vCards: message.vCards,
|
||||
_data: message.rawData,
|
||||
|
||||
@@ -15,6 +15,7 @@ export class SwaggerModuleCore {
|
||||
.setExternalDoc('Documentation', 'https://waha.devlike.pro/')
|
||||
.setVersion(VERSION.version)
|
||||
.addTag('sessions', 'Control WhatsApp sessions')
|
||||
.addTag('auth', 'Authentication')
|
||||
.addTag('screenshot', 'Get screenshot of WhatsApp and show QR code')
|
||||
.addTag('chatting', 'Chatting methods')
|
||||
.addTag(
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { ConsoleLogger } from '@nestjs/common';
|
||||
|
||||
import { WAHAEvents } from '../structures/enums.dto';
|
||||
import { WAWebhook } from '../structures/responses.dto';
|
||||
import { WebhookConfig } from '../structures/webhooks.dto';
|
||||
import { WebhookConfig } from '../structures/webhooks.config.dto';
|
||||
import { WhatsappSession } from './abc/session.abc';
|
||||
import { WebhookConductor, WebhookSender } from './abc/webhooks.abc';
|
||||
import { NotImplementedByEngineError } from './exceptions';
|
||||
import request = require('request');
|
||||
import { WAWebhook } from '../structures/webhooks.dto';
|
||||
|
||||
export class WebhookSenderCore extends WebhookSender {
|
||||
send(json) {
|
||||
|
||||
+7
-1
@@ -25,4 +25,10 @@ function flipObject(object) {
|
||||
);
|
||||
}
|
||||
|
||||
export { flipObject, parseBool };
|
||||
function splitAt(str: string, index) {
|
||||
const fst = [...str];
|
||||
const snd = fst.splice(index);
|
||||
return [fst.join(''), snd.join('')];
|
||||
}
|
||||
|
||||
export { flipObject, parseBool, splitAt };
|
||||
@@ -0,0 +1,24 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class RequestCodeRequest {
|
||||
@ApiProperty({
|
||||
description: 'Mobile phone number in international format',
|
||||
example: '12132132130',
|
||||
})
|
||||
phoneNumber: string;
|
||||
@ApiProperty({
|
||||
description:
|
||||
'How would you like to receive the one time code for registration? |sms|voice. Leave empty for Web pairing.',
|
||||
example: null,
|
||||
required: false,
|
||||
})
|
||||
method: string;
|
||||
}
|
||||
|
||||
export class OTPRequest {
|
||||
code: string;
|
||||
}
|
||||
|
||||
export class PairingCodeResponse {
|
||||
code: string;
|
||||
}
|
||||
@@ -163,3 +163,7 @@ export class MessageReactionRequest extends MessageRequest {
|
||||
})
|
||||
reaction: string;
|
||||
}
|
||||
|
||||
export class WANumberExistResult {
|
||||
numberExists: boolean;
|
||||
}
|
||||
@@ -22,6 +22,7 @@ export enum WAHAEngine {
|
||||
VENOM = 'VENOM',
|
||||
WEBJS = 'WEBJS',
|
||||
NOWEB = 'NOWEB',
|
||||
NOWEB_MOBILE = 'NOWEB_MOBILE',
|
||||
}
|
||||
|
||||
export enum WAHAPresenceStatus {
|
||||
@@ -31,3 +32,13 @@ export enum WAHAPresenceStatus {
|
||||
RECORDING = 'recording',
|
||||
PAUSED = 'paused',
|
||||
}
|
||||
|
||||
export enum WAMessageAck {
|
||||
ERROR = -1,
|
||||
PENDING = 0,
|
||||
SERVER = 1,
|
||||
DEVICE = 2,
|
||||
READ = 3,
|
||||
PLAYED = 4,
|
||||
}
|
||||
export const ACK_UNKNOWN = 'UNKNOWN';
|
||||
@@ -1,52 +1,6 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
import { WAHAEngine, WAHAEvents } from './enums.dto';
|
||||
|
||||
export class WANumberExistResult {
|
||||
numberExists: boolean;
|
||||
}
|
||||
|
||||
export class WAGroupNotification {
|
||||
@ApiProperty({
|
||||
description: 'ID that represents the groupNotification',
|
||||
})
|
||||
id: any;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'Unix timestamp for when the groupNotification was created',
|
||||
})
|
||||
timestamp: number;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'ID for the Chat that this groupNotification was sent for',
|
||||
})
|
||||
chatId: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'ContactId for the user that produced the GroupNotification',
|
||||
})
|
||||
author: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'Extra content',
|
||||
})
|
||||
body: string;
|
||||
|
||||
@ApiProperty({
|
||||
description:
|
||||
'Contact IDs for the users that were affected by this GroupNotification',
|
||||
})
|
||||
recipientIds: string[];
|
||||
}
|
||||
|
||||
export enum WAMessageAck {
|
||||
ACK_ERROR = -1,
|
||||
ACK_PENDING = 0,
|
||||
ACK_SERVER = 1,
|
||||
ACK_DEVICE = 2,
|
||||
ACK_READ = 3,
|
||||
ACK_PLAYED = 4,
|
||||
}
|
||||
import { WAMessageAck } from './enums.dto';
|
||||
|
||||
export class WALocation {
|
||||
description?: string | null;
|
||||
@@ -115,6 +69,11 @@ export class WAMessage {
|
||||
})
|
||||
ack: WAMessageAck;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'ACK status name for the message',
|
||||
})
|
||||
ackName: string;
|
||||
|
||||
@ApiProperty({
|
||||
description:
|
||||
'If the message was sent to a group, this field will contain the user that sent the message.',
|
||||
@@ -139,11 +98,3 @@ export class WAMessage {
|
||||
})
|
||||
_data?: any;
|
||||
}
|
||||
|
||||
export class WAWebhook {
|
||||
event: WAHAEvents;
|
||||
session: string;
|
||||
engine: WAHAEngine;
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
payload: WAMessage | WAGroupNotification | object;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
import { WAHASessionStatus } from './enums.dto';
|
||||
import { WebhookConfig } from './webhooks.dto';
|
||||
import { WebhookConfig } from './webhooks.config.dto';
|
||||
|
||||
/**
|
||||
* Queries
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class RetriesConfiguration {
|
||||
@ApiProperty({
|
||||
example: 2,
|
||||
})
|
||||
delaySeconds: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: 15,
|
||||
})
|
||||
attempts: number;
|
||||
}
|
||||
export class CustomHeader {
|
||||
@ApiProperty({
|
||||
example: 'X-My-Custom-Header',
|
||||
})
|
||||
name: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'Value',
|
||||
})
|
||||
value: string;
|
||||
}
|
||||
|
||||
export class HmacConfiguration {
|
||||
@ApiProperty({
|
||||
example: 'your-secret-key',
|
||||
})
|
||||
key: string;
|
||||
}
|
||||
|
||||
export class WebhookConfig {
|
||||
@ApiProperty({
|
||||
example: 'https://httpbin.org/post',
|
||||
required: true,
|
||||
})
|
||||
url: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: ['message'],
|
||||
required: true,
|
||||
})
|
||||
events: string[];
|
||||
|
||||
@ApiProperty({
|
||||
example: null,
|
||||
})
|
||||
hmac?: HmacConfiguration;
|
||||
|
||||
@ApiProperty({
|
||||
example: null,
|
||||
})
|
||||
retries?: RetriesConfiguration;
|
||||
|
||||
@ApiProperty({
|
||||
example: null,
|
||||
})
|
||||
customHeaders?: CustomHeader[];
|
||||
}
|
||||
@@ -1,60 +1,59 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class RetriesConfiguration {
|
||||
@ApiProperty({
|
||||
example: 2,
|
||||
})
|
||||
delaySeconds: number;
|
||||
import { WAHAEngine, WAHAEvents, WAMessageAck } from './enums.dto';
|
||||
import { WAMessage } from './responses.dto';
|
||||
|
||||
export class WAMessageAckBody {
|
||||
@ApiProperty({
|
||||
example: 15,
|
||||
description: 'Message ID',
|
||||
example: 'false_11111111111@c.us_AAAAAAAAAAAAAAAAAAAA',
|
||||
})
|
||||
attempts: number;
|
||||
}
|
||||
export class CustomHeader {
|
||||
@ApiProperty({
|
||||
example: 'X-My-Custom-Header',
|
||||
})
|
||||
name: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'Value',
|
||||
})
|
||||
value: string;
|
||||
id: string;
|
||||
from: string;
|
||||
to: string;
|
||||
participant: string;
|
||||
fromMe: boolean;
|
||||
ack: WAMessageAck;
|
||||
ackName: string;
|
||||
}
|
||||
|
||||
export class HmacConfiguration {
|
||||
export class WAGroupPayload {
|
||||
@ApiProperty({
|
||||
example: 'your-secret-key',
|
||||
description: 'ID that represents the groupNotification',
|
||||
})
|
||||
key: string;
|
||||
id: any;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'Unix timestamp for when the groupNotification was created',
|
||||
})
|
||||
timestamp: number;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'ID for the Chat that this groupNotification was sent for',
|
||||
})
|
||||
chatId: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'ContactId for the user that produced the GroupNotification',
|
||||
})
|
||||
author: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'Extra content',
|
||||
})
|
||||
body: string;
|
||||
|
||||
@ApiProperty({
|
||||
description:
|
||||
'Contact IDs for the users that were affected by this GroupNotification',
|
||||
})
|
||||
recipientIds: string[];
|
||||
}
|
||||
|
||||
export class WebhookConfig {
|
||||
@ApiProperty({
|
||||
example: 'https://httpbin.org/post',
|
||||
required: true,
|
||||
})
|
||||
url: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: ['message'],
|
||||
required: true,
|
||||
})
|
||||
events: string[];
|
||||
|
||||
@ApiProperty({
|
||||
example: null,
|
||||
})
|
||||
hmac?: HmacConfiguration;
|
||||
|
||||
@ApiProperty({
|
||||
example: null,
|
||||
})
|
||||
retries?: RetriesConfiguration;
|
||||
|
||||
@ApiProperty({
|
||||
example: null,
|
||||
})
|
||||
customHeaders?: CustomHeader[];
|
||||
export class WAWebhook {
|
||||
event: WAHAEvents;
|
||||
session: string;
|
||||
engine: WAHAEngine;
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
payload: WAMessage | WAGroupPayload | WAMessageAckBody | object;
|
||||
}
|
||||
+1
-1
@@ -26,7 +26,7 @@ export function getWAHAVersion(): WAHAVersion {
|
||||
}
|
||||
|
||||
export const VERSION = {
|
||||
version: '2023.8.8',
|
||||
version: '2023.8.23',
|
||||
tier: getWAHAVersion(),
|
||||
browser: getBrowserExecutablePath(),
|
||||
};
|
||||
@@ -7,7 +7,7 @@ __metadata:
|
||||
|
||||
"@adiwajshing/baileys@github:WhiskeySockets/Baileys":
|
||||
version: 6.4.0
|
||||
resolution: "@adiwajshing/baileys@https://github.com/WhiskeySockets/Baileys.git#commit=555cc9b3145ea2a94aeb34eec30eb966154b16f8"
|
||||
resolution: "@adiwajshing/baileys@https://github.com/WhiskeySockets/Baileys.git#commit=49ab16f5925789b85219bec2f35686234dab08a0"
|
||||
dependencies:
|
||||
"@adiwajshing/keyed-db": ^0.2.4
|
||||
"@hapi/boom": ^9.1.3
|
||||
@@ -37,7 +37,7 @@ __metadata:
|
||||
optional: true
|
||||
sharp:
|
||||
optional: true
|
||||
checksum: ce07f852b94750d562f4be56aeeaffb35f5df909fc0e38ae1c6b2d3fcefe8078751e49abfc35f1d30ed9dc68baa2d31fc1114624d8f74301ba2ed455110a2d76
|
||||
checksum: 0faf172db4dcfb9d6df9ff2ef7d2fe5d66aeb7c24e516197a59cbf2bb54648734d5601b992986b9be71e0774bab552be279633d79ea1fc9c8b02426b788973a1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -8275,7 +8275,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"libphonenumber-js@npm:^1.10.20":
|
||||
"libphonenumber-js@npm:^1.10.20, libphonenumber-js@npm:^1.10.36":
|
||||
version: 1.10.36
|
||||
resolution: "libphonenumber-js@npm:1.10.36"
|
||||
checksum: e5a52e13add03db3cb8c0b7401f4cc5a4167a78965954a6e61b64bf412aacd5424e37ea6ab6ef9f77fc8994e7812bd758585f78b8fb871ca75e2c6b6507982fb
|
||||
@@ -13123,6 +13123,7 @@ __metadata:
|
||||
file-type: 16.5.4
|
||||
https-proxy-agent: ^7.0.0
|
||||
jest: 26.4.2
|
||||
libphonenumber-js: ^1.10.36
|
||||
link-preview-js: ^3.0.4
|
||||
lodash: ^4.17.21
|
||||
mime-types: ^2.1.27
|
||||
@@ -13149,8 +13150,8 @@ __metadata:
|
||||
linkType: soft
|
||||
|
||||
"whatsapp-web.js@https://github.com/pedroslopez/whatsapp-web.js":
|
||||
version: 1.21.1-alpha.0
|
||||
resolution: "whatsapp-web.js@https://github.com/pedroslopez/whatsapp-web.js.git#commit=776c1b152ec71081914f551eb33c899eff7a9e99"
|
||||
version: 1.22.1
|
||||
resolution: "whatsapp-web.js@https://github.com/pedroslopez/whatsapp-web.js.git#commit=abac063b779570729476cf42e29dc694e5345ca6"
|
||||
dependencies:
|
||||
"@pedroslopez/moduleraid": ^5.0.2
|
||||
archiver: ^5.3.1
|
||||
@@ -13169,7 +13170,7 @@ __metadata:
|
||||
optional: true
|
||||
unzipper:
|
||||
optional: true
|
||||
checksum: 3377bd18b73004273a606ba2a804e10ce6c4d3fca486a892628acc703a1e35b2d5c28caf7ff4fa1c208542ec19234354b382d763ba66c469ed5c787ac43814a5
|
||||
checksum: 2100a4c826d25c5697fe304f6e036556b4c1c28f310262389c17b10344a182b0203eac6ac8823e3624c1e0c1b93187bd9447a1775aa69e01c7329659a6edcebc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Reference in new issue
Block a user