feat: activate mod_xml_curl with b2bcall-fs-config (agente.md secao 26)
- apps/freeswitch-config (b2bcall-fs-config): Fastify service implementing the mod_xml_curl HTTP protocol (form-encoded POST -> XML response), containerized, no host port published - reactivated mod_xml_curl in FreeSWITCH, binding restricted to directory|dialplan only (configuration was removed after testing showed it firing several unnecessary HTTP round-trips at boot for module configs we don't need dynamic — matches agente.md's own 'don't put every critical config through XML Curl' guidance) - no extensions/dialplan tables exist yet (next phases), so the service always answers 'not found' for now — this phase only proves the wire protocol works without breaking the static vanilla config fallback - verified end-to-end: user/8888 (nowhere) -> SUBSCRIBER_ABSENT via fs-config; user/1000 (static vanilla extension) -> USER_NOT_REGISTERED, proving FreeSWITCH correctly falls through to static XML when xml_curl says not found - docs/XML_CURL.md, including the not-yet-authenticated endpoint note (fine while it only returns not-found; needs gateway-credentials before serving real directory/dialplan data)
This commit is contained in:
17
apps/freeswitch-config/Dockerfile
Normal file
17
apps/freeswitch-config/Dockerfile
Normal file
@@ -0,0 +1,17 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
FROM node:22-slim
|
||||
|
||||
RUN corepack enable && corepack prepare pnpm@11.24.0 --activate
|
||||
|
||||
WORKDIR /repo
|
||||
|
||||
COPY pnpm-workspace.yaml package.json pnpm-lock.yaml tsconfig.base.json ./
|
||||
COPY packages/types packages/types
|
||||
COPY packages/shared packages/shared
|
||||
COPY apps/freeswitch-config apps/freeswitch-config
|
||||
|
||||
RUN pnpm install --frozen-lockfile --filter @b2bcall/freeswitch-config...
|
||||
|
||||
WORKDIR /repo/apps/freeswitch-config
|
||||
|
||||
CMD ["pnpm", "exec", "tsx", "src/main.ts"]
|
||||
21
apps/freeswitch-config/package.json
Normal file
21
apps/freeswitch-config/package.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "@b2bcall/freeswitch-config",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "tsx watch src/main.ts",
|
||||
"build": "tsc -p tsconfig.json",
|
||||
"start": "node dist/main.js",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@b2bcall/shared": "workspace:*",
|
||||
"@fastify/formbody": "^8.0.1",
|
||||
"fastify": "5.12.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.0.0",
|
||||
"tsx": "^4.23.12",
|
||||
"typescript": "^5.7.0"
|
||||
}
|
||||
}
|
||||
58
apps/freeswitch-config/src/main.ts
Normal file
58
apps/freeswitch-config/src/main.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import Fastify from "fastify";
|
||||
import formbody from "@fastify/formbody";
|
||||
import { createLogger } from "@b2bcall/shared";
|
||||
|
||||
const logger = createLogger("b2bcall-fs-config");
|
||||
|
||||
/**
|
||||
* Resposta padrão do protocolo XML Curl pra "não achei nada aqui" — o
|
||||
* FreeSWITCH cai de volta pras outras fontes XML registradas (a config
|
||||
* estática vanilla continua funcionando normalmente).
|
||||
*/
|
||||
const NOT_FOUND_XML = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="freeswitch/xml">
|
||||
<section name="result">
|
||||
<result status="not found"/>
|
||||
</section>
|
||||
</document>`;
|
||||
|
||||
interface XmlCurlBody {
|
||||
section?: string;
|
||||
tag_name?: string;
|
||||
key_name?: string;
|
||||
key_value?: string;
|
||||
purpose?: string;
|
||||
user?: string;
|
||||
domain?: string;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const app = Fastify({ logger: false });
|
||||
await app.register(formbody);
|
||||
|
||||
app.post<{ Body: XmlCurlBody }>("/", async (request, reply) => {
|
||||
const { section, purpose, user, domain } = request.body ?? {};
|
||||
|
||||
logger.info("requisicao xml_curl recebida", { section, purpose, user, domain });
|
||||
|
||||
// Nenhuma tabela de extensions/dialplan existe ainda (fases Extensions/
|
||||
// Trunks/Dialplan, agente.md secao 232). Por enquanto respondemos
|
||||
// sempre "not found" — prova o encanamento (FreeSWITCH -> mod_xml_curl
|
||||
// -> este servico -> XML valido) sem afetar a config estatica vanilla,
|
||||
// que continua sendo consultada como fallback.
|
||||
reply.header("Content-Type", "text/xml");
|
||||
return NOT_FOUND_XML;
|
||||
});
|
||||
|
||||
app.get("/health", async () => ({ status: "ok" }));
|
||||
|
||||
const port = Number(process.env.PORT ?? 8080);
|
||||
await app.listen({ port, host: "0.0.0.0" });
|
||||
logger.info(`b2bcall-fs-config ouvindo na porta ${port}`);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
logger.error("falha fatal ao iniciar b2bcall-fs-config", { error: String(err) });
|
||||
process.exit(1);
|
||||
});
|
||||
9
apps/freeswitch-config/tsconfig.json
Normal file
9
apps/freeswitch-config/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
Reference in New Issue
Block a user