Switch to Hono
This commit is contained in:
parent
9601e179bc
commit
9f0e1f8b61
10 changed files with 152 additions and 331 deletions
|
|
@ -7,10 +7,8 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@deltachat/jsonrpc-client": "^1.151.1",
|
"@deltachat/jsonrpc-client": "^1.151.1",
|
||||||
"@deltachat/stdio-rpc-server": "^1.151.1",
|
"@deltachat/stdio-rpc-server": "^1.151.1",
|
||||||
"@hapi/hapi": "^21.4.3",
|
"@hono/node-server": "^1.13.8",
|
||||||
"@hapipal/schmervice": "^3.0.0",
|
"hono": "^4.7.4",
|
||||||
"@hapipal/toys": "^4.0.0",
|
|
||||||
"hapi-pino": "^13.0.0",
|
|
||||||
"pino": "^9.6.0",
|
"pino": "^9.6.0",
|
||||||
"pino-pretty": "^13.0.0"
|
"pino-pretty": "^13.0.0"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,29 @@
|
||||||
import * as Hapi from "@hapi/hapi";
|
import { serve } from "@hono/node-server";
|
||||||
import hapiPino from "hapi-pino";
|
|
||||||
import Schmervice from "@hapipal/schmervice";
|
|
||||||
import DeltaChatService from "./service.ts";
|
import DeltaChatService from "./service.ts";
|
||||||
import {
|
import { createRoutes } from "./routes.ts";
|
||||||
ConfigureBotRoute,
|
|
||||||
GetBotRoute,
|
|
||||||
SendMessageRoute,
|
|
||||||
UnconfigureBotRoute,
|
|
||||||
HealthRoute,
|
|
||||||
} from "./routes.ts";
|
|
||||||
import { createLogger } from "./lib/logger";
|
import { createLogger } from "./lib/logger";
|
||||||
|
|
||||||
const logger = createLogger("bridge-deltachat-index");
|
const logger = createLogger("bridge-deltachat-index");
|
||||||
|
|
||||||
const server = Hapi.server({ port: 5001 });
|
|
||||||
|
|
||||||
const startServer = async () => {
|
|
||||||
await server.register({ plugin: hapiPino });
|
|
||||||
|
|
||||||
server.route(ConfigureBotRoute);
|
|
||||||
server.route(GetBotRoute);
|
|
||||||
server.route(SendMessageRoute);
|
|
||||||
server.route(UnconfigureBotRoute);
|
|
||||||
server.route(HealthRoute);
|
|
||||||
|
|
||||||
await server.register(Schmervice);
|
|
||||||
server.registerService(DeltaChatService);
|
|
||||||
|
|
||||||
await server.start();
|
|
||||||
|
|
||||||
return server;
|
|
||||||
};
|
|
||||||
|
|
||||||
const main = async () => {
|
const main = async () => {
|
||||||
await startServer();
|
const service = new DeltaChatService();
|
||||||
|
await service.initialize();
|
||||||
|
|
||||||
|
const app = createRoutes(service);
|
||||||
|
const port = parseInt(process.env.PORT || "5001", 10);
|
||||||
|
|
||||||
|
serve({ fetch: app.fetch, port }, (info) => {
|
||||||
|
logger.info({ port: info.port }, "bridge-deltachat listening");
|
||||||
|
});
|
||||||
|
|
||||||
|
const shutdown = async () => {
|
||||||
|
logger.info("Shutting down...");
|
||||||
|
await service.teardown();
|
||||||
|
process.exit(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
process.on("SIGTERM", shutdown);
|
||||||
|
process.on("SIGINT", shutdown);
|
||||||
};
|
};
|
||||||
|
|
||||||
main().catch((err) => {
|
main().catch((err) => {
|
||||||
|
|
|
||||||
|
|
@ -1,111 +1,54 @@
|
||||||
import * as Hapi from "@hapi/hapi";
|
import { Hono } from "hono";
|
||||||
import Toys from "@hapipal/toys";
|
import type DeltaChatService from "./service.ts";
|
||||||
import DeltaChatService from "./service.ts";
|
import { createLogger } from "./lib/logger";
|
||||||
|
|
||||||
const withDefaults = Toys.withRouteDefaults({
|
const logger = createLogger("bridge-deltachat-routes");
|
||||||
options: {
|
|
||||||
cors: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const getService = (request: Hapi.Request): DeltaChatService => {
|
export function createRoutes(service: DeltaChatService): Hono {
|
||||||
const { deltaChatService } = request.services();
|
const app = new Hono();
|
||||||
|
|
||||||
return deltaChatService as DeltaChatService;
|
app.post("/api/bots/:id/configure", async (c) => {
|
||||||
};
|
const id = c.req.param("id");
|
||||||
|
const { email, password } = await c.req.json<{ email: string; password: string }>();
|
||||||
|
|
||||||
interface ConfigureRequest {
|
try {
|
||||||
email: string;
|
const result = await service.configure(id, email, password);
|
||||||
password: string;
|
logger.info({ id, email }, "Bot configured");
|
||||||
|
return c.json(result);
|
||||||
|
} catch (err: any) {
|
||||||
|
logger.error({ id, error: err.message }, "Failed to configure bot");
|
||||||
|
return c.json({ error: err.message }, 500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/api/bots/:id", async (c) => {
|
||||||
|
const id = c.req.param("id");
|
||||||
|
return c.json(await service.getBot(id));
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/api/bots/:id/send", async (c) => {
|
||||||
|
const id = c.req.param("id");
|
||||||
|
const { email, message, attachments } = await c.req.json<{
|
||||||
|
email: string;
|
||||||
|
message: string;
|
||||||
|
attachments?: Array<{ data: string; filename: string; mime_type: string }>;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const result = await service.send(id, email, message, attachments);
|
||||||
|
logger.info({ id, attachmentCount: attachments?.length || 0 }, "Sent message");
|
||||||
|
return c.json({ result });
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/api/bots/:id/unconfigure", async (c) => {
|
||||||
|
const id = c.req.param("id");
|
||||||
|
await service.unconfigure(id);
|
||||||
|
logger.info({ id }, "Bot unconfigured");
|
||||||
|
return c.body(null, 200);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/api/health", (c) => {
|
||||||
|
return c.json({ status: "ok" });
|
||||||
|
});
|
||||||
|
|
||||||
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SendMessageRequest {
|
|
||||||
email: string;
|
|
||||||
message: string;
|
|
||||||
attachments?: Array<{ data: string; filename: string; mime_type: string }>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ConfigureBotRoute = withDefaults({
|
|
||||||
method: "post",
|
|
||||||
path: "/api/bots/{id}/configure",
|
|
||||||
options: {
|
|
||||||
description: "Configure a bot with email credentials",
|
|
||||||
async handler(request: Hapi.Request, h: Hapi.ResponseToolkit) {
|
|
||||||
const { id } = request.params;
|
|
||||||
const { email, password } = request.payload as ConfigureRequest;
|
|
||||||
const service = getService(request);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await service.configure(id, email, password);
|
|
||||||
request.logger.info({ id, email }, "Bot configured at %s", new Date().toISOString());
|
|
||||||
return h.response(result).code(200);
|
|
||||||
} catch (err: any) {
|
|
||||||
request.logger.error({ id, error: err.message }, "Failed to configure bot");
|
|
||||||
return h.response({ error: err.message }).code(500);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const GetBotRoute = withDefaults({
|
|
||||||
method: "get",
|
|
||||||
path: "/api/bots/{id}",
|
|
||||||
options: {
|
|
||||||
description: "Get bot status",
|
|
||||||
async handler(request: Hapi.Request, _h: Hapi.ResponseToolkit) {
|
|
||||||
const { id } = request.params;
|
|
||||||
const service = getService(request);
|
|
||||||
return service.getBot(id);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const SendMessageRoute = withDefaults({
|
|
||||||
method: "post",
|
|
||||||
path: "/api/bots/{id}/send",
|
|
||||||
options: {
|
|
||||||
description: "Send a message",
|
|
||||||
async handler(request: Hapi.Request, h: Hapi.ResponseToolkit) {
|
|
||||||
const { id } = request.params;
|
|
||||||
const { email, message, attachments } = request.payload as SendMessageRequest;
|
|
||||||
const service = getService(request);
|
|
||||||
|
|
||||||
const result = await service.send(id, email, message, attachments);
|
|
||||||
request.logger.info(
|
|
||||||
{ id, attachmentCount: attachments?.length || 0 },
|
|
||||||
"Sent a message at %s",
|
|
||||||
new Date().toISOString(),
|
|
||||||
);
|
|
||||||
|
|
||||||
return h.response({ result }).code(200);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const UnconfigureBotRoute = withDefaults({
|
|
||||||
method: "post",
|
|
||||||
path: "/api/bots/{id}/unconfigure",
|
|
||||||
options: {
|
|
||||||
description: "Unconfigure and remove a bot",
|
|
||||||
async handler(request: Hapi.Request, h: Hapi.ResponseToolkit) {
|
|
||||||
const { id } = request.params;
|
|
||||||
const service = getService(request);
|
|
||||||
|
|
||||||
await service.unconfigure(id);
|
|
||||||
request.logger.info({ id }, "Bot unconfigured at %s", new Date().toISOString());
|
|
||||||
|
|
||||||
return h.response().code(200);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const HealthRoute = withDefaults({
|
|
||||||
method: "get",
|
|
||||||
path: "/api/health",
|
|
||||||
options: {
|
|
||||||
description: "Health check",
|
|
||||||
async handler(_request: Hapi.Request, h: Hapi.ResponseToolkit) {
|
|
||||||
return h.response({ status: "ok" }).code(200);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
import { Server } from "@hapi/hapi";
|
|
||||||
import { Service } from "@hapipal/schmervice";
|
|
||||||
import { startDeltaChat, DeltaChat } from "@deltachat/stdio-rpc-server";
|
import { startDeltaChat, DeltaChat } from "@deltachat/stdio-rpc-server";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|
@ -17,14 +15,13 @@ interface BotMapping {
|
||||||
[botId: string]: number;
|
[botId: string]: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class DeltaChatService extends Service {
|
export default class DeltaChatService {
|
||||||
private dc: DeltaChat | null = null;
|
private dc: DeltaChat | null = null;
|
||||||
private botMapping: BotMapping = {};
|
private botMapping: BotMapping = {};
|
||||||
private dataDir: string;
|
private dataDir: string;
|
||||||
private mappingFile: string;
|
private mappingFile: string;
|
||||||
|
|
||||||
constructor(server: Server, options: never) {
|
constructor() {
|
||||||
super(server, options);
|
|
||||||
this.dataDir = process.env.DELTACHAT_DATA_DIR || "/home/node/deltachat-data";
|
this.dataDir = process.env.DELTACHAT_DATA_DIR || "/home/node/deltachat-data";
|
||||||
this.mappingFile = path.join(this.dataDir, "bot-mapping.json");
|
this.mappingFile = path.join(this.dataDir, "bot-mapping.json");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
import type DeltaChatService from "./service.ts";
|
|
||||||
|
|
||||||
declare module "@hapipal/schmervice" {
|
|
||||||
interface SchmerviceDecorator {
|
|
||||||
(namespace: "deltachat"): DeltaChatService;
|
|
||||||
}
|
|
||||||
type ServiceFunctionalInterface = { name: string };
|
|
||||||
}
|
|
||||||
|
|
@ -6,11 +6,9 @@
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@adiwajshing/keyed-db": "0.2.4",
|
"@adiwajshing/keyed-db": "0.2.4",
|
||||||
"@hapi/hapi": "^21.4.3",
|
"@hono/node-server": "^1.13.8",
|
||||||
"@hapipal/schmervice": "^3.0.0",
|
|
||||||
"@hapipal/toys": "^4.0.0",
|
|
||||||
"@whiskeysockets/baileys": "6.7.21",
|
"@whiskeysockets/baileys": "6.7.21",
|
||||||
"hapi-pino": "^13.0.0",
|
"hono": "^4.7.4",
|
||||||
"link-preview-js": "^3.1.0",
|
"link-preview-js": "^3.1.0",
|
||||||
"pino": "^9.6.0",
|
"pino": "^9.6.0",
|
||||||
"pino-pretty": "^13.0.0"
|
"pino-pretty": "^13.0.0"
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,29 @@
|
||||||
import * as Hapi from "@hapi/hapi";
|
import { serve } from "@hono/node-server";
|
||||||
import hapiPino from "hapi-pino";
|
|
||||||
import Schmervice from "@hapipal/schmervice";
|
|
||||||
import WhatsappService from "./service.ts";
|
import WhatsappService from "./service.ts";
|
||||||
import {
|
import { createRoutes } from "./routes.ts";
|
||||||
RegisterBotRoute,
|
|
||||||
UnverifyBotRoute,
|
|
||||||
GetBotRoute,
|
|
||||||
SendMessageRoute,
|
|
||||||
ReceiveMessageRoute,
|
|
||||||
} from "./routes.ts";
|
|
||||||
import { createLogger } from "./lib/logger";
|
import { createLogger } from "./lib/logger";
|
||||||
|
|
||||||
const logger = createLogger("bridge-whatsapp-index");
|
const logger = createLogger("bridge-whatsapp-index");
|
||||||
|
|
||||||
const server = Hapi.server({ port: 5000 });
|
|
||||||
|
|
||||||
const startServer = async () => {
|
|
||||||
await server.register({ plugin: hapiPino });
|
|
||||||
|
|
||||||
server.route(RegisterBotRoute);
|
|
||||||
server.route(UnverifyBotRoute);
|
|
||||||
server.route(GetBotRoute);
|
|
||||||
server.route(SendMessageRoute);
|
|
||||||
server.route(ReceiveMessageRoute);
|
|
||||||
|
|
||||||
await server.register(Schmervice);
|
|
||||||
server.registerService(WhatsappService);
|
|
||||||
|
|
||||||
await server.start();
|
|
||||||
|
|
||||||
return server;
|
|
||||||
};
|
|
||||||
|
|
||||||
const main = async () => {
|
const main = async () => {
|
||||||
await startServer();
|
const service = new WhatsappService();
|
||||||
|
await service.initialize();
|
||||||
|
|
||||||
|
const app = createRoutes(service);
|
||||||
|
const port = parseInt(process.env.PORT || "5000", 10);
|
||||||
|
|
||||||
|
serve({ fetch: app.fetch, port }, (info) => {
|
||||||
|
logger.info({ port: info.port }, "bridge-whatsapp listening");
|
||||||
|
});
|
||||||
|
|
||||||
|
const shutdown = async () => {
|
||||||
|
logger.info("Shutting down...");
|
||||||
|
await service.teardown();
|
||||||
|
process.exit(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
process.on("SIGTERM", shutdown);
|
||||||
|
process.on("SIGINT", shutdown);
|
||||||
};
|
};
|
||||||
|
|
||||||
main().catch((err) => {
|
main().catch((err) => {
|
||||||
|
|
|
||||||
|
|
@ -1,125 +1,58 @@
|
||||||
import * as Hapi from "@hapi/hapi";
|
import { Hono } from "hono";
|
||||||
import Toys from "@hapipal/toys";
|
import type WhatsappService from "./service.ts";
|
||||||
import WhatsappService from "./service.ts";
|
import { createLogger } from "./lib/logger";
|
||||||
|
|
||||||
const withDefaults = Toys.withRouteDefaults({
|
const logger = createLogger("bridge-whatsapp-routes");
|
||||||
options: {
|
|
||||||
cors: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const getService = (request: Hapi.Request): WhatsappService => {
|
export function createRoutes(service: WhatsappService): Hono {
|
||||||
const { whatsappService } = request.services();
|
const app = new Hono();
|
||||||
|
|
||||||
return whatsappService as WhatsappService;
|
app.post("/api/bots/:id/send", async (c) => {
|
||||||
};
|
const id = c.req.param("id");
|
||||||
|
const { phoneNumber, message, attachments } = await c.req.json<{
|
||||||
|
phoneNumber: string;
|
||||||
|
message: string;
|
||||||
|
attachments?: Array<{ data: string; filename: string; mime_type: string }>;
|
||||||
|
}>();
|
||||||
|
|
||||||
interface MessageRequest {
|
await service.send(id, phoneNumber, message, attachments);
|
||||||
phoneNumber: string;
|
logger.info({ id, attachmentCount: attachments?.length || 0 }, "Sent message");
|
||||||
message: string;
|
|
||||||
attachments?: Array<{ data: string; filename: string; mime_type: string }>;
|
return c.json({
|
||||||
|
result: {
|
||||||
|
recipient: phoneNumber,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
source: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/api/bots/:id/receive", async (c) => {
|
||||||
|
const id = c.req.param("id");
|
||||||
|
const date = new Date();
|
||||||
|
const twoDaysAgo = new Date(date.getTime());
|
||||||
|
twoDaysAgo.setDate(date.getDate() - 2);
|
||||||
|
|
||||||
|
const messages = await service.receive(id, twoDaysAgo);
|
||||||
|
return c.json(messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/api/bots/:id/register", async (c) => {
|
||||||
|
const id = c.req.param("id");
|
||||||
|
await service.register(id);
|
||||||
|
return c.body(null, 200);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/api/bots/:id/unverify", async (c) => {
|
||||||
|
const id = c.req.param("id");
|
||||||
|
await service.unverify(id);
|
||||||
|
return c.body(null, 200);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/api/bots/:id", async (c) => {
|
||||||
|
const id = c.req.param("id");
|
||||||
|
return c.json(service.getBot(id));
|
||||||
|
});
|
||||||
|
|
||||||
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SendMessageRoute = withDefaults({
|
|
||||||
method: "post",
|
|
||||||
path: "/api/bots/{id}/send",
|
|
||||||
options: {
|
|
||||||
description: "Send a message",
|
|
||||||
async handler(request: Hapi.Request, _h: Hapi.ResponseToolkit) {
|
|
||||||
const { id } = request.params;
|
|
||||||
const { phoneNumber, message, attachments } = request.payload as MessageRequest;
|
|
||||||
const whatsappService = getService(request);
|
|
||||||
await whatsappService.send(id, phoneNumber, message as string, attachments);
|
|
||||||
request.logger.info(
|
|
||||||
{
|
|
||||||
id,
|
|
||||||
attachmentCount: attachments?.length || 0,
|
|
||||||
},
|
|
||||||
"Sent a message at %s",
|
|
||||||
new Date().toISOString(),
|
|
||||||
);
|
|
||||||
|
|
||||||
return _h
|
|
||||||
.response({
|
|
||||||
result: {
|
|
||||||
recipient: phoneNumber,
|
|
||||||
timestamp: new Date().toISOString(),
|
|
||||||
source: id,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.code(200);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const ReceiveMessageRoute = withDefaults({
|
|
||||||
method: "get",
|
|
||||||
path: "/api/bots/{id}/receive",
|
|
||||||
options: {
|
|
||||||
description: "Receive messages",
|
|
||||||
async handler(request: Hapi.Request, _h: Hapi.ResponseToolkit) {
|
|
||||||
const { id } = request.params;
|
|
||||||
const whatsappService = getService(request);
|
|
||||||
const date = new Date();
|
|
||||||
const twoDaysAgo = new Date(date.getTime());
|
|
||||||
twoDaysAgo.setDate(date.getDate() - 2);
|
|
||||||
request.logger.info({ id }, "Received messages at %s", new Date().toISOString());
|
|
||||||
|
|
||||||
return whatsappService.receive(id, twoDaysAgo);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const RegisterBotRoute = withDefaults({
|
|
||||||
method: "post",
|
|
||||||
path: "/api/bots/{id}/register",
|
|
||||||
options: {
|
|
||||||
description: "Register a bot",
|
|
||||||
async handler(request: Hapi.Request, _h: Hapi.ResponseToolkit) {
|
|
||||||
const { id } = request.params;
|
|
||||||
const whatsappService = getService(request);
|
|
||||||
|
|
||||||
await whatsappService.register(id);
|
|
||||||
/*
|
|
||||||
, (error: string) => {
|
|
||||||
if (error) {
|
|
||||||
return _h.response(error).code(500);
|
|
||||||
}
|
|
||||||
request.logger.info({ id }, "Register bot at %s", new Date());
|
|
||||||
|
|
||||||
return _h.response().code(200);
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
return _h.response().code(200);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const UnverifyBotRoute = withDefaults({
|
|
||||||
method: "post",
|
|
||||||
path: "/api/bots/{id}/unverify",
|
|
||||||
options: {
|
|
||||||
description: "Unverify bot",
|
|
||||||
async handler(request: Hapi.Request, _h: Hapi.ResponseToolkit) {
|
|
||||||
const { id } = request.params;
|
|
||||||
const whatsappService = getService(request);
|
|
||||||
|
|
||||||
return whatsappService.unverify(id);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const GetBotRoute = withDefaults({
|
|
||||||
method: "get",
|
|
||||||
path: "/api/bots/{id}",
|
|
||||||
options: {
|
|
||||||
description: "Get bot info",
|
|
||||||
async handler(request: Hapi.Request, _h: Hapi.ResponseToolkit) {
|
|
||||||
const { id } = request.params;
|
|
||||||
const whatsappService = getService(request);
|
|
||||||
|
|
||||||
return whatsappService.getBot(id);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
import { Server } from "@hapi/hapi";
|
|
||||||
import { Service } from "@hapipal/schmervice";
|
|
||||||
import makeWASocket, {
|
import makeWASocket, {
|
||||||
DisconnectReason,
|
DisconnectReason,
|
||||||
proto,
|
proto,
|
||||||
|
|
@ -23,16 +21,12 @@ const logger = createLogger("bridge-whatsapp-service");
|
||||||
|
|
||||||
export type AuthCompleteCallback = (error?: string) => void;
|
export type AuthCompleteCallback = (error?: string) => void;
|
||||||
|
|
||||||
export default class WhatsappService extends Service {
|
export default class WhatsappService {
|
||||||
connections: { [key: string]: any } = {};
|
connections: { [key: string]: any } = {};
|
||||||
loginConnections: { [key: string]: any } = {};
|
loginConnections: { [key: string]: any } = {};
|
||||||
|
|
||||||
static browserDescription: [string, string, string] = ["Bridge", "Chrome", "2.0"];
|
static browserDescription: [string, string, string] = ["Bridge", "Chrome", "2.0"];
|
||||||
|
|
||||||
constructor(server: Server, options: never) {
|
|
||||||
super(server, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
getBaseDirectory(): string {
|
getBaseDirectory(): string {
|
||||||
return `/home/node/baileys`;
|
return `/home/node/baileys`;
|
||||||
}
|
}
|
||||||
|
|
@ -87,7 +81,6 @@ export default class WhatsappService extends Service {
|
||||||
|
|
||||||
private async createConnection(
|
private async createConnection(
|
||||||
botID: string,
|
botID: string,
|
||||||
server: Server,
|
|
||||||
options: any,
|
options: any,
|
||||||
authCompleteCallback?: any,
|
authCompleteCallback?: any,
|
||||||
) {
|
) {
|
||||||
|
|
@ -125,13 +118,13 @@ export default class WhatsappService extends Service {
|
||||||
const disconnectStatusCode = (lastDisconnect?.error as any)?.output?.statusCode;
|
const disconnectStatusCode = (lastDisconnect?.error as any)?.output?.statusCode;
|
||||||
if (disconnectStatusCode === DisconnectReason.restartRequired) {
|
if (disconnectStatusCode === DisconnectReason.restartRequired) {
|
||||||
logger.info("reconnecting after got new login");
|
logger.info("reconnecting after got new login");
|
||||||
await this.createConnection(botID, server, options);
|
await this.createConnection(botID, options);
|
||||||
authCompleteCallback?.();
|
authCompleteCallback?.();
|
||||||
} else if (disconnectStatusCode !== DisconnectReason.loggedOut) {
|
} else if (disconnectStatusCode !== DisconnectReason.loggedOut) {
|
||||||
logger.info("reconnecting");
|
logger.info("reconnecting");
|
||||||
await this.sleep(pause);
|
await this.sleep(pause);
|
||||||
pause *= 2;
|
pause *= 2;
|
||||||
this.createConnection(botID, server, options);
|
this.createConnection(botID, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -178,7 +171,7 @@ export default class WhatsappService extends Service {
|
||||||
const { version, isLatest } = await fetchLatestBaileysVersion();
|
const { version, isLatest } = await fetchLatestBaileysVersion();
|
||||||
logger.info({ version: version.join("."), isLatest }, "using WA version");
|
logger.info({ version: version.join("."), isLatest }, "using WA version");
|
||||||
|
|
||||||
await this.createConnection(botID, this.server, {
|
await this.createConnection(botID, {
|
||||||
browser: WhatsappService.browserDescription,
|
browser: WhatsappService.browserDescription,
|
||||||
version,
|
version,
|
||||||
});
|
});
|
||||||
|
|
@ -355,7 +348,6 @@ export default class WhatsappService extends Service {
|
||||||
const { version } = await fetchLatestBaileysVersion();
|
const { version } = await fetchLatestBaileysVersion();
|
||||||
await this.createConnection(
|
await this.createConnection(
|
||||||
botID,
|
botID,
|
||||||
this.server,
|
|
||||||
{ version, browser: WhatsappService.browserDescription },
|
{ version, browser: WhatsappService.browserDescription },
|
||||||
callback,
|
callback,
|
||||||
);
|
);
|
||||||
|
|
@ -452,10 +444,6 @@ export default class WhatsappService extends Service {
|
||||||
_botID: string,
|
_botID: string,
|
||||||
_lastReceivedDate: Date,
|
_lastReceivedDate: Date,
|
||||||
): Promise<proto.IWebMessageInfo[]> {
|
): Promise<proto.IWebMessageInfo[]> {
|
||||||
// loadAllUnreadMessages() was removed in Baileys 7.x
|
|
||||||
// Messages are now delivered via events (messages.upsert, messaging-history.set)
|
|
||||||
// and forwarded to webhooks automatically.
|
|
||||||
// See: https://baileys.wiki/docs/migration/to-v7.0.0/
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Message polling is no longer supported in Baileys 7.x. " +
|
"Message polling is no longer supported in Baileys 7.x. " +
|
||||||
"Please configure a webhook to receive messages instead. " +
|
"Please configure a webhook to receive messages instead. " +
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
import type WhatsappService from "./service.ts";
|
|
||||||
|
|
||||||
declare module "@hapipal/schmervice" {
|
|
||||||
interface SchmerviceDecorator {
|
|
||||||
(namespace: "whatsapp"): WhatsappService;
|
|
||||||
}
|
|
||||||
type ServiceFunctionalInterface = { name: string };
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue