Compare commits

..
11 Commits
Author SHA1 Message Date
devlikepro 2bc4a59aaf [core] 2024.11.1
Release / amd64 - chrome - chrome (push) Waiting to run
Release / amd64 - chromium - latest (push) Waiting to run
Release / linux/arm64 - chromium - arm (push) Waiting to run
Release / amd64 - none - noweb (push) Waiting to run
Release / linux/arm64 - none - noweb-arm (push) Waiting to run
2024-11-04 12:08:16 +07:00
devlikepro cf886de5ce [core] Add status for WEBJS 2024-11-04 12:08:15 +07:00
devlikepro 9969966ac6 [core] Add labels CRUD
fix #607
2024-11-04 12:08:15 +07:00
devlikepro fb809338e3 [core] 2024.10.14
Release / amd64 - chrome - chrome (push) Waiting to run
Release / amd64 - chromium - latest (push) Waiting to run
Release / linux/arm64 - chromium - arm (push) Waiting to run
Release / amd64 - none - noweb (push) Waiting to run
Release / linux/arm64 - none - noweb-arm (push) Waiting to run
2024-10-31 16:45:38 +07:00
devlikepro c6284eb994 [core] fix /api/messages
fix #622
2024-10-31 16:45:15 +07:00
devlikepro 454bda4c82 [core] fix /api/messages
Release / amd64 - chrome - chrome (push) Waiting to run
Release / amd64 - chromium - latest (push) Waiting to run
Release / linux/arm64 - chromium - arm (push) Waiting to run
Release / amd64 - none - noweb (push) Waiting to run
Release / linux/arm64 - none - noweb-arm (push) Waiting to run
fix #620
2024-10-31 13:07:30 +07:00
devlikepro 26e21441a0 [core] 2024.10.13 2024-10-31 13:04:25 +07:00
devlikepro 2edef0166e [core] add waves on voice back
fix #621
2024-10-31 13:03:46 +07:00
devlikepro 05cb89779b [core] 2024.10.12
Release / amd64 - chrome - chrome (push) Waiting to run
Release / amd64 - chromium - latest (push) Waiting to run
Release / linux/arm64 - chromium - arm (push) Waiting to run
Release / amd64 - none - noweb (push) Waiting to run
Release / linux/arm64 - none - noweb-arm (push) Waiting to run
2024-10-30 16:56:44 +07:00
devlikepro c0b2524952 [core] remove single process 2024-10-30 16:56:30 +07:00
devlikepro f1bb445593 [core] 2024.10.11
Release / amd64 - chrome - chrome (push) Waiting to run
Release / amd64 - chromium - latest (push) Waiting to run
Release / linux/arm64 - chromium - arm (push) Waiting to run
Release / amd64 - none - noweb (push) Waiting to run
Release / linux/arm64 - none - noweb-arm (push) Waiting to run
2024-10-29 17:09:58 +07:00
12 changed files with 350 additions and 16 deletions

No files matched your search

+2
View File
@@ -6,6 +6,7 @@ import {
Put,
Query,
UsePipes,
ValidationPipe,
} from '@nestjs/common';
import { ApiOperation, ApiSecurity, ApiTags } from '@nestjs/swagger';
import { WAHAValidationPipe } from '@waha/nestjs/pipes/WAHAValidationPipe';
@@ -172,6 +173,7 @@ export class ChattingController {
@Get('/messages')
@ApiOperation({ summary: 'Get messages in a chat' })
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
async getMessages(
@Query() query: GetMessageQuery,
@Query() filter: GetChatMessagesFilter,
+91 -2
View File
@@ -1,4 +1,16 @@
import { Body, Controller, Get, Param, Put } from '@nestjs/common';
import {
Body,
Controller,
Delete,
Get,
NotFoundException,
Param,
Post,
Put,
UnprocessableEntityException,
UsePipes,
ValidationPipe,
} from '@nestjs/common';
import { ApiOperation, ApiSecurity, ApiTags } from '@nestjs/swagger';
import { WhatsappSession } from '@waha/core/abc/session.abc';
import { ChatIdApiParam } from '@waha/nestjs/params/ChatIdApiParam';
@@ -6,7 +18,12 @@ import {
SessionApiParam,
WorkingSessionParam,
} from '@waha/nestjs/params/SessionApiParam';
import { Label, SetLabelsRequest } from '@waha/structures/labels.dto';
import {
Label,
LabelBody,
SetLabelsRequest,
} from '@waha/structures/labels.dto';
import * as lodash from 'lodash';
import { SessionManager } from '../core/abc/manager.abc';
@@ -23,6 +40,78 @@ export class LabelsController {
return session.getLabels();
}
@Post('/')
@SessionApiParam
@ApiOperation({ summary: 'Create a new label' })
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
async create(
@WorkingSessionParam session: WhatsappSession,
@Body() body: LabelBody,
): Promise<Label> {
const labelDto = body.toDTO();
const labels = await session.getLabels();
if (labels.length >= 20) {
throw new UnprocessableEntityException('Maximum 20 labels allowed');
}
const labelByName = lodash.find(labels, { name: labelDto.name });
if (labelByName) {
throw new UnprocessableEntityException(
`Label with '${labelByName.name}' already exists, id: ${labelByName.id}`,
);
}
return session.createLabel(labelDto);
}
@Put('/:labelId')
@SessionApiParam
@ApiOperation({ summary: 'Update a label' })
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
async update(
@WorkingSessionParam session: WhatsappSession,
@Param('labelId') labelId: string,
@Body() body: LabelBody,
): Promise<Label> {
const label = await session.getLabel(labelId);
if (!label) {
throw new NotFoundException('Label not found');
}
const labelDto = body.toDTO();
const labels = await session.getLabels();
const labelByName = lodash.find(labels, { name: labelDto.name });
if (labelByName) {
throw new UnprocessableEntityException(
`Label with '${labelByName.name}' already exists, id: ${labelByName.id}`,
);
}
label.name = labelDto.name;
label.color = labelDto.color;
label.colorHex = Label.toHex(label.color);
await session.updateLabel(label);
return label;
}
@Delete('/:labelId')
@SessionApiParam
@ApiOperation({ summary: 'Delete a label' })
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
async delete(
@WorkingSessionParam session: WhatsappSession,
@Param('labelId') labelId: string,
): Promise<any> {
const label = await session.getLabel(labelId);
if (!label) {
throw new NotFoundException('Label not found');
}
await session.deleteLabel(label);
return { result: true };
}
@Get('/chats/:chatId')
@SessionApiParam
@ChatIdApiParam
+19 -3
View File
@@ -9,12 +9,13 @@ import {
GetChatMessagesQuery,
} from '@waha/structures/chats.dto';
import { SendButtonsRequest } from '@waha/structures/chatting.buttons.dto';
import { Label, LabelID } from '@waha/structures/labels.dto';
import { Label, LabelDTO, LabelID } from '@waha/structures/labels.dto';
import { PaginationParams } from '@waha/structures/pagination.dto';
import { WAMessage } from '@waha/structures/responses.dto';
import { LoggerBuilder } from '@waha/utils/logging';
import { EventEmitter } from 'events';
import * as fs from 'fs';
import * as lodash from 'lodash';
import { Logger } from 'pino';
import { MessageId } from 'whatsapp-web.js';
@@ -66,7 +67,6 @@ import { NotImplementedByEngineError } from '../exceptions';
import { IMediaManager } from '../media/IMediaManager';
import { QR } from '../QR';
import { DataStore } from './DataStore';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const qrcode = require('qrcode-terminal');
@@ -204,7 +204,7 @@ export abstract class WhatsappSession {
'--password-store=basic',
'--renderer-process-limit=2', // https://superuser.com/questions/654565/how-to-run-google-chrome-in-a-single-process
'--safebrowsing-disable-auto-update',
'--single-process',
// '--single-process',
'--use-mock-keychain',
'--window-size=1280,720',
];
@@ -387,11 +387,27 @@ export abstract class WhatsappSession {
/**
* Labels methods
*/
public async getLabel(labelId: string): Promise<Label | undefined> {
const labels = await this.getLabels();
return lodash.find(labels, { id: labelId });
}
public getLabels(): Promise<Label[]> {
throw new NotImplementedByEngineError();
}
public async createLabel(label: LabelDTO): Promise<Label> {
throw new NotImplementedByEngineError();
}
public async updateLabel(label: Label): Promise<Label> {
throw new NotImplementedByEngineError();
}
public async deleteLabel(label: Label): Promise<void> {
throw new NotImplementedByEngineError();
}
public getChatsByLabelId(labelId: string) {
throw new NotImplementedByEngineError();
}
+51 -1
View File
@@ -21,7 +21,10 @@ import makeWASocket, {
WAMessageKey,
} from '@adiwajshing/baileys';
import { WACallEvent } from '@adiwajshing/baileys/lib/Types/Call';
import { Label as NOWEBLabel } from '@adiwajshing/baileys/lib/Types/Label';
import {
Label as NOWEBLabel,
LabelActionBody,
} from '@adiwajshing/baileys/lib/Types/Label';
import { LabelAssociationType } from '@adiwajshing/baileys/lib/Types/LabelAssociation';
import { isLidUser } from '@adiwajshing/baileys/lib/WABinary/jid-utils';
import { Logger as BaileysLogger } from '@adiwajshing/baileys/node_modules/pino';
@@ -49,6 +52,7 @@ import { BinaryFile, RemoteFile } from '@waha/structures/files.dto';
import {
Label,
LabelChatAssociation,
LabelDTO,
LabelID,
} from '@waha/structures/labels.dto';
import { ReplyToMessage } from '@waha/structures/message.dto';
@@ -875,6 +879,52 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
return labels.map(this.toLabel);
}
public async createLabel(label: LabelDTO): Promise<Label> {
const labels = await this.store.getLabels();
const highestLabelId = lodash.max(
labels.map((label) => parseInt(label.id)),
);
const labelId = highestLabelId ? highestLabelId + 1 : 1;
const labelAction: LabelActionBody = {
id: labelId.toString(),
name: label.name,
color: label.color,
deleted: false,
predefinedId: undefined,
};
await this.sock.addLabel(undefined, labelAction);
return {
id: labelId.toString(),
name: label.name,
color: label.color,
colorHex: Label.toHex(label.color),
};
}
public async updateLabel(label: Label): Promise<Label> {
const labelAction: LabelActionBody = {
id: label.id,
name: label.name,
color: label.color,
deleted: false,
predefinedId: undefined,
};
await this.sock.addLabel(undefined, labelAction);
return label;
}
public async deleteLabel(label: Label): Promise<void> {
const labelAction: LabelActionBody = {
id: label.id,
name: label.name,
color: label.color,
deleted: true,
predefinedId: undefined,
};
await this.sock.addLabel(undefined, labelAction);
}
public async getChatsByLabelId(labelId: string) {
const chats = await this.store.getChatsByLabelId(labelId);
// Remove unreadCount, it's not ready yet
+71
View File
@@ -1,5 +1,7 @@
import { GetChatMessagesFilter } from '@waha/structures/chats.dto';
import { Label } from '@waha/structures/labels.dto';
import { PaginationParams } from '@waha/structures/pagination.dto';
import { TextStatus } from '@waha/structures/status.dto';
import * as lodash from 'lodash';
import { Client } from 'whatsapp-web.js';
import { Message } from 'whatsapp-web.js/src/structures';
@@ -45,6 +47,44 @@ export class WebjsClient extends Client {
});
}
async createLabel(name: string, color: number): Promise<number> {
const labelId: number = await this.pupPage.evaluate(
async (name, color) => {
// @ts-ignore
return await window.WAHA.WAWebBizLabelEditingAction.labelAddAction(
name,
color,
);
},
name,
color,
);
return labelId;
}
async deleteLabel(label: Label) {
return await this.pupPage.evaluate(async (label) => {
// @ts-ignore
return await window.WAHA.WAWebBizLabelEditingAction.labelDeleteAction(
label.id,
label.name,
label.color,
);
}, label);
}
async updateLabel(label: Label) {
return await this.pupPage.evaluate(async (label) => {
// @ts-ignore
return await window.WAHA.WAWebBizLabelEditingAction.labelEditAction(
label.id,
label.name,
undefined, // predefinedId
label.color,
);
}, label);
}
async getChats(pagination?: PaginationParams) {
if (lodash.isEmpty(pagination)) {
return await super.getChats();
@@ -62,6 +102,37 @@ export class WebjsClient extends Client {
return chats.map((chat) => ChatFactory.create(this, chat));
}
async sendTextStatus(status: TextStatus) {
// Convert from hex to number
const waColor = 'FF' + status.backgroundColor.replace('#', '');
const color = parseInt(waColor, 16);
const textStatus = {
text: status.text,
color: color,
font: status.font,
};
const sentMsg = await this.pupPage.evaluate(async (status) => {
// @ts-ignore
await window.Store.SendStatus.sendStatusTextMsgAction(status);
// @ts-ignore
const meUser = window.Store.User.getMeUser();
// @ts-ignore
const myStatus = window.Store.Status.getModelsArray().findLast(
(x) => x.id == meUser,
);
if (!myStatus) {
return undefined;
}
// @ts-ignore
const msg = myStatus.msgs.last();
// @ts-ignore
return msg ? window.WWebJS.getMessageModel(msg) : undefined;
}, textStatus);
return sentMsg ? new Message(this, sentMsg) : undefined;
}
async getMessages(
chatId: string,
filter: GetChatMessagesFilter,
+3
View File
@@ -1,5 +1,8 @@
exports.LoadWAHA = () => {
window.WAHA = {};
window.WAHA.WAWebBizLabelEditingAction = window.require(
'WAWebBizLabelEditingAction',
);
window.WAHA.getChats = async (pagination) => {
let chats = window.Store.Chat.getModelsArray().slice();
+42 -1
View File
@@ -1,8 +1,10 @@
import { UnprocessableEntityException } from '@nestjs/common';
import {
getChannelInviteLink,
WAHAInternalEvent,
WhatsappSession,
} from '@waha/core/abc/session.abc';
import { toJID } from '@waha/core/engines/noweb/session.noweb.core';
import { LocalAuth } from '@waha/core/engines/webjs/LocalAuth';
import { WebjsClient } from '@waha/core/engines/webjs/WebjsClient';
import {
@@ -58,11 +60,16 @@ import {
ParticipantsRequest,
SettingsSecurityChangeInfo,
} from '@waha/structures/groups.dto';
import { Label, LabelID } from '@waha/structures/labels.dto';
import { Label, LabelDTO, LabelID } from '@waha/structures/labels.dto';
import { ReplyToMessage } from '@waha/structures/message.dto';
import { PaginationParams } from '@waha/structures/pagination.dto';
import { WAMessage, WAMessageReaction } from '@waha/structures/responses.dto';
import { MeInfo } from '@waha/structures/sessions.dto';
import {
BROADCAST_ID,
StatusRequest,
TextStatus,
} from '@waha/structures/status.dto';
import { WAMessageRevokedBody } from '@waha/structures/webhooks.dto';
import { PaginatorInMemory } from '@waha/utils/Paginator';
import { sleep, waitUntil } from '@waha/utils/promiseTimeout';
@@ -632,6 +639,24 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
return labels.map(this.toLabel);
}
public async createLabel(label: LabelDTO): Promise<Label> {
const labelId = await this.whatsapp.createLabel(label.name, label.color);
return {
id: labelId.toString(),
name: label.name,
color: label.color,
colorHex: Label.toHex(label.color),
};
}
public async updateLabel(label: Label): Promise<Label> {
return await this.whatsapp.updateLabel(label);
}
public deleteLabel(label: Label): Promise<void> {
return this.whatsapp.deleteLabel(label);
}
public getChatsByLabelId(labelId: string) {
return this.whatsapp.getChatsByLabelId(labelId);
}
@@ -950,6 +975,22 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
}
}
/**
* Status methods
*/
protected checkStatusRequest(request: StatusRequest) {
if (request.contacts?.length > 0) {
const msg =
"WEBJS doesn't accept 'contacts'. Remove the field to send status to all contacts.";
throw new UnprocessableEntityException(msg);
}
}
public sendTextStatus(status: TextStatus) {
this.checkStatusRequest(status);
return this.whatsapp.sendTextStatus(status);
}
/**
* END - Methods for API
*/
+2
View File
@@ -49,9 +49,11 @@ export class ChatQuery extends SessionQuery {
export class GetMessageQuery extends GetChatMessagesQuery {
@IsNotEmpty()
@IsString()
session: string = WHATSAPP_DEFAULT_SESSION_NAME;
@ChatIdProperty()
@IsString()
chatId: string;
}
+62 -1
View File
@@ -1,5 +1,7 @@
import { UnprocessableEntityException } from '@nestjs/common';
import { ApiProperty } from '@nestjs/swagger';
import { ChatIdProperty } from '@waha/structures/properties.dto';
import { IsHexColor, IsNumber, IsOptional, IsString } from 'class-validator';
const Colors = [
'#ff9485',
@@ -24,6 +26,65 @@ const Colors = [
'#9368cf',
];
export class LabelBody {
@ApiProperty({
example: 'Lead',
description: 'Label name',
})
@IsString()
name: string;
@ApiProperty({
example: '#ff9485',
description: 'Color in hex',
})
@IsHexColor()
@IsOptional()
colorHex?: string;
@ApiProperty({
example: null,
description: 'Color number, not hex',
})
@IsNumber()
@IsOptional()
color?: number;
toDTO(): LabelDTO {
if (this.color != null && this.colorHex != null) {
throw new UnprocessableEntityException(
"Use either 'color' or 'colorHex'",
);
}
if (this.color == null && this.colorHex == null) {
throw new UnprocessableEntityException(
"'color' or 'colorHex' is required",
);
}
if (this.colorHex) {
const color = Colors.indexOf(this.colorHex);
if (color == -1) {
throw new UnprocessableEntityException(
"Invalid 'colorHex'. Possible values: " + Colors.join(', '),
);
}
this.color = color;
}
return {
name: this.name,
color: this.color,
};
}
}
export class LabelDTO {
name: string;
color: number;
}
export class Label {
@ApiProperty({
example: '1',
@@ -39,7 +100,7 @@ export class Label {
@ApiProperty({
example: 0,
description: 'Internal color number, not hex',
description: 'Color number, not hex',
})
color: number;
+2 -3
View File
@@ -11,10 +11,9 @@ import {
export const BROADCAST_ID = 'status@broadcast';
class StatusRequest {
export class StatusRequest {
@ApiProperty({
description:
'it is always necessary to inform the list of contacts that will have access to the posted status',
description: 'Contact list to send the status to.',
example: ['55xxxxxxxxxxx@c.us'],
})
contacts = ['55xxxxxxxxxxx@c.us'];
+1 -1
View File
@@ -33,7 +33,7 @@ export function getEngineName(): string {
}
export const VERSION: WAHAEnvironment = {
version: '2024.10.10',
version: '2024.11.1',
engine: getEngineName(),
tier: getWAHAVersion(),
browser: getBrowserExecutablePath(),
+4 -4
View File
@@ -7,7 +7,7 @@ __metadata:
"@adiwajshing/baileys@github:devlikeapro/Baileys#fork-master-channels-678":
version: 6.7.8
resolution: "@adiwajshing/baileys@https://github.com/devlikeapro/Baileys.git#commit=1a3d827b5d9633e0b82d95362fc07cf1060aa32f"
resolution: "@adiwajshing/baileys@https://github.com/devlikeapro/Baileys.git#commit=c44cb586e9860ae97f6b3cf206e51fa13edfe7ba"
dependencies:
"@adiwajshing/keyed-db": ^0.2.4
"@hapi/boom": ^9.1.3
@@ -39,7 +39,7 @@ __metadata:
optional: true
sharp:
optional: true
checksum: fd4053af48069c3cdd6017075490d2061302e8006acbcf4d9a831159a1ae213548d135acbc4f2b8217c48bf989dbdc5c96a904df71becf2b0576a7a61998cc83
checksum: a98a8bead0b14df2abe21de47bdcde22378fc8425cf189f5a96ac57a9946646c1bb7aedc400dcf9913b1dd61d1e5bc1c6f149743ff54f6503691a9c0ccfaa1f9
languageName: node
linkType: hard
@@ -12384,7 +12384,7 @@ __metadata:
"whatsapp-web.js@github:devlikeapro/whatsapp-web.js#fork-main-channels":
version: 1.26.0
resolution: "whatsapp-web.js@https://github.com/devlikeapro/whatsapp-web.js.git#commit=76329eedc27b07c11e38bf1b60e6c2476c11dd73"
resolution: "whatsapp-web.js@https://github.com/devlikeapro/whatsapp-web.js.git#commit=aa90f7378659a237f30cda6d368359a1f81904dc"
dependencies:
"@pedroslopez/moduleraid": ^5.0.2
archiver: ^5.3.1
@@ -12402,7 +12402,7 @@ __metadata:
optional: true
unzipper:
optional: true
checksum: b8d4fcb1fd1365a38f07f95dd2eb1fd743c6c406fc7ac679662ddeded80c441720bc8400222a37d61765ebcbb5c6799f169d5ac45f12f58b5421c55bb9f2ab7e
checksum: 7c914e9cdd4a25c967e057d0cb5019973f0556f6220320e4bcbc0666669801b92abf97c2cc783762ef462d0006123953e233136f457689ebac395260fe69a5fc
languageName: node
linkType: hard