Restructure omni services and add Chatwoot research snapshot

This commit is contained in:
Ruslan Bakiev
2026-02-21 11:11:27 +07:00
parent edea7a0034
commit b73babbbf6
7732 changed files with 978203 additions and 32 deletions

108
omni_inbound/src/server.ts Normal file
View File

@@ -0,0 +1,108 @@
import { createServer, type IncomingMessage, type ServerResponse } from "node:http";
import { RECEIVER_FLOW_QUEUE_NAME, enqueueInboundEvent, isDuplicateJobError } from "./queue";
import { parseTelegramBusinessUpdate } from "./telegram";
const MAX_BODY_SIZE_BYTES = Number(process.env.MAX_BODY_SIZE_BYTES || 1024 * 1024);
function writeJson(res: ServerResponse, statusCode: number, body: unknown) {
const payload = JSON.stringify(body);
res.statusCode = statusCode;
res.setHeader("content-type", "application/json; charset=utf-8");
res.end(payload);
}
async function readJsonBody(req: IncomingMessage): Promise<unknown> {
const chunks: Buffer[] = [];
let total = 0;
for await (const chunk of req) {
const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
total += buf.length;
if (total > MAX_BODY_SIZE_BYTES) {
throw new Error(`payload_too_large:${MAX_BODY_SIZE_BYTES}`);
}
chunks.push(buf);
}
const raw = Buffer.concat(chunks).toString("utf8");
if (!raw) return {};
return JSON.parse(raw);
}
function validateTelegramSecret(req: IncomingMessage): boolean {
const expected = (process.env.TELEGRAM_WEBHOOK_SECRET || "").trim();
if (!expected) return true;
const incoming = String(req.headers["x-telegram-bot-api-secret-token"] || "").trim();
return incoming !== "" && incoming === expected;
}
export function startServer() {
const port = Number(process.env.PORT || 8080);
const server = createServer(async (req, res) => {
if (!req.url || !req.method) {
writeJson(res, 404, { ok: false, error: "not_found" });
return;
}
if (req.url === "/health" && req.method === "GET") {
writeJson(res, 200, {
ok: true,
service: "omni_inbound",
queue: RECEIVER_FLOW_QUEUE_NAME,
now: new Date().toISOString(),
});
return;
}
if (req.url === "/webhooks/telegram/business" && req.method === "POST") {
if (!validateTelegramSecret(req)) {
writeJson(res, 401, { ok: false, error: "invalid_webhook_secret" });
return;
}
try {
const body = await readJsonBody(req);
const envelope = parseTelegramBusinessUpdate(body);
await enqueueInboundEvent(envelope);
writeJson(res, 200, {
ok: true,
queued: true,
duplicate: false,
providerEventId: envelope.providerEventId,
idempotencyKey: envelope.idempotencyKey,
});
} catch (error) {
if (isDuplicateJobError(error)) {
writeJson(res, 200, {
ok: true,
queued: false,
duplicate: true,
});
return;
}
const message = error instanceof Error ? error.message : String(error);
const statusCode = message.startsWith("payload_too_large:") ? 413 : 503;
writeJson(res, statusCode, {
ok: false,
error: "receiver_enqueue_failed",
message,
});
}
return;
}
writeJson(res, 404, { ok: false, error: "not_found" });
});
server.listen(port, "0.0.0.0", () => {
console.log(`[omni_inbound] listening on :${port}`);
});
return server;
}