Compare commits

..
13 Commits
Author SHA1 Message Date
devlikepro 6346d4143d [core] 2025.2.2
Release / WEBJS - chrome - amd64 - chrome (push) Waiting to run
Release / WEBJS - chromium - amd64 - latest (push) Waiting to run
Release / WEBJS - chromium - linux/arm64 - arm (push) Waiting to run
Release / GOWS - none - amd64 - gows (push) Waiting to run
Release / GOWS - none - linux/arm64 - gows-arm (push) Waiting to run
Release / NOWEB - none - amd64 - noweb (push) Waiting to run
Release / NOWEB - none - linux/arm64 - noweb-arm (push) Waiting to run
2025-02-10 08:57:14 +07:00
devlikepro fd8dc88760 [core] rm auth/authorize-code 2025-02-10 08:57:14 +07:00
devlikepro b2810f390e [core] max connections 3000 2025-02-10 08:57:14 +07:00
devlikepro 23d3cd0f4b [core] Up GOWS - build proto 2025-02-10 08:57:13 +07:00
devlikepro 4a3c76773d [core] Up GOWS 2025-02-10 08:57:12 +07:00
devlikepro d23e7604f0 [core] NOWEB Channels Search 2025-02-10 08:57:12 +07:00
devlikepro 0b3f6c6eff [core] GOWS - Search Channels 2025-02-10 08:57:12 +07:00
devlikepro f2869c892b [core] WEBJS - ensure suffix 2025-02-10 08:57:12 +07:00
devlikepro 3755a9529b [core] GOWS - Channels Search, Messages Preview 2025-02-10 08:57:11 +07:00
devlikepro 890f0593ee [core] NOWEB - Channels Search, Messages Preview 2025-02-10 08:57:11 +07:00
devlikepro e6d666b5b0 [core] WEBJS Channels Search, Messages Preview 2025-02-10 08:57:10 +07:00
devlikepro f440acf145 [core] Channels Search, Messages Preview - API 2025-02-10 08:57:10 +07:00
devlikepro 1ad0e0c6dd [core] Add proto files
fixes #784
2025-02-07 08:41:37 +07:00
22 changed files with 18667 additions and 96 deletions

No files matched your search

-1
View File
@@ -1,5 +1,4 @@
Dockerfile
src/core/engines/gows/grpc
src/core/engines/gows/proto
.*sessions
sessions
-1
View File
@@ -1,4 +1,3 @@
src/core/engines/gows/grpc
src/core/engines/gows/proto
.env
*.heapsnapshot
-1
View File
@@ -18,7 +18,6 @@ RUN yarn install
WORKDIR /git
ADD . /git
RUN yarn install
RUN yarn gows:proto
RUN yarn build && find ./dist -name "*.d.ts" -delete
#
+1 -1
View File
@@ -38,7 +38,7 @@ services:
# command:
# - postgres
# - "-c"
# - "max_connections=1000"
# - "max_connections=3000"
# NOTE: Only if you're using MongoDB
# https://waha.devlike.pro/docs/how-to/storages/#sessions---mongodb
-39
View File
@@ -6,7 +6,6 @@ import {
Query,
UseInterceptors,
} from '@nestjs/common';
import { UnprocessableEntityException } from '@nestjs/common/exceptions/unprocessable-entity.exception';
import { ApiOperation, ApiSecurity, ApiTags } from '@nestjs/swagger';
import { ApiFileAcceptHeader } from '@waha/nestjs/ApiFileAcceptHeader';
import {
@@ -19,8 +18,6 @@ import { SessionManager } from '../core/abc/manager.abc';
import { WhatsappSession } from '../core/abc/session.abc';
import { BufferResponseInterceptor } from '../nestjs/BufferResponseInterceptor';
import {
CaptchaBody,
OTPRequest,
QRCodeFormat,
QRCodeQuery,
QRCodeValue,
@@ -63,42 +60,6 @@ class AuthController {
) {
return session.requestCode(request.phoneNumber, request.method, request);
}
@Post('authorize-code')
@SessionApiParam
@ApiOperation({
summary: 'Send OTP authentication code.',
})
authorizeCode(
@SessionParam session: WhatsappSession,
@Body() request: OTPRequest,
) {
return session.authorizeCode(request.code);
}
@Get('captcha')
@SessionApiParam
@ApiFileAcceptHeader()
@UseInterceptors(new BufferResponseInterceptor())
@ApiOperation({
summary: 'Get captcha image.',
})
async getCaptcha(@SessionParam session: WhatsappSession): Promise<Buffer> {
const image = await session.getCaptcha();
return image.get();
}
@Post('captcha')
@SessionApiParam
@ApiOperation({
summary: 'Enter captcha code.',
})
saveCaptcha(
@SessionParam session: WhatsappSession,
@Body() body: CaptchaBody,
) {
return session.saveCaptcha(body.code);
}
}
export { AuthController };
+102 -5
View File
@@ -3,31 +3,129 @@ import {
Controller,
Delete,
Get,
HttpCode,
HttpStatus,
Param,
Post,
Query,
UsePipes,
} from '@nestjs/common';
import { ApiOperation, ApiSecurity, ApiTags } from '@nestjs/swagger';
import { ApiOperation, ApiParam, ApiSecurity, ApiTags } from '@nestjs/swagger';
import { ChannelsInfoServiceCore } from '@waha/core/services/ChannelsInfoServiceCore';
import {
SessionApiParam,
WorkingSessionParam,
} from '@waha/nestjs/params/SessionApiParam';
import { WAHAValidationPipe } from '@waha/nestjs/pipes/WAHAValidationPipe';
import {
Channel,
ChannelCategory,
ChannelCountry,
ChannelListResult,
ChannelMessage,
ChannelSearchByText,
ChannelSearchByView,
ChannelView,
CreateChannelRequest,
ListChannelsQuery,
NewsletterIdApiParam,
NewsletterIdOrInviteCodeApiParam,
PreviewChannelMessages,
} from '@waha/structures/channels.dto';
import { SessionManager } from '../core/abc/manager.abc';
import { isNewsletter, WhatsappSession } from '../core/abc/session.abc';
import {
isNewsletter,
parseChannelInviteLink,
WhatsappSession,
} from '../core/abc/session.abc';
@ApiSecurity('api_key')
@Controller('api/:session/channels')
@ApiTags('📢 Channels')
export class ChannelsController {
constructor(private manager: SessionManager) {}
constructor(
private manager: SessionManager,
private channelsInfoService: ChannelsInfoServiceCore,
) {}
@Post('/search/by-view')
@HttpCode(HttpStatus.OK)
@SessionApiParam
@UsePipes(new WAHAValidationPipe())
@ApiOperation({ summary: 'Search for channels (by view)' })
async searchByView(
@WorkingSessionParam session: WhatsappSession,
@Body() request: ChannelSearchByView,
): Promise<ChannelListResult> {
return session.searchChannelsByView(request);
}
@Post('/search/by-text')
@HttpCode(HttpStatus.OK)
@SessionApiParam
@UsePipes(new WAHAValidationPipe())
@ApiOperation({ summary: 'Search for channels (by text)' })
async searchByText(
@WorkingSessionParam session: WhatsappSession,
@Body() request: ChannelSearchByText,
): Promise<ChannelListResult> {
return session.searchChannelsByText(request);
}
@Get('/search/views')
@SessionApiParam
@ApiOperation({ summary: 'Get list of views for channel search' })
getSearchViews(): Promise<ChannelView[]> {
return this.channelsInfoService.getViews();
}
@Get('/search/countries')
@SessionApiParam
@ApiOperation({ summary: 'Get list of countries for channel search' })
getSearchCountries(): Promise<ChannelCountry[]> {
return this.channelsInfoService.getCountries();
}
@Get('/search/categories')
@SessionApiParam
@ApiOperation({ summary: 'Get list of categories for channel search' })
getSearchCategories(): Promise<ChannelCategory[]> {
return this.channelsInfoService.getCategories();
}
@Get(':id/messages/preview')
@SessionApiParam
@UsePipes(new WAHAValidationPipe())
@ApiParam({
name: 'id',
description: 'Channel id or invite code',
required: true,
type: 'string',
schema: {
default: '0029Va4K0PZ5a245NkngBA2M',
},
})
@ApiOperation({
summary: 'Preview channel messages',
description:
'You can use either ' +
'invite code (https://www.whatsapp.com/channel/123) or (123)' +
'OR' +
'Channel ID (123@newsletter).',
})
async previewChannelMessages(
@WorkingSessionParam session: WhatsappSession,
@Param('id') code: string,
@Query() query: PreviewChannelMessages,
): Promise<ChannelMessage[]> {
if (isNewsletter(code)) {
const channel = await session.channelsGetChannel(code);
code = parseChannelInviteLink(channel.invite);
}
const inviteCode = parseChannelInviteLink(code);
return session.previewChannelMessages(inviteCode, query);
}
@Get('')
@SessionApiParam
@@ -76,8 +174,7 @@ export class ChannelsController {
if (isNewsletter(id)) {
return session.channelsGetChannel(id);
} else {
// https://www.whatsapp.com/channel/123 => 123
const inviteCode = id.split('/').pop();
const inviteCode = parseChannelInviteLink(id);
return session.channelsGetChannelByInviteCode(inviteCode);
}
}
+43 -13
View File
@@ -1,7 +1,12 @@
import {
Channel,
ChannelListResult,
ChannelMessage,
ChannelSearchByText,
ChannelSearchByView,
CreateChannelRequest,
ListChannelsQuery,
PreviewChannelMessages,
} from '@waha/structures/channels.dto';
import {
ChatSummary,
@@ -326,24 +331,12 @@ export abstract class WhatsappSession {
throw new NotImplementedByEngineError();
}
public authorizeCode(code: string) {
throw new NotImplementedByEngineError();
}
abstract getScreenshot(): Promise<Buffer>;
public getSessionMeInfo(): MeInfo | null {
return null;
}
public getCaptcha(): Promise<QR> {
throw new NotImplementedByEngineError();
}
public saveCaptcha(code: string) {
throw new NotImplementedByEngineError();
}
/**
* Other methods
*/
@@ -537,8 +530,16 @@ export abstract class WhatsappSession {
}
protected async refreshProfilePicture(id: string) {
let fn: Promise<string>;
if (isNewsletter(id)) {
fn = this.channelsGetChannel(id).then(
(channel: Channel) => channel.picture || channel.preview,
);
} else {
fn = this.fetchContactProfilePicture(id);
}
this.profilePictures.del(id);
const url = await this.fetchContactProfilePicture(id).catch((err) => {
const url = await fn.catch((err) => {
this.logger.warn('Error fetching profile picture');
this.logger.warn(err, err.stack);
return null;
@@ -661,6 +662,25 @@ export abstract class WhatsappSession {
/**
* Channels methods
*/
public searchChannelsByView(
query: ChannelSearchByView,
): Promise<ChannelListResult> {
throw new NotImplementedByEngineError();
}
public searchChannelsByText(
query: ChannelSearchByText,
): Promise<ChannelListResult> {
throw new NotImplementedByEngineError();
}
public async previewChannelMessages(
inviteCode: string,
query: PreviewChannelMessages,
): Promise<ChannelMessage[]> {
throw new NotImplementedByEngineError();
}
public channelsList(query: ListChannelsQuery): Promise<Channel[]> {
throw new NotImplementedByEngineError();
}
@@ -772,3 +792,13 @@ export function isNewsletter(jid: string) {
export function getChannelInviteLink(code: string) {
return `https://whatsapp.com/channel/${code}`;
}
export function parseChannelInviteLink(link: string): string {
// https://www.whatsapp.com/channel/123 => 123
const code = link.split('/').pop();
return code;
}
export function getPublicUrlFromDirectPath(directPath: string) {
return `https://pps.whatsapp.net${directPath}`;
}
+2
View File
@@ -14,6 +14,7 @@ import { GowsEngineConfigService } from '@waha/core/config/GowsEngineConfigServi
import { WebJSEngineConfigService } from '@waha/core/config/WebJSEngineConfigService';
import { MediaLocalStorageModule } from '@waha/core/media/local/media.local.storage.module';
import { MediaLocalStorageConfig } from '@waha/core/media/local/MediaLocalStorageConfig';
import { ChannelsInfoServiceCore } from '@waha/core/services/ChannelsInfoServiceCore';
import { BufferJsonReplacerInterceptor } from '@waha/nestjs/BufferJsonReplacerInterceptor';
import {
getPinoHttpUseLevel,
@@ -148,6 +149,7 @@ const PROVIDERS = [
provide: APP_INTERCEPTOR,
useClass: BufferJsonReplacerInterceptor,
},
ChannelsInfoServiceCore,
DashboardConfigServiceCore,
SwaggerConfigServiceCore,
WebJSEngineConfigService,
File diff suppressed because it is too large. Load diff
+748
View File
@@ -0,0 +1,748 @@
// GENERATED CODE -- DO NOT EDIT!
'use strict';
var grpc = require('@grpc/grpc-js');
var gows_pb = require('./gows_pb.js');
function serialize_messages_ChatPresenceRequest(arg) {
if (!(arg instanceof gows_pb.ChatPresenceRequest)) {
throw new Error('Expected argument of type messages.ChatPresenceRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_ChatPresenceRequest(buffer_arg) {
return gows_pb.ChatPresenceRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_CheckPhonesRequest(arg) {
if (!(arg instanceof gows_pb.CheckPhonesRequest)) {
throw new Error('Expected argument of type messages.CheckPhonesRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_CheckPhonesRequest(buffer_arg) {
return gows_pb.CheckPhonesRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_CheckPhonesResponse(arg) {
if (!(arg instanceof gows_pb.CheckPhonesResponse)) {
throw new Error('Expected argument of type messages.CheckPhonesResponse');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_CheckPhonesResponse(buffer_arg) {
return gows_pb.CheckPhonesResponse.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_CreateNewsletterRequest(arg) {
if (!(arg instanceof gows_pb.CreateNewsletterRequest)) {
throw new Error('Expected argument of type messages.CreateNewsletterRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_CreateNewsletterRequest(buffer_arg) {
return gows_pb.CreateNewsletterRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_DownloadMediaRequest(arg) {
if (!(arg instanceof gows_pb.DownloadMediaRequest)) {
throw new Error('Expected argument of type messages.DownloadMediaRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_DownloadMediaRequest(buffer_arg) {
return gows_pb.DownloadMediaRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_DownloadMediaResponse(arg) {
if (!(arg instanceof gows_pb.DownloadMediaResponse)) {
throw new Error('Expected argument of type messages.DownloadMediaResponse');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_DownloadMediaResponse(buffer_arg) {
return gows_pb.DownloadMediaResponse.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_Empty(arg) {
if (!(arg instanceof gows_pb.Empty)) {
throw new Error('Expected argument of type messages.Empty');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_Empty(buffer_arg) {
return gows_pb.Empty.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_EntityByIdRequest(arg) {
if (!(arg instanceof gows_pb.EntityByIdRequest)) {
throw new Error('Expected argument of type messages.EntityByIdRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_EntityByIdRequest(buffer_arg) {
return gows_pb.EntityByIdRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_EventJson(arg) {
if (!(arg instanceof gows_pb.EventJson)) {
throw new Error('Expected argument of type messages.EventJson');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_EventJson(buffer_arg) {
return gows_pb.EventJson.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_GetChatsRequest(arg) {
if (!(arg instanceof gows_pb.GetChatsRequest)) {
throw new Error('Expected argument of type messages.GetChatsRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_GetChatsRequest(buffer_arg) {
return gows_pb.GetChatsRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_GetContactsRequest(arg) {
if (!(arg instanceof gows_pb.GetContactsRequest)) {
throw new Error('Expected argument of type messages.GetContactsRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_GetContactsRequest(buffer_arg) {
return gows_pb.GetContactsRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_GetMessagesRequest(arg) {
if (!(arg instanceof gows_pb.GetMessagesRequest)) {
throw new Error('Expected argument of type messages.GetMessagesRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_GetMessagesRequest(buffer_arg) {
return gows_pb.GetMessagesRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_GetNewsletterMessagesByInviteRequest(arg) {
if (!(arg instanceof gows_pb.GetNewsletterMessagesByInviteRequest)) {
throw new Error('Expected argument of type messages.GetNewsletterMessagesByInviteRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_GetNewsletterMessagesByInviteRequest(buffer_arg) {
return gows_pb.GetNewsletterMessagesByInviteRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_Json(arg) {
if (!(arg instanceof gows_pb.Json)) {
throw new Error('Expected argument of type messages.Json');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_Json(buffer_arg) {
return gows_pb.Json.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_JsonList(arg) {
if (!(arg instanceof gows_pb.JsonList)) {
throw new Error('Expected argument of type messages.JsonList');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_JsonList(buffer_arg) {
return gows_pb.JsonList.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_MarkReadRequest(arg) {
if (!(arg instanceof gows_pb.MarkReadRequest)) {
throw new Error('Expected argument of type messages.MarkReadRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_MarkReadRequest(buffer_arg) {
return gows_pb.MarkReadRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_MessageReaction(arg) {
if (!(arg instanceof gows_pb.MessageReaction)) {
throw new Error('Expected argument of type messages.MessageReaction');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_MessageReaction(buffer_arg) {
return gows_pb.MessageReaction.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_MessageRequest(arg) {
if (!(arg instanceof gows_pb.MessageRequest)) {
throw new Error('Expected argument of type messages.MessageRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_MessageRequest(buffer_arg) {
return gows_pb.MessageRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_MessageResponse(arg) {
if (!(arg instanceof gows_pb.MessageResponse)) {
throw new Error('Expected argument of type messages.MessageResponse');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_MessageResponse(buffer_arg) {
return gows_pb.MessageResponse.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_Newsletter(arg) {
if (!(arg instanceof gows_pb.Newsletter)) {
throw new Error('Expected argument of type messages.Newsletter');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_Newsletter(buffer_arg) {
return gows_pb.Newsletter.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_NewsletterInfoRequest(arg) {
if (!(arg instanceof gows_pb.NewsletterInfoRequest)) {
throw new Error('Expected argument of type messages.NewsletterInfoRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_NewsletterInfoRequest(buffer_arg) {
return gows_pb.NewsletterInfoRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_NewsletterList(arg) {
if (!(arg instanceof gows_pb.NewsletterList)) {
throw new Error('Expected argument of type messages.NewsletterList');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_NewsletterList(buffer_arg) {
return gows_pb.NewsletterList.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_NewsletterListRequest(arg) {
if (!(arg instanceof gows_pb.NewsletterListRequest)) {
throw new Error('Expected argument of type messages.NewsletterListRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_NewsletterListRequest(buffer_arg) {
return gows_pb.NewsletterListRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_NewsletterSearchPageResult(arg) {
if (!(arg instanceof gows_pb.NewsletterSearchPageResult)) {
throw new Error('Expected argument of type messages.NewsletterSearchPageResult');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_NewsletterSearchPageResult(buffer_arg) {
return gows_pb.NewsletterSearchPageResult.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_NewsletterToggleFollowRequest(arg) {
if (!(arg instanceof gows_pb.NewsletterToggleFollowRequest)) {
throw new Error('Expected argument of type messages.NewsletterToggleFollowRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_NewsletterToggleFollowRequest(buffer_arg) {
return gows_pb.NewsletterToggleFollowRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_NewsletterToggleMuteRequest(arg) {
if (!(arg instanceof gows_pb.NewsletterToggleMuteRequest)) {
throw new Error('Expected argument of type messages.NewsletterToggleMuteRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_NewsletterToggleMuteRequest(buffer_arg) {
return gows_pb.NewsletterToggleMuteRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_PairCodeRequest(arg) {
if (!(arg instanceof gows_pb.PairCodeRequest)) {
throw new Error('Expected argument of type messages.PairCodeRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_PairCodeRequest(buffer_arg) {
return gows_pb.PairCodeRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_PairCodeResponse(arg) {
if (!(arg instanceof gows_pb.PairCodeResponse)) {
throw new Error('Expected argument of type messages.PairCodeResponse');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_PairCodeResponse(buffer_arg) {
return gows_pb.PairCodeResponse.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_PresenceRequest(arg) {
if (!(arg instanceof gows_pb.PresenceRequest)) {
throw new Error('Expected argument of type messages.PresenceRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_PresenceRequest(buffer_arg) {
return gows_pb.PresenceRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_ProfilePictureRequest(arg) {
if (!(arg instanceof gows_pb.ProfilePictureRequest)) {
throw new Error('Expected argument of type messages.ProfilePictureRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_ProfilePictureRequest(buffer_arg) {
return gows_pb.ProfilePictureRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_ProfilePictureResponse(arg) {
if (!(arg instanceof gows_pb.ProfilePictureResponse)) {
throw new Error('Expected argument of type messages.ProfilePictureResponse');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_ProfilePictureResponse(buffer_arg) {
return gows_pb.ProfilePictureResponse.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_SearchNewslettersByTextRequest(arg) {
if (!(arg instanceof gows_pb.SearchNewslettersByTextRequest)) {
throw new Error('Expected argument of type messages.SearchNewslettersByTextRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_SearchNewslettersByTextRequest(buffer_arg) {
return gows_pb.SearchNewslettersByTextRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_SearchNewslettersByViewRequest(arg) {
if (!(arg instanceof gows_pb.SearchNewslettersByViewRequest)) {
throw new Error('Expected argument of type messages.SearchNewslettersByViewRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_SearchNewslettersByViewRequest(buffer_arg) {
return gows_pb.SearchNewslettersByViewRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_Session(arg) {
if (!(arg instanceof gows_pb.Session)) {
throw new Error('Expected argument of type messages.Session');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_Session(buffer_arg) {
return gows_pb.Session.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_SessionStateResponse(arg) {
if (!(arg instanceof gows_pb.SessionStateResponse)) {
throw new Error('Expected argument of type messages.SessionStateResponse');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_SessionStateResponse(buffer_arg) {
return gows_pb.SessionStateResponse.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_StartSessionRequest(arg) {
if (!(arg instanceof gows_pb.StartSessionRequest)) {
throw new Error('Expected argument of type messages.StartSessionRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_StartSessionRequest(buffer_arg) {
return gows_pb.StartSessionRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_SubscribePresenceRequest(arg) {
if (!(arg instanceof gows_pb.SubscribePresenceRequest)) {
throw new Error('Expected argument of type messages.SubscribePresenceRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_SubscribePresenceRequest(buffer_arg) {
return gows_pb.SubscribePresenceRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
//
// Events
//
var EventStreamService = exports.EventStreamService = {
streamEvents: {
path: '/messages.EventStream/StreamEvents',
requestStream: false,
responseStream: true,
requestType: gows_pb.Session,
responseType: gows_pb.EventJson,
requestSerialize: serialize_messages_Session,
requestDeserialize: deserialize_messages_Session,
responseSerialize: serialize_messages_EventJson,
responseDeserialize: deserialize_messages_EventJson,
},
};
exports.EventStreamClient = grpc.makeGenericClientConstructor(EventStreamService);
var MessageServiceService = exports.MessageServiceService = {
//
// Session management
//
startSession: {
path: '/messages.MessageService/StartSession',
requestStream: false,
responseStream: false,
requestType: gows_pb.StartSessionRequest,
responseType: gows_pb.Empty,
requestSerialize: serialize_messages_StartSessionRequest,
requestDeserialize: deserialize_messages_StartSessionRequest,
responseSerialize: serialize_messages_Empty,
responseDeserialize: deserialize_messages_Empty,
},
stopSession: {
path: '/messages.MessageService/StopSession',
requestStream: false,
responseStream: false,
requestType: gows_pb.Session,
responseType: gows_pb.Empty,
requestSerialize: serialize_messages_Session,
requestDeserialize: deserialize_messages_Session,
responseSerialize: serialize_messages_Empty,
responseDeserialize: deserialize_messages_Empty,
},
getSessionState: {
path: '/messages.MessageService/GetSessionState',
requestStream: false,
responseStream: false,
requestType: gows_pb.Session,
responseType: gows_pb.SessionStateResponse,
requestSerialize: serialize_messages_Session,
requestDeserialize: deserialize_messages_Session,
responseSerialize: serialize_messages_SessionStateResponse,
responseDeserialize: deserialize_messages_SessionStateResponse,
},
requestCode: {
path: '/messages.MessageService/RequestCode',
requestStream: false,
responseStream: false,
requestType: gows_pb.PairCodeRequest,
responseType: gows_pb.PairCodeResponse,
requestSerialize: serialize_messages_PairCodeRequest,
requestDeserialize: deserialize_messages_PairCodeRequest,
responseSerialize: serialize_messages_PairCodeResponse,
responseDeserialize: deserialize_messages_PairCodeResponse,
},
logout: {
path: '/messages.MessageService/Logout',
requestStream: false,
responseStream: false,
requestType: gows_pb.Session,
responseType: gows_pb.Empty,
requestSerialize: serialize_messages_Session,
requestDeserialize: deserialize_messages_Session,
responseSerialize: serialize_messages_Empty,
responseDeserialize: deserialize_messages_Empty,
},
//
// Actions
//
sendMessage: {
path: '/messages.MessageService/SendMessage',
requestStream: false,
responseStream: false,
requestType: gows_pb.MessageRequest,
responseType: gows_pb.MessageResponse,
requestSerialize: serialize_messages_MessageRequest,
requestDeserialize: deserialize_messages_MessageRequest,
responseSerialize: serialize_messages_MessageResponse,
responseDeserialize: deserialize_messages_MessageResponse,
},
sendReaction: {
path: '/messages.MessageService/SendReaction',
requestStream: false,
responseStream: false,
requestType: gows_pb.MessageReaction,
responseType: gows_pb.MessageResponse,
requestSerialize: serialize_messages_MessageReaction,
requestDeserialize: deserialize_messages_MessageReaction,
responseSerialize: serialize_messages_MessageResponse,
responseDeserialize: deserialize_messages_MessageResponse,
},
getProfilePicture: {
path: '/messages.MessageService/GetProfilePicture',
requestStream: false,
responseStream: false,
requestType: gows_pb.ProfilePictureRequest,
responseType: gows_pb.ProfilePictureResponse,
requestSerialize: serialize_messages_ProfilePictureRequest,
requestDeserialize: deserialize_messages_ProfilePictureRequest,
responseSerialize: serialize_messages_ProfilePictureResponse,
responseDeserialize: deserialize_messages_ProfilePictureResponse,
},
sendPresence: {
path: '/messages.MessageService/SendPresence',
requestStream: false,
responseStream: false,
requestType: gows_pb.PresenceRequest,
responseType: gows_pb.Empty,
requestSerialize: serialize_messages_PresenceRequest,
requestDeserialize: deserialize_messages_PresenceRequest,
responseSerialize: serialize_messages_Empty,
responseDeserialize: deserialize_messages_Empty,
},
sendChatPresence: {
path: '/messages.MessageService/SendChatPresence',
requestStream: false,
responseStream: false,
requestType: gows_pb.ChatPresenceRequest,
responseType: gows_pb.Empty,
requestSerialize: serialize_messages_ChatPresenceRequest,
requestDeserialize: deserialize_messages_ChatPresenceRequest,
responseSerialize: serialize_messages_Empty,
responseDeserialize: deserialize_messages_Empty,
},
subscribePresence: {
path: '/messages.MessageService/SubscribePresence',
requestStream: false,
responseStream: false,
requestType: gows_pb.SubscribePresenceRequest,
responseType: gows_pb.Empty,
requestSerialize: serialize_messages_SubscribePresenceRequest,
requestDeserialize: deserialize_messages_SubscribePresenceRequest,
responseSerialize: serialize_messages_Empty,
responseDeserialize: deserialize_messages_Empty,
},
markRead: {
path: '/messages.MessageService/MarkRead',
requestStream: false,
responseStream: false,
requestType: gows_pb.MarkReadRequest,
responseType: gows_pb.Empty,
requestSerialize: serialize_messages_MarkReadRequest,
requestDeserialize: deserialize_messages_MarkReadRequest,
responseSerialize: serialize_messages_Empty,
responseDeserialize: deserialize_messages_Empty,
},
checkPhones: {
path: '/messages.MessageService/CheckPhones',
requestStream: false,
responseStream: false,
requestType: gows_pb.CheckPhonesRequest,
responseType: gows_pb.CheckPhonesResponse,
requestSerialize: serialize_messages_CheckPhonesRequest,
requestDeserialize: deserialize_messages_CheckPhonesRequest,
responseSerialize: serialize_messages_CheckPhonesResponse,
responseDeserialize: deserialize_messages_CheckPhonesResponse,
},
//
// Newsletters
//
getSubscribedNewsletters: {
path: '/messages.MessageService/GetSubscribedNewsletters',
requestStream: false,
responseStream: false,
requestType: gows_pb.NewsletterListRequest,
responseType: gows_pb.NewsletterList,
requestSerialize: serialize_messages_NewsletterListRequest,
requestDeserialize: deserialize_messages_NewsletterListRequest,
responseSerialize: serialize_messages_NewsletterList,
responseDeserialize: deserialize_messages_NewsletterList,
},
getNewsletterInfo: {
path: '/messages.MessageService/GetNewsletterInfo',
requestStream: false,
responseStream: false,
requestType: gows_pb.NewsletterInfoRequest,
responseType: gows_pb.Newsletter,
requestSerialize: serialize_messages_NewsletterInfoRequest,
requestDeserialize: deserialize_messages_NewsletterInfoRequest,
responseSerialize: serialize_messages_Newsletter,
responseDeserialize: deserialize_messages_Newsletter,
},
getNewsletterMessagesByInvite: {
path: '/messages.MessageService/GetNewsletterMessagesByInvite',
requestStream: false,
responseStream: false,
requestType: gows_pb.GetNewsletterMessagesByInviteRequest,
responseType: gows_pb.Json,
requestSerialize: serialize_messages_GetNewsletterMessagesByInviteRequest,
requestDeserialize: deserialize_messages_GetNewsletterMessagesByInviteRequest,
responseSerialize: serialize_messages_Json,
responseDeserialize: deserialize_messages_Json,
},
searchNewslettersByView: {
path: '/messages.MessageService/SearchNewslettersByView',
requestStream: false,
responseStream: false,
requestType: gows_pb.SearchNewslettersByViewRequest,
responseType: gows_pb.NewsletterSearchPageResult,
requestSerialize: serialize_messages_SearchNewslettersByViewRequest,
requestDeserialize: deserialize_messages_SearchNewslettersByViewRequest,
responseSerialize: serialize_messages_NewsletterSearchPageResult,
responseDeserialize: deserialize_messages_NewsletterSearchPageResult,
},
searchNewslettersByText: {
path: '/messages.MessageService/SearchNewslettersByText',
requestStream: false,
responseStream: false,
requestType: gows_pb.SearchNewslettersByTextRequest,
responseType: gows_pb.NewsletterSearchPageResult,
requestSerialize: serialize_messages_SearchNewslettersByTextRequest,
requestDeserialize: deserialize_messages_SearchNewslettersByTextRequest,
responseSerialize: serialize_messages_NewsletterSearchPageResult,
responseDeserialize: deserialize_messages_NewsletterSearchPageResult,
},
createNewsletter: {
path: '/messages.MessageService/CreateNewsletter',
requestStream: false,
responseStream: false,
requestType: gows_pb.CreateNewsletterRequest,
responseType: gows_pb.Newsletter,
requestSerialize: serialize_messages_CreateNewsletterRequest,
requestDeserialize: deserialize_messages_CreateNewsletterRequest,
responseSerialize: serialize_messages_Newsletter,
responseDeserialize: deserialize_messages_Newsletter,
},
newsletterToggleMute: {
path: '/messages.MessageService/NewsletterToggleMute',
requestStream: false,
responseStream: false,
requestType: gows_pb.NewsletterToggleMuteRequest,
responseType: gows_pb.Empty,
requestSerialize: serialize_messages_NewsletterToggleMuteRequest,
requestDeserialize: deserialize_messages_NewsletterToggleMuteRequest,
responseSerialize: serialize_messages_Empty,
responseDeserialize: deserialize_messages_Empty,
},
newsletterToggleFollow: {
path: '/messages.MessageService/NewsletterToggleFollow',
requestStream: false,
responseStream: false,
requestType: gows_pb.NewsletterToggleFollowRequest,
responseType: gows_pb.Empty,
requestSerialize: serialize_messages_NewsletterToggleFollowRequest,
requestDeserialize: deserialize_messages_NewsletterToggleFollowRequest,
responseSerialize: serialize_messages_Empty,
responseDeserialize: deserialize_messages_Empty,
},
//
// Media
//
downloadMedia: {
path: '/messages.MessageService/DownloadMedia',
requestStream: false,
responseStream: false,
requestType: gows_pb.DownloadMediaRequest,
responseType: gows_pb.DownloadMediaResponse,
requestSerialize: serialize_messages_DownloadMediaRequest,
requestDeserialize: deserialize_messages_DownloadMediaRequest,
responseSerialize: serialize_messages_DownloadMediaResponse,
responseDeserialize: deserialize_messages_DownloadMediaResponse,
},
//
// Storage
//
getMessageById: {
path: '/messages.MessageService/GetMessageById',
requestStream: false,
responseStream: false,
requestType: gows_pb.EntityByIdRequest,
responseType: gows_pb.Json,
requestSerialize: serialize_messages_EntityByIdRequest,
requestDeserialize: deserialize_messages_EntityByIdRequest,
responseSerialize: serialize_messages_Json,
responseDeserialize: deserialize_messages_Json,
},
getMessages: {
path: '/messages.MessageService/GetMessages',
requestStream: false,
responseStream: false,
requestType: gows_pb.GetMessagesRequest,
responseType: gows_pb.JsonList,
requestSerialize: serialize_messages_GetMessagesRequest,
requestDeserialize: deserialize_messages_GetMessagesRequest,
responseSerialize: serialize_messages_JsonList,
responseDeserialize: deserialize_messages_JsonList,
},
getContacts: {
path: '/messages.MessageService/GetContacts',
requestStream: false,
responseStream: false,
requestType: gows_pb.GetContactsRequest,
responseType: gows_pb.JsonList,
requestSerialize: serialize_messages_GetContactsRequest,
requestDeserialize: deserialize_messages_GetContactsRequest,
responseSerialize: serialize_messages_JsonList,
responseDeserialize: deserialize_messages_JsonList,
},
getContactById: {
path: '/messages.MessageService/GetContactById',
requestStream: false,
responseStream: false,
requestType: gows_pb.EntityByIdRequest,
responseType: gows_pb.Json,
requestSerialize: serialize_messages_EntityByIdRequest,
requestDeserialize: deserialize_messages_EntityByIdRequest,
responseSerialize: serialize_messages_Json,
responseDeserialize: deserialize_messages_Json,
},
getChats: {
path: '/messages.MessageService/GetChats',
requestStream: false,
responseStream: false,
requestType: gows_pb.GetChatsRequest,
responseType: gows_pb.JsonList,
requestSerialize: serialize_messages_GetChatsRequest,
requestDeserialize: deserialize_messages_GetChatsRequest,
responseSerialize: serialize_messages_JsonList,
responseDeserialize: deserialize_messages_JsonList,
},
};
exports.MessageServiceClient = grpc.makeGenericClientConstructor(MessageServiceService);
File diff suppressed because it is too large. Load diff
+34 -1
View File
@@ -29,9 +29,14 @@ import { IMediaEngineProcessor } from '@waha/core/media/IMediaEngineProcessor';
import { QR } from '@waha/core/QR';
import {
Channel,
ChannelListResult,
ChannelMessage,
ChannelRole,
ChannelSearchByText,
ChannelSearchByView,
CreateChannelRequest,
ListChannelsQuery,
PreviewChannelMessages,
} from '@waha/structures/channels.dto';
import {
ChatRequest,
@@ -111,6 +116,11 @@ enum WhatsMeowEvent {
LOGGED_OUT = 'events.LoggedOut',
}
const gRPCClientConfig = {
'grpc.max_send_message_length': 128 * 1024 * 1024,
'grpc.max_receive_message_length': 128 * 1024 * 1024,
};
export interface GowsConfig {
connection: string;
}
@@ -170,6 +180,7 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
this.client = new MessageServiceClient(
this.engineConfig.connection,
grpc.credentials.createInsecure(),
gRPCClientConfig,
);
try {
@@ -199,6 +210,7 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
const client = new messages.EventStreamClient(
this.engineConfig.connection,
grpc.credentials.createInsecure(),
gRPCClientConfig,
);
const stream = client.StreamEvents(this.session);
return { client, stream };
@@ -689,6 +701,25 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
/**
* Channels methods
*/
public searchChannelsByView(
query: ChannelSearchByView,
): Promise<ChannelListResult> {
throw new AvailableInPlusVersion();
}
public searchChannelsByText(
query: ChannelSearchByText,
): Promise<ChannelListResult> {
throw new AvailableInPlusVersion();
}
public async previewChannelMessages(
inviteCode: string,
query: PreviewChannelMessages,
): Promise<ChannelMessage[]> {
throw new AvailableInPlusVersion();
}
protected toChannel(newsletter: messages.Newsletter): Channel {
const role: ChannelRole =
(newsletter.role?.toUpperCase() as ChannelRole) || ChannelRole.GUEST;
@@ -709,6 +740,7 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
preview: preview,
verified: newsletter.verified,
role: role,
subscribersCount: newsletter.subscriberCount,
};
}
@@ -977,7 +1009,7 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
// END - Methods for API
//
private async processIncomingMessage(message, downloadMedia = true) {
protected async processIncomingMessage(message, downloadMedia = true) {
// if there is no text or media message
if (!message) return;
if (!message.Message) return;
@@ -1195,6 +1227,7 @@ export class GOWSEngineMediaProcessor implements IMediaEngineProcessor<any> {
async getMediaBuffer(message: any): Promise<Buffer | null> {
const data = JSON.stringify(message.Message);
const request = new messages.DownloadMediaRequest({
// double "session" it's not a mistake here
session: this.session.session,
message: data,
});
+31 -5
View File
@@ -48,9 +48,14 @@ import { PairingCodeResponse } from '@waha/structures/auth.dto';
import { CallData } from '@waha/structures/calls.dto';
import {
Channel,
ChannelListResult,
ChannelMessage,
ChannelRole,
ChannelSearchByText,
ChannelSearchByView,
CreateChannelRequest,
ListChannelsQuery,
PreviewChannelMessages,
} from '@waha/structures/channels.dto';
import {
ChatSummary,
@@ -149,6 +154,7 @@ import {
import {
ensureSuffix,
getChannelInviteLink,
getPublicUrlFromDirectPath,
isNewsletter,
WhatsappSession,
} from '../../abc/session.abc';
@@ -1316,6 +1322,25 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
/**
* Channels methods
*/
public searchChannelsByView(
query: ChannelSearchByView,
): Promise<ChannelListResult> {
throw new AvailableInPlusVersion();
}
public searchChannelsByText(
query: ChannelSearchByText,
): Promise<ChannelListResult> {
throw new AvailableInPlusVersion();
}
public async previewChannelMessages(
inviteCode: string,
query: PreviewChannelMessages,
): Promise<ChannelMessage[]> {
throw new AvailableInPlusVersion();
}
protected toChannel(newsletter: NewsletterMetadata): Channel {
const role =
// @ts-ignore
@@ -1323,20 +1348,21 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
(newsletter.viewer_metadata?.view_role as ChannelRole) ||
ChannelRole.GUEST;
const preview = newsletter.preview
? getUrlFromDirectPath(newsletter.preview)
? getPublicUrlFromDirectPath(newsletter.preview)
: null;
const picture = newsletter.picture
? getUrlFromDirectPath(newsletter.picture)
? getPublicUrlFromDirectPath(newsletter.picture)
: null;
return {
id: newsletter.id,
name: newsletter.name,
description: newsletter.description,
invite: getChannelInviteLink(newsletter.invite),
preview: preview,
picture: picture,
preview: preview || picture,
picture: picture || preview,
verified: newsletter.verification === 'VERIFIED',
role: role,
subscribersCount: newsletter.subscribers,
};
}
@@ -1636,7 +1662,7 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
return reaction;
}
private async processIncomingMessage(message, downloadMedia = true) {
protected async processIncomingMessage(message, downloadMedia = true) {
// if there is no text or media message
if (!message) return;
if (!message.message) return;
@@ -18,17 +18,21 @@ const { LoadPaginator } = require('./_Paginator.js');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const ChatFactory = require('whatsapp-web.js/src/factories/ChatFactory');
export class WebjsClient extends Client {
export class WebjsClientCore extends Client {
constructor(options) {
super(options);
// Wait until it's READY and inject more utils
this.on(Events.READY, async () => {
await this.pupPage.evaluate(LoadLodash);
await this.pupPage.evaluate(LoadPaginator);
await this.pupPage.evaluate(LoadWAHA);
await this.injectWaha();
});
}
async injectWaha() {
await this.pupPage.evaluate(LoadLodash);
await this.pupPage.evaluate(LoadPaginator);
await this.pupPage.evaluate(LoadWAHA);
}
async unpair() {
await this.pupPage.evaluate(async () => {
if (
+59 -12
View File
@@ -4,7 +4,7 @@ import {
WhatsappSession,
} from '@waha/core/abc/session.abc';
import { LocalAuth } from '@waha/core/engines/webjs/LocalAuth';
import { WebjsClient } from '@waha/core/engines/webjs/WebjsClient';
import { WebjsClientCore } from '@waha/core/engines/webjs/WebjsClientCore';
import {
AvailableInPlusVersion,
NotImplementedByEngineError,
@@ -15,9 +15,14 @@ import { splitAt } from '@waha/helpers';
import { PairingCodeResponse } from '@waha/structures/auth.dto';
import {
Channel,
ChannelListResult,
ChannelMessage,
ChannelRole,
ChannelSearchByText,
ChannelSearchByView,
CreateChannelRequest,
ListChannelsQuery,
PreviewChannelMessages,
} from '@waha/structures/channels.dto';
import {
ChatSortField,
@@ -106,7 +111,7 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
private engineStateCheckDelayedJob: SingleDelayedJobRunner;
private shouldRestart: boolean;
whatsapp: WebjsClient;
whatsapp: WebjsClientCore;
protected qr: QR;
public constructor(config) {
@@ -169,7 +174,7 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
rmMaxRetries: undefined,
});
this.addProxyConfig(clientOptions);
return new WebjsClient(clientOptions);
return new WebjsClientCore(clientOptions);
}
private restartClient() {
@@ -479,7 +484,11 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
reply(request: MessageReplyRequest) {
const options = this.getMessageOptions(request);
return this.whatsapp.sendMessage(request.chatId, request.text, options);
return this.whatsapp.sendMessage(
this.ensureSuffix(request.chatId),
request.text,
options,
);
}
sendImage(request: MessageImageRequest) {
@@ -499,12 +508,16 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
name: request.title,
});
const options = this.getMessageOptions(request);
return this.whatsapp.sendMessage(request.chatId, location, options);
return this.whatsapp.sendMessage(
this.ensureSuffix(request.chatId),
location,
options,
);
}
async forwardMessage(request: MessageForwardRequest): Promise<WAMessage> {
const forwardMessage = this.recreateMessage(request.messageId);
const msg = await forwardMessage.forward(request.chatId);
const msg = await forwardMessage.forward(this.ensureSuffix(request.chatId));
// Return "sent: true" for now
// need to research how to get the data from WebJS
// @ts-ignore
@@ -512,17 +525,23 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
}
async sendSeen(request: SendSeenRequest) {
const chat: Chat = await this.whatsapp.getChatById(request.chatId);
const chat: Chat = await this.whatsapp.getChatById(
this.ensureSuffix(request.chatId),
);
await chat.sendSeen();
}
async startTyping(request: ChatRequest) {
const chat: Chat = await this.whatsapp.getChatById(request.chatId);
const chat: Chat = await this.whatsapp.getChatById(
this.ensureSuffix(request.chatId),
);
await chat.sendStateTyping();
}
async stopTyping(request: ChatRequest) {
const chat: Chat = await this.whatsapp.getChatById(request.chatId);
const chat: Chat = await this.whatsapp.getChatById(
this.ensureSuffix(request.chatId),
);
await chat.clearState();
}
@@ -658,7 +677,7 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
}
async deleteChat(chatId) {
const chat = await this.whatsapp.getChatById(chatId);
const chat = await this.whatsapp.getChatById(this.ensureSuffix(chatId));
return chat.delete();
}
@@ -922,6 +941,25 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
/**
* Channels methods
*/
public searchChannelsByView(
query: ChannelSearchByView,
): Promise<ChannelListResult> {
throw new AvailableInPlusVersion();
}
public searchChannelsByText(
query: ChannelSearchByText,
): Promise<ChannelListResult> {
throw new AvailableInPlusVersion();
}
public async previewChannelMessages(
inviteCode: string,
query: PreviewChannelMessages,
): Promise<ChannelMessage[]> {
throw new AvailableInPlusVersion();
}
protected ChatToChannel(chat: WEBJSChannel): Channel {
// @ts-ignore
const metadata = chat.channelMetadata;
@@ -938,6 +976,7 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
picture: null,
verified: metadata.verified,
role: role,
subscribersCount: null,
};
}
@@ -955,6 +994,7 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
picture: metadata.pictureUrl,
verified: metadata.isVerified,
role: role,
subscribersCount: metadata.subscribersCount,
};
}
@@ -966,6 +1006,10 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
channels = channels.filter((channel) => channel.role === query.role);
}
// Exclude GUEST, browser saves the data
// when we search channels or getting messages
channels = channels.filter((channel) => channel.role === 'GUEST');
const promises = channels.map(async (channel) =>
this.whatsapp.getProfilePicUrl(channel.id),
);
@@ -1211,7 +1255,10 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
this.events2.get(WAHAEvents.CALL_RECEIVED).switch(calls$);
}
private async processIncomingMessage(message: Message, downloadMedia = true) {
protected async processIncomingMessage(
message: Message,
downloadMedia = true,
) {
if (downloadMedia) {
try {
message = await this.downloadMedia(message);
@@ -1267,7 +1314,7 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
protected extractReplyTo(message: Message): ReplyToMessage | null {
// @ts-ignore
const quotedMsg = message.rawData.quotedMsg;
const quotedMsg = message.rawData?.quotedMsg;
if (!quotedMsg) {
return;
}
@@ -0,0 +1,22 @@
import { Injectable } from '@nestjs/common';
import { AvailableInPlusVersion } from '@waha/core/exceptions';
import {
ChannelCategory,
ChannelCountry,
ChannelView,
} from '@waha/structures/channels.dto';
@Injectable()
export class ChannelsInfoServiceCore {
async getCountries(): Promise<ChannelCountry[]> {
throw new AvailableInPlusVersion();
}
async getCategories(): Promise<ChannelCategory[]> {
throw new AvailableInPlusVersion();
}
async getViews(): Promise<ChannelView[]> {
throw new AvailableInPlusVersion();
}
}
+7
View File
@@ -30,4 +30,11 @@ function splitAt(str: string, index) {
return [fst.join(''), snd.join('')];
}
export function sortObjectByValues(obj: any) {
return Object.fromEntries(
// @ts-ignore
Object.entries(obj).sort(([, v1], [, v2]) => v2 - v1),
);
}
export { flipObject, parseBool, splitAt };
-8
View File
@@ -35,14 +35,6 @@ export class RequestCodeRequest {
localeCountry: string;
}
export class OTPRequest {
code: string;
}
export class CaptchaBody {
code: string;
}
export class PairingCodeResponse {
code: string;
}
+102 -1
View File
@@ -1,5 +1,17 @@
import { ApiParam, ApiProperty, getSchemaPath } from '@nestjs/swagger';
import { BooleanString } from '@waha/nestjs/validation/BooleanString';
import { BinaryFile, RemoteFile } from '@waha/structures/files.dto';
import { WAMessage } from '@waha/structures/responses.dto';
import { Transform, Type } from 'class-transformer';
import {
ArrayMinSize,
IsArray,
IsBoolean,
IsNotEmpty,
IsNumber,
IsOptional,
IsString,
} from 'class-validator';
export class CreateChannelRequest {
@ApiProperty({
@@ -38,7 +50,7 @@ export class ListChannelsQuery {
role?: ChannelRoleFilter;
}
export class Channel {
class ChannelBase {
@ApiProperty({
description: 'Newsletter id',
example: '123123123123@newsletter',
@@ -73,9 +85,15 @@ export class Channel {
verified: boolean;
subscribersCount: number;
}
export class Channel extends ChannelBase {
role: ChannelRole;
}
export class ChannelPublicInfo extends ChannelBase {}
export const NewsletterIdApiParam = ApiParam({
name: 'id',
required: true,
@@ -96,3 +114,86 @@ export const NewsletterIdOrInviteCodeApiParam = ApiParam({
description:
'WhatsApp Channel ID or invite code from invite link https://www.whatsapp.com/channel/11111',
});
export class ChannelCountry {
code: string;
name: string;
}
export class ChannelCategory {
value: string;
name: string;
}
export class ChannelView {
value: string;
name: string;
}
export class ChannelSearch {
@IsNumber()
@IsOptional()
limit: number = 50;
@IsString()
startCursor: string = '';
}
export class ChannelSearchByView extends ChannelSearch {
@IsString()
view: string = 'RECOMMENDED';
@IsArray()
@IsString({ each: true })
@ArrayMinSize(1)
countries: string[] = ['US'];
@IsArray()
@IsString({ each: true })
categories: string[] = [];
}
export class ChannelSearchByText extends ChannelSearch {
@IsString()
@IsNotEmpty()
text: string = 'Donald Trump';
@IsArray()
@IsString({ each: true })
categories: string[] = [];
}
export class ChannelPagination {
startCursor: string | null;
endCursor: string | null;
hasNextPage: boolean;
hasPreviousPage: boolean;
}
export class ChannelListResult {
page: ChannelPagination;
channels: ChannelPublicInfo[];
}
export class ChannelMessage {
message: WAMessage;
@ApiProperty({
example: { '👍': 10, '❤️': 5 },
type: Object,
additionalProperties: { type: 'number' },
})
reactions: { [emoji: string]: number };
viewCount: number;
}
export class PreviewChannelMessages {
@Transform(BooleanString)
@IsBoolean()
downloadMedia: boolean = false;
@IsNumber()
@Type(() => Number)
limit: number = 100;
}
+1 -1
View File
@@ -33,7 +33,7 @@ export function getEngineName(): string {
}
export const VERSION: WAHAEnvironment = {
version: '2025.2.1',
version: '2025.2.2',
engine: getEngineName(),
tier: getWAHAVersion(),
browser: getBrowserExecutablePath(),
+1 -1
View File
@@ -2,7 +2,7 @@
"waha": {
"gows": {
"repo": "devlikeapro/gows",
"ref": "4b11c1d58018bc4b5028de51aa1bc7da9c2d9103"
"ref": "b4d8005bac5d4e9094af5fa4945a4731a656330f"
},
"dashboard": {
"repo": "devlikeapro/dashboard",
+2 -2
View File
@@ -7,7 +7,7 @@ __metadata:
"@adiwajshing/baileys@github:devlikeapro/Baileys#fork-master-channels-6712":
version: 6.7.12
resolution: "@adiwajshing/baileys@https://github.com/devlikeapro/Baileys.git#commit=18359f20a3c34166665ad8b62000347ce0c4592e"
resolution: "@adiwajshing/baileys@https://github.com/devlikeapro/Baileys.git#commit=6394c30b4011b688d041b604abe27e05a6ef1d03"
dependencies:
"@adiwajshing/keyed-db": ^0.2.4
"@hapi/boom": ^9.1.3
@@ -40,7 +40,7 @@ __metadata:
optional: true
sharp:
optional: true
checksum: 53c939b9b2d47cb00db73e6cb04633fdd62c69dce6e5d830c3e18e09c90bceb0425c9c59ac58bfdeabce501091ca895132b035877243dfaf90f2297c99eb8fef
checksum: 84f85787f1c02fe19c3d5f413292fb867584dd2576a5426b231f0d3d5aaed121a7bb9d32e52145dbb332880d3f58acf4323783cba6577c1489e4cf694c22b912
languageName: node
linkType: hard