Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9362c5d6ae | ||
|
|
117a9108c0 | ||
|
|
5214e461f2 | ||
|
|
9bdb178b7d | ||
|
|
9c526ffdba | ||
|
|
f80a74edd1 | ||
|
|
7d8c6c0a62 | ||
|
|
17b26b869b | ||
|
|
dfbe54e92f | ||
|
|
2321de409b | ||
|
|
502287a258 | ||
|
|
052ff0ea6e | ||
|
|
2b76789cdf | ||
|
|
7bbf5df231 | ||
|
|
794a04e7d3 | ||
|
|
645467f13a |
No files matched your search
+1
-1
@@ -131,7 +131,7 @@ RUN if [ "$USE_BROWSER" = "chromium" ]; then \
|
||||
# Install Chrome
|
||||
# Available versions:
|
||||
# https://www.ubuntuupdates.org/package/google_chrome/stable/main/base/google-chrome-stable
|
||||
ARG CHROME_VERSION="135.0.7049.114-1"
|
||||
ARG CHROME_VERSION="137.0.7151.55-1"
|
||||
RUN if [ "$USE_BROWSER" = "chrome" ]; then \
|
||||
wget --no-verbose -O /tmp/chrome.deb https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_${CHROME_VERSION}_amd64.deb \
|
||||
&& apt-get update \
|
||||
|
||||
@@ -41,7 +41,7 @@ up-noweb-libsignal:
|
||||
. ${NVM_DIR}/nvm.sh && nvm exec yarn up libsignal@github:devlikeapro/libsignal-node#fork-master
|
||||
|
||||
up-webjs:
|
||||
. ${NVM_DIR}/nvm.sh && nvm exec yarn up whatsapp-web.js@github:devlikeapro/whatsapp-web.js#fork-main-channels
|
||||
. ${NVM_DIR}/nvm.sh && nvm exec yarn up whatsapp-web.js@github:devlikeapro/whatsapp-web.js#fork-main-2025-06-09
|
||||
|
||||
start-proxy:
|
||||
docker run --rm -d --name squid-container -e TZ=UTC -p 3128:3128 ubuntu/squid:5.2-22.04_beta
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+4
-4
@@ -88,7 +88,7 @@
|
||||
"sharp": "^0.33.4",
|
||||
"swagger-ui-express": "^4.1.4",
|
||||
"ulid": "^2.3.0",
|
||||
"whatsapp-web.js": "github:devlikeapro/whatsapp-web.js#fork-main-channels",
|
||||
"whatsapp-web.js": "github:devlikeapro/whatsapp-web.js#fork-main-2025-06-09",
|
||||
"write-file-atomic": "^6.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
@@ -97,12 +97,12 @@
|
||||
"resolutions": {
|
||||
"bufferutil": "^4.0.8",
|
||||
"ws": "^8.18.0",
|
||||
"puppeteer": "^24.7.2",
|
||||
"puppeteer": "^24.10.0",
|
||||
"whatwg-url": "13.0.0",
|
||||
"libsignal": "github:devlikeapro/libsignal-node#fork-master"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@grpc/grpc-js": "^1.12.4",
|
||||
"@grpc/grpc-js": "^1.13.4",
|
||||
"@grpc/proto-loader": "^0.7.13",
|
||||
"@nestjs/cli": "^11.0.0",
|
||||
"@nestjs/schematics": "^11.0.0",
|
||||
@@ -117,7 +117,7 @@
|
||||
"eslint-config-prettier": "^6.10.0",
|
||||
"eslint-plugin-import": "^2.20.1",
|
||||
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||
"grpc-tools": "^1.12.4",
|
||||
"grpc-tools": "^1.13.0",
|
||||
"jest": "^29.7.0",
|
||||
"prettier": "^1.19.1",
|
||||
"protoc-gen-ts": "^0.8.7",
|
||||
|
||||
+2
-2
@@ -12,9 +12,9 @@ touch "$OUTPUT_FILE"
|
||||
# Find all .md files in the source directory and combine them
|
||||
find "$SOURCE_DIR" -type f -name "*.ts" | while read -r file; do
|
||||
# Add file name to OUTPUT_FILE
|
||||
echo -e "\n-------" >> "$OUTPUT_FILE"
|
||||
echo "\n-------" >> "$OUTPUT_FILE"
|
||||
echo "File: $file" >> "$OUTPUT_FILE"
|
||||
echo -e "-------\n" >> "$OUTPUT_FILE"
|
||||
echo "-------\n" >> "$OUTPUT_FILE"
|
||||
# Append the content of the file to the output file
|
||||
cat "$file" >> "$OUTPUT_FILE"
|
||||
done
|
||||
|
||||
@@ -36,8 +36,8 @@ class AuthController {
|
||||
summary: 'Get QR code for pairing WhatsApp API.',
|
||||
})
|
||||
@SessionApiParam
|
||||
@ApiFileAcceptHeader(Base64File, QRCodeValue)
|
||||
@UseInterceptors(new BufferResponseInterceptor())
|
||||
@ApiFileAcceptHeader('image/png', Base64File, QRCodeValue)
|
||||
@UseInterceptors(new BufferResponseInterceptor('image/png'))
|
||||
async getQR(
|
||||
@QRCodeSessionParam session: WhatsappSession,
|
||||
@Query() query: QRCodeQuery,
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Post,
|
||||
UnprocessableEntityException,
|
||||
UseInterceptors,
|
||||
} from '@nestjs/common';
|
||||
import { ApiOperation, ApiSecurity, ApiTags } from '@nestjs/swagger';
|
||||
import { SessionManager } from '@waha/core/abc/manager.abc';
|
||||
import { WAMimeType } from '@waha/core/media/WAMimeType';
|
||||
import { ApiFileAcceptHeader } from '@waha/nestjs/ApiFileAcceptHeader';
|
||||
import {
|
||||
SessionApiParam,
|
||||
WorkingSessionParam,
|
||||
} from '@waha/nestjs/params/SessionApiParam';
|
||||
import {
|
||||
FileDTO,
|
||||
VideoFileDTO,
|
||||
VoiceFileDTO,
|
||||
} from '@waha/structures/media.dto';
|
||||
|
||||
import { WhatsappSession } from '../core/abc/session.abc';
|
||||
import { BufferResponseInterceptor } from '../nestjs/BufferResponseInterceptor';
|
||||
|
||||
@ApiSecurity('api_key')
|
||||
@Controller('api/:session/media')
|
||||
@ApiTags('🖼️ Media')
|
||||
class MediaController {
|
||||
constructor(private manager: SessionManager) {}
|
||||
|
||||
@Post('convert/voice')
|
||||
@ApiOperation({
|
||||
summary: 'Convert voice to WhatsApp format (opus)',
|
||||
})
|
||||
@SessionApiParam
|
||||
@UseInterceptors(
|
||||
new BufferResponseInterceptor(WAMimeType.VOICE, 'output.opus'),
|
||||
)
|
||||
@ApiFileAcceptHeader(WAMimeType.VOICE)
|
||||
async convertVoice(
|
||||
@WorkingSessionParam session: WhatsappSession,
|
||||
@Body() file: VoiceFileDTO,
|
||||
): Promise<Buffer> {
|
||||
const data = await this.buffer(session, file);
|
||||
const content = await session.mediaConverter.voice(data);
|
||||
return content;
|
||||
}
|
||||
|
||||
@Post('convert/video')
|
||||
@ApiOperation({
|
||||
summary: 'Convert video to WhatsApp format (mp4)',
|
||||
})
|
||||
@SessionApiParam
|
||||
@UseInterceptors(
|
||||
new BufferResponseInterceptor(WAMimeType.VIDEO, 'output.mp4'),
|
||||
)
|
||||
@ApiFileAcceptHeader(WAMimeType.VIDEO)
|
||||
async convertVideo(
|
||||
@WorkingSessionParam session: WhatsappSession,
|
||||
@Body() file: VideoFileDTO,
|
||||
): Promise<Buffer> {
|
||||
const data = await this.buffer(session, file);
|
||||
const content = await session.mediaConverter.video(data);
|
||||
return content;
|
||||
}
|
||||
|
||||
private async buffer(
|
||||
session: WhatsappSession,
|
||||
file: FileDTO,
|
||||
): Promise<Buffer> {
|
||||
if ('url' in file) {
|
||||
return session.fetch(file.url);
|
||||
} else if ('data' in file) {
|
||||
return Buffer.from(file.data, 'base64');
|
||||
} else {
|
||||
throw new UnprocessableEntityException(
|
||||
'Either "url" or "data" must be specified.',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { MediaController };
|
||||
@@ -21,8 +21,8 @@ export class ScreenshotController {
|
||||
constructor(private manager: SessionManager) {}
|
||||
|
||||
@Get('/screenshot')
|
||||
@UseInterceptors(new BufferResponseInterceptor())
|
||||
@ApiFileAcceptHeader()
|
||||
@UseInterceptors(new BufferResponseInterceptor('image/jpeg'))
|
||||
@ApiFileAcceptHeader('image/jpeg')
|
||||
async screenshot(
|
||||
@Res({ passthrough: true }) res: Response,
|
||||
@Query() sessionQuery: SessionQuery,
|
||||
|
||||
@@ -76,6 +76,7 @@ export class SwaggerConfiguratorCore {
|
||||
'🏷️ Labels',
|
||||
'Labels - available only for WhatsApp Business accounts',
|
||||
)
|
||||
.addTag('🖼️ Media', 'Media methods')
|
||||
.addTag('🔍 Observability', 'Other methods')
|
||||
.addTag('🗄️ Storage', 'Storage methods')
|
||||
.addApiKey({
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { isJidBroadcast } from '@adiwajshing/baileys/lib/WABinary/jid-utils';
|
||||
import {
|
||||
CoreMediaConverter,
|
||||
IMediaConverter,
|
||||
} from '@waha/core/media/IConverter';
|
||||
import { MessagesForRead } from '@waha/core/utils/convertors';
|
||||
import { isJidNewsletter } from '@waha/core/utils/jids';
|
||||
import {
|
||||
@@ -24,16 +28,15 @@ import { SendButtonsRequest } from '@waha/structures/chatting.buttons.dto';
|
||||
import { BinaryFile, RemoteFile } from '@waha/structures/files.dto';
|
||||
import { Label, LabelDTO, LabelID } from '@waha/structures/labels.dto';
|
||||
import { LidToPhoneNumber } from '@waha/structures/lids.dto';
|
||||
import {
|
||||
LimitOffsetParams,
|
||||
PaginationParams,
|
||||
} from '@waha/structures/pagination.dto';
|
||||
import { PaginationParams } from '@waha/structures/pagination.dto';
|
||||
import { MessageSource, WAMessage } from '@waha/structures/responses.dto';
|
||||
import { DefaultMap } from '@waha/utils/DefaultMap';
|
||||
import { generatePrefixedId } from '@waha/utils/ids';
|
||||
import { LoggerBuilder } from '@waha/utils/logging';
|
||||
import { complete } from '@waha/utils/reactive/complete';
|
||||
import { SwitchObservable } from '@waha/utils/reactive/SwitchObservable';
|
||||
import axios from 'axios';
|
||||
import axiosRetry from 'axios-retry';
|
||||
import * as fs from 'fs';
|
||||
import * as lodash from 'lodash';
|
||||
import * as NodeCache from 'node-cache';
|
||||
@@ -109,9 +112,12 @@ 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');
|
||||
|
||||
axiosRetry(axios, { retries: 3 });
|
||||
|
||||
const CHROME_PATH = '/usr/bin/google-chrome-stable';
|
||||
const CHROMIUM_PATH = '/usr/bin/chromium';
|
||||
|
||||
@@ -168,6 +174,8 @@ export abstract class WhatsappSession {
|
||||
stdTTL: 10 * 60, // 10 minutes
|
||||
});
|
||||
|
||||
public mediaConverter: IMediaConverter = new CoreMediaConverter();
|
||||
|
||||
public constructor({
|
||||
name,
|
||||
printQR,
|
||||
@@ -993,6 +1001,15 @@ export abstract class WhatsappSession {
|
||||
const api = this.sentMessageIds.has(id);
|
||||
return api ? MessageSource.API : MessageSource.APP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the content from the specified URL and returns it as a Buffer.
|
||||
*/
|
||||
public async fetch(url: string): Promise<Buffer> {
|
||||
return axios.get(url, { responseType: 'arraybuffer' }).then((res) => {
|
||||
return Buffer.from(res.data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function getGroupInviteLink(code: string) {
|
||||
|
||||
@@ -36,6 +36,7 @@ import { EventsController } from '../api/events.controller';
|
||||
import { GroupsController } from '../api/groups.controller';
|
||||
import { HealthController } from '../api/health.controller';
|
||||
import { LabelsController } from '../api/labels.controller';
|
||||
import { MediaController } from '../api/media.controller';
|
||||
import { PingController } from '../api/ping.controller';
|
||||
import { PresenceController } from '../api/presence.controller';
|
||||
import { ScreenshotController } from '../api/screenshot.controller';
|
||||
@@ -141,6 +142,7 @@ export const CONTROLLERS = [
|
||||
ServerController,
|
||||
ServerDebugController,
|
||||
VersionController,
|
||||
MediaController,
|
||||
];
|
||||
const PROVIDERS = [
|
||||
{
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { WhatsappConfigService } from '@waha/config.service';
|
||||
import { BootstrapConfig } from '@waha/core/engines/gows/GowsBootstrap';
|
||||
import { GowsConfig } from '@waha/core/engines/gows/session.gows.core';
|
||||
|
||||
@Injectable()
|
||||
export class GowsEngineConfigService {
|
||||
constructor(protected configService: ConfigService) {}
|
||||
constructor(
|
||||
protected configService: ConfigService,
|
||||
protected whatsappConfigService: WhatsappConfigService,
|
||||
) {}
|
||||
|
||||
getBootstrapConfig(): BootstrapConfig {
|
||||
return {
|
||||
path: this.configService.get('WAHA_GOWS_PATH'),
|
||||
socket: this.getSocket(),
|
||||
pprof: this.whatsappConfigService.debugModeEnabled,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ export async function isUnixSocket(socketPath: string): Promise<boolean> {
|
||||
export interface BootstrapConfig {
|
||||
path: string;
|
||||
socket: string;
|
||||
pprof?: boolean;
|
||||
}
|
||||
|
||||
export class GowsBootstrap implements EngineBootstrap {
|
||||
@@ -44,6 +45,7 @@ export class GowsBootstrap implements EngineBootstrap {
|
||||
this.logger,
|
||||
this.config.path,
|
||||
this.config.socket,
|
||||
this.config.pprof,
|
||||
);
|
||||
this.gows.start(() => {
|
||||
this.logger.info(`GOWS stopped, exiting...`);
|
||||
|
||||
@@ -14,13 +14,22 @@ export class GowsSubprocess {
|
||||
private logger: Logger,
|
||||
readonly path: string,
|
||||
readonly socket: string,
|
||||
readonly pprof: boolean = false,
|
||||
) {}
|
||||
|
||||
start(onExit: (code: number) => void) {
|
||||
this.logger.info('Starting GOWS subprocess...');
|
||||
this.logger.debug(`GOWS path '${this.path}', socket: '${this.socket}'...`);
|
||||
|
||||
this.child = spawn(this.path, ['--socket', this.socket], {
|
||||
const args = ['--socket', this.socket];
|
||||
if (this.pprof) {
|
||||
this.logger.info('Debug mode enabled, adding pprof flags');
|
||||
args.push('--pprof');
|
||||
args.push('--pprof-port=6060');
|
||||
args.push('--pprof-host=0.0.0.0');
|
||||
}
|
||||
|
||||
this.child = spawn(this.path, args, {
|
||||
detached: true,
|
||||
});
|
||||
this.logger.debug(`GOWS started with PID: ${this.child.pid}`);
|
||||
|
||||
@@ -671,7 +671,7 @@ var EventStreamService = exports.EventStreamService = {
|
||||
},
|
||||
};
|
||||
|
||||
exports.EventStreamClient = grpc.makeGenericClientConstructor(EventStreamService);
|
||||
exports.EventStreamClient = grpc.makeGenericClientConstructor(EventStreamService, 'EventStream');
|
||||
var MessageServiceService = exports.MessageServiceService = {
|
||||
//
|
||||
// Session management
|
||||
@@ -1381,4 +1381,4 @@ getMessageById: {
|
||||
},
|
||||
};
|
||||
|
||||
exports.MessageServiceClient = grpc.makeGenericClientConstructor(MessageServiceService);
|
||||
exports.MessageServiceClient = grpc.makeGenericClientConstructor(MessageServiceService, 'MessageService');
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Expose a function to the page if it does not exist
|
||||
*
|
||||
* NOTE:
|
||||
* Rewrite it to 'upsertFunction' after updating Puppeteer to 20.6 or higher
|
||||
* using page.removeExposedFunction
|
||||
* https://pptr.dev/api/puppeteer.page.removeExposedFunction
|
||||
*
|
||||
* @param {import(puppeteer).Page} page
|
||||
* @param {string} name
|
||||
* @param {Function} fn
|
||||
*/
|
||||
export async function exposeFunctionIfAbsent(page, name, fn) {
|
||||
const exist = await page.evaluate((name) => {
|
||||
return !!window[name];
|
||||
}, name);
|
||||
if (exist) {
|
||||
return;
|
||||
}
|
||||
await page.exposeFunction(name, fn);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { exposeFunctionIfAbsent } from '@waha/core/engines/webjs/Puppeteer';
|
||||
import { WebJSPresence } from '@waha/core/engines/webjs/types';
|
||||
import { GetChatMessagesFilter } from '@waha/structures/chats.dto';
|
||||
import { Label } from '@waha/structures/labels.dto';
|
||||
@@ -10,7 +11,6 @@ import * as lodash from 'lodash';
|
||||
import { Page } from 'puppeteer';
|
||||
import { Client, Events } from 'whatsapp-web.js';
|
||||
import { Message } from 'whatsapp-web.js/src/structures';
|
||||
import { exposeFunctionIfAbsent } from 'whatsapp-web.js/src/util/Puppeter';
|
||||
|
||||
import { CallErrorEvent, PAGE_CALL_ERROR_EVENT, WPage } from './WPage';
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { AvailableInPlusVersion } from '../exceptions';
|
||||
|
||||
export interface IMediaConverter {
|
||||
voice(content: Buffer): Promise<Buffer>;
|
||||
video(content: Buffer): Promise<Buffer>;
|
||||
}
|
||||
|
||||
export class CoreMediaConverter implements IMediaConverter {
|
||||
video(content: Buffer): Promise<Buffer> {
|
||||
throw new AvailableInPlusVersion();
|
||||
}
|
||||
|
||||
voice(content: Buffer): Promise<Buffer> {
|
||||
throw new AvailableInPlusVersion();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export enum WAMimeType {
|
||||
VOICE = 'audio/ogg; codecs=opus',
|
||||
VIDEO = 'video/mp4',
|
||||
}
|
||||
@@ -11,7 +11,7 @@ function getRefSchemaPaths(models) {
|
||||
/**
|
||||
* Decorator to add a file accept header to the swagger documentation
|
||||
*/
|
||||
export function ApiFileAcceptHeader(...models) {
|
||||
export function ApiFileAcceptHeader(mimetype: string, ...models) {
|
||||
models = models.length ? models : [Base64File];
|
||||
return applyDecorators(
|
||||
// Add extra models, otherwise it'll give a error
|
||||
@@ -20,7 +20,7 @@ export function ApiFileAcceptHeader(...models) {
|
||||
ApiResponse({
|
||||
status: 200,
|
||||
content: {
|
||||
'image/png': {
|
||||
[mimetype]: {
|
||||
schema: {
|
||||
type: 'string',
|
||||
format: 'binary',
|
||||
|
||||
@@ -21,6 +21,11 @@ import { Base64File } from '../structures/files.dto';
|
||||
export class BufferResponseInterceptor<T>
|
||||
implements NestInterceptor<Buffer, Base64File | StreamableFile>
|
||||
{
|
||||
constructor(
|
||||
private mimetype: string,
|
||||
private filename: string = null,
|
||||
) {}
|
||||
|
||||
intercept(
|
||||
context: ExecutionContext,
|
||||
next: CallHandler,
|
||||
@@ -28,27 +33,35 @@ export class BufferResponseInterceptor<T>
|
||||
const ctx = context.switchToHttp();
|
||||
const request = ctx.getRequest<Request>();
|
||||
const response = ctx.getResponse<Response>();
|
||||
return next.handle().pipe(map(processBuffer));
|
||||
|
||||
function processBuffer(buffer: Buffer) {
|
||||
// Check buffer is Buffer
|
||||
if (!Buffer.isBuffer(buffer)) {
|
||||
return buffer;
|
||||
}
|
||||
return next
|
||||
.handle()
|
||||
.pipe(map((buffer) => this.processBuffer(buffer, request, response)));
|
||||
}
|
||||
|
||||
const accept = request.headers['accept'];
|
||||
if (accept == 'application/json') {
|
||||
return {
|
||||
mimetype: 'image/png',
|
||||
data: buffer.toString('base64'),
|
||||
};
|
||||
}
|
||||
const file = new StreamableFile(buffer);
|
||||
response.set({
|
||||
'Content-Type': 'image/png',
|
||||
'Content-Length': buffer.length,
|
||||
});
|
||||
return file;
|
||||
processBuffer(buffer: Buffer, request: Request, response: Response) {
|
||||
// Check buffer is Buffer
|
||||
if (!Buffer.isBuffer(buffer)) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
const accept = request.headers['accept'];
|
||||
if (accept == 'application/json') {
|
||||
return {
|
||||
mimetype: this.mimetype,
|
||||
data: buffer.toString('base64'),
|
||||
};
|
||||
}
|
||||
const file = new StreamableFile(buffer);
|
||||
response.set({
|
||||
'Content-Type': this.mimetype,
|
||||
'Content-Length': buffer.length,
|
||||
});
|
||||
if (this.filename) {
|
||||
response.set({
|
||||
'Content-Disposition': `attachment; filename="${this.filename}"`,
|
||||
});
|
||||
}
|
||||
return file;
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,11 @@ import {
|
||||
VoiceBinaryFile,
|
||||
VoiceRemoteFile,
|
||||
} from './files.dto';
|
||||
import { ChatIdProperty, ReplyToProperty } from './properties.dto';
|
||||
import {
|
||||
ChatIdProperty,
|
||||
ConvertApiProperty,
|
||||
ReplyToProperty,
|
||||
} from './properties.dto';
|
||||
|
||||
/**
|
||||
* Queries
|
||||
@@ -320,6 +324,9 @@ export class MessageVoiceRequest extends ChatRequest {
|
||||
|
||||
@ReplyToProperty()
|
||||
reply_to?: string;
|
||||
|
||||
@ConvertApiProperty()
|
||||
convert: boolean;
|
||||
}
|
||||
|
||||
@ApiExtraModels(VideoRemoteFile, VideoBinaryFile)
|
||||
@@ -346,6 +353,9 @@ export class MessageVideoRequest extends ChatRequest {
|
||||
example: false,
|
||||
})
|
||||
asNote?: boolean;
|
||||
|
||||
@ConvertApiProperty()
|
||||
convert: boolean;
|
||||
}
|
||||
|
||||
export class MessageLinkPreviewRequest extends ChatRequest {
|
||||
|
||||
@@ -35,3 +35,34 @@ export class WAMedia {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
error?: object;
|
||||
}
|
||||
|
||||
export class FileDTO {
|
||||
@ApiProperty({
|
||||
description: 'The URL for the file',
|
||||
})
|
||||
url?: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'Base64 content of the file',
|
||||
example: null,
|
||||
})
|
||||
data?: string;
|
||||
}
|
||||
|
||||
export class VoiceFileDTO extends FileDTO {
|
||||
@ApiProperty({
|
||||
description: 'The URL for the voice file',
|
||||
example:
|
||||
process.env.WHATSAPP_SWAGGER_VIDEO_EXAMPLE_URL ||
|
||||
'https://github.com/devlikeapro/waha/raw/core/examples/voice.mp3',
|
||||
})
|
||||
url?: string;
|
||||
}
|
||||
|
||||
export class VideoFileDTO extends FileDTO {
|
||||
@ApiProperty({
|
||||
description: 'The URL for the video file',
|
||||
example: 'https://github.com/devlikeapro/waha/raw/core/examples/video.mp4',
|
||||
})
|
||||
url?: string;
|
||||
}
|
||||
@@ -30,6 +30,14 @@ function ReplyToProperty() {
|
||||
});
|
||||
}
|
||||
|
||||
export function ConvertApiProperty() {
|
||||
return ApiProperty({
|
||||
description:
|
||||
'Convert the input file to the required format using ffmpeg before sending',
|
||||
example: true,
|
||||
});
|
||||
}
|
||||
|
||||
export {
|
||||
ChatIdProperty,
|
||||
MessageIdOnlyProperty,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ApiExtraModels, ApiProperty, getSchemaPath } from '@nestjs/swagger';
|
||||
import { ConvertApiProperty } from '@waha/structures/properties.dto';
|
||||
|
||||
import {
|
||||
BinaryFile,
|
||||
@@ -63,6 +64,9 @@ export class VoiceStatus extends StatusRequest {
|
||||
file: VoiceRemoteFile | VoiceBinaryFile;
|
||||
|
||||
backgroundColor: string = '#38b42f';
|
||||
|
||||
@ConvertApiProperty()
|
||||
convert: boolean;
|
||||
}
|
||||
|
||||
@ApiExtraModels(VideoRemoteFile, VideoBinaryFile)
|
||||
@@ -76,6 +80,9 @@ export class VideoStatus extends StatusRequest {
|
||||
file: VideoRemoteFile | VideoBinaryFile;
|
||||
|
||||
caption?: string;
|
||||
|
||||
@ConvertApiProperty()
|
||||
convert: boolean;
|
||||
}
|
||||
|
||||
export class DeleteStatusRequest extends StatusRequest {
|
||||
|
||||
+3
-1
@@ -33,9 +33,11 @@ export function getEngineName(): string {
|
||||
}
|
||||
|
||||
export const VERSION: WAHAEnvironment = {
|
||||
version: '2025.5.6',
|
||||
version: '2025.6.2',
|
||||
engine: getEngineName(),
|
||||
tier: getWAHAVersion(),
|
||||
browser:
|
||||
getEngineName() === WAHAEngine.WEBJS ? getBrowserExecutablePath() : null,
|
||||
};
|
||||
|
||||
export const IsChrome = VERSION.browser?.includes('chrome');
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"waha": {
|
||||
"gows": {
|
||||
"repo": "devlikeapro/gows",
|
||||
"ref": "v1.0.7"
|
||||
"ref": "v1.0.8"
|
||||
},
|
||||
"dashboard": {
|
||||
"repo": "devlikeapro/dashboard",
|
||||
|
||||
@@ -1299,13 +1299,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@grpc/grpc-js@npm:^1.12.4":
|
||||
version: 1.12.4
|
||||
resolution: "@grpc/grpc-js@npm:1.12.4"
|
||||
"@grpc/grpc-js@npm:^1.13.4":
|
||||
version: 1.13.4
|
||||
resolution: "@grpc/grpc-js@npm:1.13.4"
|
||||
dependencies:
|
||||
"@grpc/proto-loader": ^0.7.13
|
||||
"@js-sdsl/ordered-map": ^4.4.2
|
||||
checksum: 6dab69c70173735b775717361662ed5a931d2ca1bc9f3ed5f7095a05f26eb59489b1805b0a8f78b77f34d48a896f358ca951f0ce38d8053d18b0d5d0fd92837f
|
||||
checksum: fe5db84bbbcd07cc1b68d1683b7fbe9cfcc5c3a60655ecc17fb3e1cd2adc4c1ce891b15e6e9a9c2140f6891def6f93b509a60d2bce253d13b317f9136e968451
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -2650,20 +2650,20 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@puppeteer/browsers@npm:2.10.3":
|
||||
version: 2.10.3
|
||||
resolution: "@puppeteer/browsers@npm:2.10.3"
|
||||
"@puppeteer/browsers@npm:2.10.5":
|
||||
version: 2.10.5
|
||||
resolution: "@puppeteer/browsers@npm:2.10.5"
|
||||
dependencies:
|
||||
debug: ^4.4.0
|
||||
debug: ^4.4.1
|
||||
extract-zip: ^2.0.1
|
||||
progress: ^2.0.3
|
||||
proxy-agent: ^6.5.0
|
||||
semver: ^7.7.1
|
||||
semver: ^7.7.2
|
||||
tar-fs: ^3.0.8
|
||||
yargs: ^17.7.2
|
||||
bin:
|
||||
browsers: lib/cjs/main-cli.js
|
||||
checksum: 34bd9c915a6c05577e8bbe0ae3118b275a467cc53233843d531663a716e6bcd7ab36cb320ae8fed31872f0706beeb24afb975576f11ecd80d1937e8e44f2c473
|
||||
checksum: d294a30ed91f58ad3317ccc18054a1785542e21284d3ab455364bf734bb8a1bfa93d4434dba530ff4225491908f427ca71e5b042e77d1c8fa23e57416c185aef
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -5532,15 +5532,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"chromium-bidi@npm:4.1.1":
|
||||
version: 4.1.1
|
||||
resolution: "chromium-bidi@npm:4.1.1"
|
||||
"chromium-bidi@npm:5.1.0":
|
||||
version: 5.1.0
|
||||
resolution: "chromium-bidi@npm:5.1.0"
|
||||
dependencies:
|
||||
mitt: ^3.0.1
|
||||
zod: ^3.24.1
|
||||
peerDependencies:
|
||||
devtools-protocol: "*"
|
||||
checksum: 30ed480364c00f6608e1f173dc0ba224d5d7d97941994ce89352fb807ebe1bd91fdafaf0afe419282af547603f6f03a5fe9684138cbefbba901b260d05cfe226
|
||||
checksum: 2f9f84305cebc5cf8a3817e2c1f220814a9d5f994ea91a3d08c758b4a77d1ed73210722953e50b935a30893903ee984c5a664818094d8e046d8891bbe2b72805
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -6118,7 +6118,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"debug@npm:^4.3.5":
|
||||
"debug@npm:^4.3.5, debug@npm:^4.4.1":
|
||||
version: 4.4.1
|
||||
resolution: "debug@npm:4.4.1"
|
||||
dependencies:
|
||||
@@ -6284,10 +6284,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"devtools-protocol@npm:0.0.1439962":
|
||||
version: 0.0.1439962
|
||||
resolution: "devtools-protocol@npm:0.0.1439962"
|
||||
checksum: f1ef3892da29d1da9fba18c8c64da5e0a46153ead084f3cb8c7f1c2cb4b61fe69b2d6a174f89555a4b3db7d52134b60efce79c8b71248768bd5faad83c63caf2
|
||||
"devtools-protocol@npm:0.0.1452169":
|
||||
version: 0.0.1452169
|
||||
resolution: "devtools-protocol@npm:0.0.1452169"
|
||||
checksum: f9d3eb8b5d88ae0a0da3bb2699e038f8310ac70160aaf714e726b06025593fbca7b261a838606bd6ecf46a20b8b36f10fa96323bfd7cfa34480e6f572d802e6a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -7871,15 +7871,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"grpc-tools@npm:^1.12.4":
|
||||
version: 1.12.4
|
||||
resolution: "grpc-tools@npm:1.12.4"
|
||||
"grpc-tools@npm:^1.13.0":
|
||||
version: 1.13.0
|
||||
resolution: "grpc-tools@npm:1.13.0"
|
||||
dependencies:
|
||||
"@mapbox/node-pre-gyp": ^1.0.5
|
||||
bin:
|
||||
grpc_tools_node_protoc: bin/protoc.js
|
||||
grpc_tools_node_protoc_plugin: bin/protoc_plugin.js
|
||||
checksum: 5ea946c2d231e2b58be48b14e12f2982b44845f62d05327cf84f67fae30355c7a781d8443b0988f9db77d4eb219f15e5f98e869f6a14c4276084726e48dc8ec0
|
||||
checksum: 0fbd4007f752f23ac49b83e2c6c516f004018e5e01bef669720c8aaf8b507d224983d15f6b90abe725164cdb77a4a449f8906a573e94c59e532f38a1ef221185
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -11164,33 +11164,33 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"puppeteer-core@npm:24.8.0":
|
||||
version: 24.8.0
|
||||
resolution: "puppeteer-core@npm:24.8.0"
|
||||
"puppeteer-core@npm:24.10.0":
|
||||
version: 24.10.0
|
||||
resolution: "puppeteer-core@npm:24.10.0"
|
||||
dependencies:
|
||||
"@puppeteer/browsers": 2.10.3
|
||||
chromium-bidi: 4.1.1
|
||||
debug: ^4.4.0
|
||||
devtools-protocol: 0.0.1439962
|
||||
"@puppeteer/browsers": 2.10.5
|
||||
chromium-bidi: 5.1.0
|
||||
debug: ^4.4.1
|
||||
devtools-protocol: 0.0.1452169
|
||||
typed-query-selector: ^2.12.0
|
||||
ws: ^8.18.1
|
||||
checksum: e89db314280404a509c00cded220c89c0704084f2162968d88ed4e334be36869cc8f2675ed5207937f5785ac1d03787b958ef0eaecdaa9d4c9c860e63e37f341
|
||||
ws: ^8.18.2
|
||||
checksum: 16783646bef4d3113fd0193c28f4875d881b93f8ec8f5aa7cb121aa39a0de43f40b3a374d4b8f9c4d3997abe01a2176f452a1be507155067ff87e6d46feff4a3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"puppeteer@npm:^24.7.2":
|
||||
version: 24.8.0
|
||||
resolution: "puppeteer@npm:24.8.0"
|
||||
"puppeteer@npm:^24.10.0":
|
||||
version: 24.10.0
|
||||
resolution: "puppeteer@npm:24.10.0"
|
||||
dependencies:
|
||||
"@puppeteer/browsers": 2.10.3
|
||||
chromium-bidi: 4.1.1
|
||||
"@puppeteer/browsers": 2.10.5
|
||||
chromium-bidi: 5.1.0
|
||||
cosmiconfig: ^9.0.0
|
||||
devtools-protocol: 0.0.1439962
|
||||
puppeteer-core: 24.8.0
|
||||
devtools-protocol: 0.0.1452169
|
||||
puppeteer-core: 24.10.0
|
||||
typed-query-selector: ^2.12.0
|
||||
bin:
|
||||
puppeteer: lib/cjs/puppeteer/node/cli.js
|
||||
checksum: 699d732b0a2097308d64e38e0fbd5caefa23897eb83c30616f4c433a9c3a41f4b47b4ade6dae60ef998df1cf99e68e431f927312e7a438e720b5d50f9e308ddd
|
||||
checksum: 50a84d3beed45bcd8f7f3800d0ad3397fe9e24d0cd72b4b596bc99e601b7b8a4b41e18a017c55772f2edf7c00ba2981cae78789029c8d0d5e3fd4448ffb5b5b0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -11721,12 +11721,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"semver@npm:^7.7.1":
|
||||
version: 7.7.1
|
||||
resolution: "semver@npm:7.7.1"
|
||||
"semver@npm:^7.7.2":
|
||||
version: 7.7.2
|
||||
resolution: "semver@npm:7.7.2"
|
||||
bin:
|
||||
semver: bin/semver.js
|
||||
checksum: 586b825d36874007c9382d9e1ad8f93888d8670040add24a28e06a910aeebd673a2eb9e3bf169c6679d9245e66efb9057e0852e70d9daa6c27372aab1dda7104
|
||||
checksum: dd94ba8f1cbc903d8eeb4dd8bf19f46b3deb14262b6717d0de3c804b594058ae785ef2e4b46c5c3b58733c99c83339068203002f9e37cfe44f7e2cc5e3d2f621
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -13308,7 +13308,7 @@ __metadata:
|
||||
"@adiwajshing/keyed-db": ^0.2.4
|
||||
"@aws-sdk/client-s3": ^3.633.0
|
||||
"@aws-sdk/s3-request-presigner": ^3.633.0
|
||||
"@grpc/grpc-js": ^1.12.4
|
||||
"@grpc/grpc-js": ^1.13.4
|
||||
"@grpc/proto-loader": ^0.7.13
|
||||
"@nestjs/axios": ^3.0.2
|
||||
"@nestjs/cli": ^11.0.0
|
||||
@@ -13355,7 +13355,7 @@ __metadata:
|
||||
file-type: 16.5.4
|
||||
fs-extra: ^11.2.0
|
||||
google-protobuf: ^3.21.4
|
||||
grpc-tools: ^1.12.4
|
||||
grpc-tools: ^1.13.0
|
||||
https-proxy-agent: ^7.0.0
|
||||
jest: ^29.7.0
|
||||
joi: ^17.13.3
|
||||
@@ -13392,7 +13392,7 @@ __metadata:
|
||||
tsconfig-paths: ^4.1.0
|
||||
typescript: ^4.8.4
|
||||
ulid: ^2.3.0
|
||||
whatsapp-web.js: "github:devlikeapro/whatsapp-web.js#fork-main-channels"
|
||||
whatsapp-web.js: "github:devlikeapro/whatsapp-web.js#fork-main-2025-06-09"
|
||||
write-file-atomic: ^6.0.0
|
||||
yargs: ^17.7.2
|
||||
dependenciesMeta:
|
||||
@@ -13486,9 +13486,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"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=26562719b4068713d588b7e8d51652a9f0e4f683"
|
||||
"whatsapp-web.js@github:devlikeapro/whatsapp-web.js#fork-main-2025-06-09":
|
||||
version: 1.30.1-alpha.2
|
||||
resolution: "whatsapp-web.js@https://github.com/devlikeapro/whatsapp-web.js.git#commit=f0e8284c9a281fa15ce2086d5668c02011947416"
|
||||
dependencies:
|
||||
"@pedroslopez/moduleraid": ^5.0.2
|
||||
archiver: ^5.3.1
|
||||
@@ -13506,7 +13506,7 @@ __metadata:
|
||||
optional: true
|
||||
unzipper:
|
||||
optional: true
|
||||
checksum: e1fe71ce6959542ec964b1d0e190071f0796c37459732c641b0b5be719383415b9f1008dab443713b20caf0562fecd3c005be5f64b3f992b56587122029666cd
|
||||
checksum: ad0b97ac3b5246801af33e4e7cc34ce34b8541a3737bb97f53322f4612b8eb435eec2b47a6ef9f7f794649324d70041e3f6f6f5453be8d4b74da0051334ee98e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Reference in new issue
Block a user