feat: add Event Socket integration (b2bcall-fs-events)
- packages/telephony: TelephonyProvider interface (agente.md secao 25) and
FreeSwitchTelephonyProvider implementation over the 'esl' library
(actively maintained, TypeScript-native, built-in reconnect-with-backoff
satisfying secao 195); normalizeEslEvent() translates raw ESL events into
the internal vocabulary (secao 24)
- apps/freeswitch-events (b2bcall-fs-events): permanent ESL connection,
resubscribes on every reconnect, publishes normalized events to the
'b2bcall:events' Redis pub/sub channel; containerized (Dockerfile +
docker-compose service) since its whole job is reaching the freeswitch
container by internal hostname
- packages/shared: reusable createLogger() (structured JSON per secao 189),
fixed a BigInt serialization crash surfaced by the esl library's error
stats
- found and fixed a real FreeSWITCH 1.11 default: without an explicit
apply-inbound-acl, mod_event_socket silently rejects any non-loopback
connection ('Access Denied, go away.') even with the correct password —
added a dedicated ACL (loopback + the Docker Compose network range, never
0.0.0.0/0) in infrastructure/freeswitch/overrides/autoload_configs/
- verified end-to-end with a local loopback test call: CALL_CREATED ->
CALL_ANSWERED -> CALL_ENDED observed on the Redis channel with the
correct callUuid and hangup cause
- docs/EVENT_SOCKET.md
This commit is contained in:
@@ -1 +1,2 @@
|
||||
export * from "@b2bcall/types";
|
||||
export * from "./logger";
|
||||
|
||||
28
packages/shared/src/logger.ts
Normal file
28
packages/shared/src/logger.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Logging JSON estruturado (agente.md secao 189). Sempre inclui `service` e
|
||||
* `ts`; nunca logar secrets — quem chama é responsável por isso.
|
||||
*/
|
||||
export interface Logger {
|
||||
debug(msg: string, context?: Record<string, unknown>): void;
|
||||
info(msg: string, context?: Record<string, unknown>): void;
|
||||
warn(msg: string, context?: Record<string, unknown>): void;
|
||||
error(msg: string, context?: Record<string, unknown>): void;
|
||||
}
|
||||
|
||||
export function createLogger(service: string): Logger {
|
||||
const write = (level: string, msg: string, context: Record<string, unknown> = {}) => {
|
||||
process.stdout.write(
|
||||
`${JSON.stringify(
|
||||
{ level, service, msg, ts: new Date().toISOString(), ...context },
|
||||
(_key, value) => (typeof value === "bigint" ? value.toString() : value),
|
||||
)}\n`,
|
||||
);
|
||||
};
|
||||
|
||||
return {
|
||||
debug: (msg, context) => write("debug", msg, context),
|
||||
info: (msg, context) => write("info", msg, context),
|
||||
warn: (msg, context) => write("warn", msg, context),
|
||||
error: (msg, context) => write("error", msg, context),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user