Add Signal and Whatsapp Docker CI

This commit is contained in:
Darren Clarke 2024-05-15 10:27:14 +02:00
parent b8ff61265b
commit 6305a8b0bc
12 changed files with 99 additions and 8 deletions

2
.gitignore vendored
View file

@ -1,7 +1,7 @@
node_modules node_modules
.env .env
.turbo .turbo
.tsbuildinfo *.tsbuildinfo
build/** build/**
**/dist/** **/dist/**
.next/** .next/**

View file

@ -106,6 +106,28 @@ bridge-worker-docker-release:
variables: variables:
DOCKER_NS: ${CI_REGISTRY}/digiresilience/link/link-stack/bridge-worker DOCKER_NS: ${CI_REGISTRY}/digiresilience/link/link-stack/bridge-worker
bridge-whatsapp-docker-build:
extends: .docker-build
variables:
DOCKER_NS: ${CI_REGISTRY}/digiresilience/link/link-stack/bridge-whatsapp
DOCKERFILE_PATH: ./apps/bridge-whatsapp/Dockerfile
bridge-whatsapp-docker-release:
extends: .docker-release
variables:
DOCKER_NS: ${CI_REGISTRY}/digiresilience/link/link-stack/bridge-whatsapp
signal-cli-rest-api-docker-build:
extends: .docker-build
variables:
DOCKER_NS: ${CI_REGISTRY}/digiresilience/link/link-stack/signal-cli-rest-api
DOCKERFILE_PATH: ./docker/signal-cli-rest-api/Dockerfile
signal-cli-rest-api-docker-release:
extends: .docker-release
variables:
DOCKER_NS: ${CI_REGISTRY}/digiresilience/link/link-stack/signal-cli-rest-api
memcached-docker-build: memcached-docker-build:
extends: .docker-build extends: .docker-build
variables: variables:

View file

@ -0,0 +1 @@
export { receiveMessage as POST } from "bridge-ui";

View file

@ -0,0 +1,38 @@
FROM node:20-bookworm AS base
FROM base AS builder
ARG APP_DIR=/opt/bridge-whatsapp
RUN mkdir -p ${APP_DIR}/
RUN npm i -g turbo
WORKDIR ${APP_DIR}
COPY . .
RUN turbo prune --scope=bridge-whatsapp --docker
FROM base AS installer
ARG APP_DIR=/opt/bridge-whatsapp
WORKDIR ${APP_DIR}
COPY --from=builder ${APP_DIR}/out/json/ .
COPY --from=builder ${APP_DIR}/out/full/ .
COPY --from=builder ${APP_DIR}/out/package-lock.json ./package-lock.json
RUN npm ci
RUN npm i -g turbo
RUN turbo run build --filter=bridge-whatsapp
FROM base as runner
ARG BUILD_DATE
ARG VERSION
ARG APP_DIR=/opt/bridge-whatsapp
RUN mkdir -p ${APP_DIR}/
RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
apt-get install -y --no-install-recommends \
dumb-init
WORKDIR ${APP_DIR}
COPY --from=installer ${APP_DIR} ./
RUN chown -R node:node ${APP_DIR}
WORKDIR ${APP_DIR}/apps/bridge-whatsapp/
RUN chmod +x docker-entrypoint.sh
USER node
EXPOSE 5000
ENV PORT 5000
ENV NODE_ENV production
ENTRYPOINT ["/opt/bridge-whatsapp/apps/bridge-whatsapp/docker-entrypoint.sh"]

View file

@ -0,0 +1,5 @@
#!/bin/bash
set -e
echo "starting bridge-whatsapp"
exec dumb-init npm run start

View file

@ -2,7 +2,7 @@
"name": "bridge-whatsapp", "name": "bridge-whatsapp",
"version": "0.3.0", "version": "0.3.0",
"type": "module", "type": "module",
"main": "build/main/main.js", "main": "build/main/index.js",
"author": "Darren Clarke <darren@redaranj.com>", "author": "Darren Clarke <darren@redaranj.com>",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"dependencies": { "dependencies": {
@ -28,6 +28,7 @@
}, },
"scripts": { "scripts": {
"build": "tsc -p tsconfig.json", "build": "tsc -p tsconfig.json",
"dev": "tsx src/index.ts" "dev": "tsx src/index.ts",
"start": "node build/main/index.js"
} }
} }

View file

@ -2,7 +2,7 @@ import * as Hapi from "@hapi/hapi";
import * as AuthBearer from "hapi-auth-bearer-token"; import * as AuthBearer from "hapi-auth-bearer-token";
import hapiPino from "hapi-pino"; import hapiPino from "hapi-pino";
import Schmervice from "@hapipal/schmervice"; import Schmervice from "@hapipal/schmervice";
import WhatsappService from "./service"; import WhatsappService from "./service.js";
import { import {
GetAllWhatsappBotsRoute, GetAllWhatsappBotsRoute,
GetBotsRoute, GetBotsRoute,
@ -12,7 +12,7 @@ import {
UnverifyBotRoute, UnverifyBotRoute,
RefreshBotRoute, RefreshBotRoute,
CreateBotRoute, CreateBotRoute,
} from "./routes"; } from "./routes.js";
const server = Hapi.server({ host: "localhost", port: 5000 }); const server = Hapi.server({ host: "localhost", port: 5000 });

View file

@ -1,6 +1,6 @@
import * as Hapi from "@hapi/hapi"; import * as Hapi from "@hapi/hapi";
import * as Helpers from "./helpers";
import Boom from "@hapi/boom"; import Boom from "@hapi/boom";
import * as Helpers from "./helpers.js";
export const GetAllWhatsappBotsRoute = Helpers.withDefaults({ export const GetAllWhatsappBotsRoute = Helpers.withDefaults({
method: "get", method: "get",

View file

@ -1,4 +1,4 @@
import type WhatsappService from "./service"; import type WhatsappService from "./service.js";
declare module "@hapipal/schmervice" { declare module "@hapipal/schmervice" {
interface SchmerviceDecorator { interface SchmerviceDecorator {

View file

@ -5,4 +5,9 @@ export { Edit } from "./components/Edit";
export { Detail } from "./components/Detail"; export { Detail } from "./components/Detail";
export { ServiceLayout } from "./components/ServiceLayout"; export { ServiceLayout } from "./components/ServiceLayout";
export { serviceConfig, getServiceTable } from "./config/config"; export { serviceConfig, getServiceTable } from "./config/config";
export { getBot, sendMessage, handleWebhook } from "./lib/routing"; export {
getBot,
sendMessage,
receiveMessage,
handleWebhook,
} from "./lib/routing";

View file

@ -12,6 +12,11 @@ export const sendMessage = async (
params: ServiceParams, params: ServiceParams,
): Promise<NextResponse> => getService(params)?.sendMessage(req, params); ): Promise<NextResponse> => getService(params)?.sendMessage(req, params);
export const receiveMessage = async (
req: NextRequest,
params: ServiceParams,
): Promise<NextResponse> => getService(params)?.receiveMessage(req, params);
export const handleWebhook = async ( export const handleWebhook = async (
req: NextRequest, req: NextRequest,
params: ServiceParams, params: ServiceParams,

View file

@ -82,6 +82,20 @@ export class Service {
return NextResponse.json({ response: "ok" }); return NextResponse.json({ response: "ok" });
} }
async receiveMessage(
req: NextRequest,
{ params: { service, token } }: ServiceParams,
): Promise<NextResponse> {
const message = await req.json();
const worker = await getWorkerUtils();
await worker.addJob(`${service}/receive-${service}-message`, {
token,
message,
});
return NextResponse.json({ response: "ok" });
}
async handleWebhook(_req: NextRequest): Promise<NextResponse> { async handleWebhook(_req: NextRequest): Promise<NextResponse> {
return NextResponse.error() as any; return NextResponse.error() as any;
} }