Skip to content

Commit

Permalink
[core] Add GOWS engine
Browse files Browse the repository at this point in the history
  • Loading branch information
devlikepro committed Jan 10, 2025
1 parent 71d3e24 commit 0b9f9b2
Show file tree
Hide file tree
Showing 28 changed files with 1,699 additions and 17 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Dockerfile
src/core/engines/gows/grpc
.*sessions
sessions
files
Expand Down
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src/core/engines/gows/grpc/*
20 changes: 18 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,38 @@ jobs:
# browser: "chrome"
# goss: 'goss-linux-arm'

# No browser - x86
# NOWEB - x86
- runner: 'buildjet-4vcpu-ubuntu-2204'
tag: 'noweb'
platform: 'amd64'
browser: 'none'
engine: 'NOWEB'
goss: 'goss-linux-amd64'

# No browser - ARM
# NOWEB - ARM
- runner: 'buildjet-4vcpu-ubuntu-2204-arm'
tag: 'noweb-arm'
platform: 'linux/arm64'
browser: 'none'
engine: 'NOWEB'
goss: 'goss-linux-arm'

# GOWS - x86
- runner: 'buildjet-4vcpu-ubuntu-2204'
tag: 'gows'
platform: 'amd64'
browser: 'none'
engine: 'GOWS'
goss: 'goss-linux-amd64'

# No browser - ARM
- runner: 'buildjet-4vcpu-ubuntu-2204-arm'
tag: 'gows-arm'
platform: 'linux/arm64'
browser: 'none'
engine: 'GOWS'
goss: 'goss-linux-arm'

steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
src/core/engines/gows/grpc
.env
*.heapsnapshot
.yarn
Expand Down
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ exclude: |
(?x)^(
^src/dashboard/.*|
^src/core/engines/webjs/.*html|
^src/core/engines/gows/grpc/.*|
^src/plus/engines/webjs/.*html|
^.yarn/.*
)$
Expand Down
67 changes: 64 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
# GOWS
ARG GOWS_GITHUB_REPO=devlikeapro/gows
ARG GOWS_SHA=95ca63a1dee5faec75232a9f59a548dfd4e414ff
ARG WAHA_DASHBOARD_GITHUB_REPO=devlikeapro/dashboard
ARG WAHA_DASHBOARD_SHA=a1c839d8da94d1cade182addffdfc42fc0cf7ed3

#
# Build
#
ARG NODE_VERSION=22.8-bullseye
FROM node:${NODE_VERSION} AS build
ENV PUPPETEER_SKIP_DOWNLOAD=True

# install protoc
RUN apt-get update && \
apt-get install protobuf-compiler -y

# npm packages
WORKDIR /src
COPY package.json .
Expand All @@ -18,6 +28,16 @@ RUN yarn install
WORKDIR /src
ADD . /src
RUN yarn install

# Build node grpc client for GOWS engine
WORKDIR /gows/proto
ARG GOWS_GITHUB_REPO
ARG GOWS_SHA
RUN wget https://raw.githubusercontent.com/${GOWS_GITHUB_REPO}/${GOWS_SHA}/proto/gows.proto
WORKDIR /src

RUN make proto-gows

RUN yarn build && find ./dist -name "*.d.ts" -delete

#
Expand All @@ -26,15 +46,41 @@ RUN yarn build && find ./dist -name "*.d.ts" -delete
FROM node:${NODE_VERSION} AS dashboard

# Download WAHA Dashboard
ENV WAHA_DASHBOARD_SHA fed4e50e88e4d26c610e3289fd0d8657cb866543
ARG WAHA_DASHBOARD_GITHUB_REPO
ARG WAHA_DASHBOARD_SHA
RUN \
wget https://github.com/devlikeapro/dashboard/archive/${WAHA_DASHBOARD_SHA}.zip \
wget https://github.com/${WAHA_DASHBOARD_GITHUB_REPO}/archive/${WAHA_DASHBOARD_SHA}.zip \
&& unzip ${WAHA_DASHBOARD_SHA}.zip -d /tmp/dashboard \
&& mkdir -p /dashboard \
&& mv /tmp/dashboard/dashboard-${WAHA_DASHBOARD_SHA}/* /dashboard/ \
&& rm -rf ${WAHA_DASHBOARD_SHA}.zip \
&& rm -rf /tmp/dashboard/dashboard-${WAHA_DASHBOARD_SHA}

#
# GOWS
#
FROM golang:1.23-bullseye AS gows
# install protoc
RUN apt-get update && \
apt-get install protobuf-compiler -y

# Image processing for thumbnails
RUN apt-get update \
&& apt-get install -y libvips-dev \
&& rm -rf /var/lib/apt/lists/*

ARG GOWS_GITHUB_REPO
ARG GOWS_SHA
RUN git clone https://github.com/${GOWS_GITHUB_REPO} gows && \
cd gows && \
git checkout ${GOWS_SHA}

WORKDIR /go/gows
RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
RUN make all


#
# Final
#
Expand All @@ -51,6 +97,11 @@ RUN echo "USE_BROWSER=$USE_BROWSER"
# Install ffmpeg to generate previews for videos
RUN apt-get update && apt-get install -y ffmpeg --no-install-recommends && rm -rf /var/lib/apt/lists/*

# Image processing for thumbnails
RUN apt-get update \
&& apt-get install -y libvips \
&& rm -rf /var/lib/apt/lists/*

# Install zip and unzip - either for chromium or chrome
RUN if [ "$USE_BROWSER" = "chromium" ] || [ "$USE_BROWSER" = "chrome" ]; then \
apt-get update \
Expand Down Expand Up @@ -100,7 +151,13 @@ RUN if [ "$USE_BROWSER" = "chrome" ]; then \
&& rm -rf /var/lib/apt/lists/*; \
fi

# Set the ENV for NOWEB docker image
# GOWS requirements
# libc6
RUN apt-get update \
&& apt-get install -y libc6 \
&& rm -rf /var/lib/apt/lists/*

# Set the ENV for docker image
ENV WHATSAPP_DEFAULT_ENGINE=$WHATSAPP_DEFAULT_ENGINE

# Attach sources, install packages
Expand All @@ -109,6 +166,10 @@ COPY package.json ./
COPY --from=build /src/node_modules ./node_modules
COPY --from=build /src/dist ./dist
COPY --from=dashboard /dashboard ./dist/dashboard
COPY --from=gows /go/gows/bin/gows /app/gows
ENV WAHA_GOWS_PATH /app/gows
ENV WAHA_GOWS_SOCKET /tmp/gows.sock

COPY entrypoint.sh /entrypoint.sh

# Chokidar options to monitor file changes
Expand Down
19 changes: 19 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ build-chrome:
build-noweb:
docker build . -t devlikeapro/waha:noweb --build-arg USE_BROWSER=none --build-arg WHATSAPP_DEFAULT_ENGINE=NOWEB

build-plus-gows:
docker build . -t devlikeapro/waha-plus:gows --build-arg USE_BROWSER=none --build-arg WHATSAPP_DEFAULT_ENGINE=GOWS

build-all: build build-chrome build-noweb

build-plus:
Expand Down Expand Up @@ -42,3 +45,19 @@ up-webjs:

start-proxy:
docker run --rm -d --name squid-container -e TZ=UTC -p 3128:3128 ubuntu/squid:5.2-22.04_beta

proto-gows:
rm -rf src/core/engines/gows/grpc
mkdir -p src/core/engines/gows/grpc
protoc \
--plugin=protoc-gen-ts=node_modules/.bin/protoc-gen-ts \
--plugin=protoc-gen-grpc=node_modules/.bin/grpc_tools_node_protoc_plugin \
--js_out=import_style=commonjs,binary:src/core/engines/gows/grpc \
--grpc_out=grpc_js:src/core/engines/gows/grpc \
--ts_out=grpc_js:src/core/engines/gows/grpc \
-I ../gows/proto ../gows/proto/gows.proto

gows:
cd ../gows && \
export PATH=${HOME}/go/bin:${PATH} && \
make all
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"express-basic-auth": "^1.2.1",
"file-type": "16.5.4",
"fs-extra": "^11.2.0",
"google-protobuf": "^3.21.4",
"https-proxy-agent": "^7.0.0",
"joi": "^17.13.3",
"knex": "^3.1.0",
Expand Down Expand Up @@ -94,6 +95,8 @@
"libsignal": "github:devlikeapro/libsignal-node#fork-master"
},
"devDependencies": {
"@grpc/grpc-js": "^1.12.4",
"@grpc/proto-loader": "^0.7.13",
"@nestjs/cli": "^9.0.0",
"@nestjs/schematics": "^9.0.1",
"@nestjs/testing": "^9.0.9",
Expand All @@ -107,8 +110,10 @@
"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",
"jest": "^29.7.0",
"prettier": "^1.19.1",
"protoc-gen-ts": "^0.8.7",
"supertest": "^4.0.2",
"ts-jest": "^29.1.3",
"ts-loader": "^6.2.1",
Expand Down
15 changes: 15 additions & 0 deletions src/core/abc/EngineBootstrap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export interface EngineBootstrap {
bootstrap(): Promise<void>;

shutdown(): Promise<void>;
}

export class NoopEngineBootstrap implements EngineBootstrap {
async bootstrap(): Promise<void> {
return;
}

async shutdown(): Promise<void> {
return;
}
}
28 changes: 26 additions & 2 deletions src/core/abc/manager.abc.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import {
BeforeApplicationShutdown,
OnApplicationBootstrap,
UnprocessableEntityException,
} from '@nestjs/common';
import { WhatsappConfigService } from '@waha/config.service';
import {
EngineBootstrap,
NoopEngineBootstrap,
} from '@waha/core/abc/EngineBootstrap';
import { GowsEngineConfigService } from '@waha/core/config/GowsEngineConfigService';
import { GowsBootstrap } from '@waha/core/engines/gows/GowsBootstrap';
import { ISessionMeRepository } from '@waha/core/storage/ISessionMeRepository';
import { ISessionWorkerRepository } from '@waha/core/storage/ISessionWorkerRepository';
import { WAHAWebhook } from '@waha/structures/webhooks.dto';
Expand All @@ -29,7 +36,9 @@ import { WhatsappSession } from './session.abc';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const AsyncLock = require('async-lock');

export abstract class SessionManager implements BeforeApplicationShutdown {
export abstract class SessionManager
implements BeforeApplicationShutdown, OnApplicationBootstrap
{
public store: any;
public sessionAuthRepository: ISessionAuthRepository;
public sessionConfigRepository: ISessionConfigRepository;
Expand All @@ -42,8 +51,9 @@ export abstract class SessionManager implements BeforeApplicationShutdown {
LOCK_TIMEOUT = 10_000;

protected constructor(
protected config: WhatsappConfigService,
protected log: PinoLogger,
protected config: WhatsappConfigService,
protected gowsConfigService: GowsEngineConfigService,
) {
this.lock = new AsyncLock({
maxPending: Infinity,
Expand Down Expand Up @@ -160,7 +170,21 @@ export abstract class SessionManager implements BeforeApplicationShutdown {
beforeApplicationShutdown(signal?: string) {
return;
}

onApplicationBootstrap(): any {
return;
}

protected getEngineBootstrap(engine: WAHAEngine): EngineBootstrap {
const logger = this.log.logger.child({ engine: engine.toLowerCase() });
if (engine === WAHAEngine.GOWS) {
const config = this.gowsConfigService.getBootstrapConfig();
return new GowsBootstrap(logger, config);
}
return new NoopEngineBootstrap();
}
}

export function populateSessionInfo(
event: WAHAEvents,
session: WhatsappSession,
Expand Down
6 changes: 4 additions & 2 deletions src/core/abc/session.abc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { complete } from '@waha/utils/reactive/complete';
import { SwitchObservable } from '@waha/utils/reactive/SwitchObservable';
import * as fs from 'fs';
import * as lodash from 'lodash';
import { PinoLogger } from 'nestjs-pino';
import * as NodeCache from 'node-cache';
import { Logger } from 'pino';
import {
Expand Down Expand Up @@ -53,6 +54,7 @@ import {
MessageTextRequest,
MessageVideoRequest,
MessageVoiceRequest,
SendSeenRequest,
} from '../../structures/chatting.dto';
import { ContactQuery, ContactRequest } from '../../structures/contacts.dto';
import {
Expand Down Expand Up @@ -380,7 +382,7 @@ export abstract class WhatsappSession {

abstract reply(request: MessageReplyRequest);

abstract sendSeen(chat: ChatRequest);
abstract sendSeen(chat: SendSeenRequest);

abstract startTyping(chat: ChatRequest);

Expand Down Expand Up @@ -530,7 +532,7 @@ export abstract class WhatsappSession {
if (!has || refresh) {
await this.refreshProfilePicture(id);
}
return this.profilePictures.get(id);
return this.profilePictures.get(id) || null;
}

protected async refreshProfilePicture(id: string) {
Expand Down
2 changes: 2 additions & 0 deletions src/core/app.module.core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ServerDebugController,
} from '@waha/api/server.controller';
import { WebsocketGatewayCore } from '@waha/core/api/websocket.gateway.core';
import { GowsEngineConfigService } from '@waha/core/config/GowsEngineConfigService';
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';
Expand Down Expand Up @@ -148,6 +149,7 @@ const PROVIDERS = [
DashboardConfigServiceCore,
SwaggerConfigServiceCore,
WebJSEngineConfigService,
GowsEngineConfigService,
WhatsappConfigService,
EngineConfigService,
WebsocketGatewayCore,
Expand Down
26 changes: 26 additions & 0 deletions src/core/config/GowsEngineConfigService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
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) {}

getBootstrapConfig(): BootstrapConfig {
return {
path: this.configService.get('WAHA_GOWS_PATH'),
socket: this.getSocket(),
};
}

getSocket() {
return this.configService.get('WAHA_GOWS_SOCKET', '/tmp/gows.sock');
}

getConfig(): GowsConfig {
return {
connection: 'unix:' + this.getSocket(),
};
}
}
Loading

0 comments on commit 0b9f9b2

Please sign in to comment.