- Create new @link-stack/logger package wrapping Pino for structured logging - Replace all console.log/error/warn statements across the monorepo - Configure environment-aware logging (pretty-print in dev, JSON in prod) - Add automatic redaction of sensitive fields (passwords, tokens, etc.) - Remove dead commented-out logger file from bridge-worker - Follow Pino's standard argument order (context object first, message second) - Support log levels via LOG_LEVEL environment variable - Export TypeScript types for better IDE support This provides consistent, structured logging across all applications and packages, making debugging easier and production logs more parseable.
73 lines
2.2 KiB
TypeScript
73 lines
2.2 KiB
TypeScript
/* eslint-disable camelcase */
|
|
// import { SavedVoiceProvider } from "@digiresilience/bridge-db";
|
|
import Twilio from "twilio";
|
|
import { CallInstance } from "twilio/lib/rest/api/v2010/account/call";
|
|
import { Zammad, getOrCreateUser } from "./zammad.js";
|
|
import { createLogger } from "@link-stack/logger";
|
|
|
|
const logger = createLogger('bridge-worker-common');
|
|
|
|
type SavedVoiceProvider = any;
|
|
|
|
export const twilioClientFor = (
|
|
provider: SavedVoiceProvider,
|
|
): Twilio.Twilio => {
|
|
const { accountSid, apiKeySid, apiKeySecret } = provider.credentials;
|
|
if (!accountSid || !apiKeySid || !apiKeySecret)
|
|
throw new Error(
|
|
`twilio provider ${provider.name} does not have credentials`,
|
|
);
|
|
|
|
return Twilio(apiKeySid, apiKeySecret, {
|
|
accountSid,
|
|
});
|
|
};
|
|
|
|
export const createZammadTicket = async (
|
|
call: CallInstance,
|
|
mp3: Buffer,
|
|
): Promise<void> => {
|
|
const title = `Call from ${call.fromFormatted} at ${call.startTime}`;
|
|
const body = `<ul>
|
|
<li>Caller: ${call.fromFormatted}</li>
|
|
<li>Service Number: ${call.toFormatted}</li>
|
|
<li>Call Duration: ${call.duration} seconds</li>
|
|
<li>Start Time: ${call.startTime}</li>
|
|
<li>End Time: ${call.endTime}</li>
|
|
</ul>
|
|
<p>See the attached recording.</p>`;
|
|
const filename = `${call.sid}-${call.startTime}.mp3`;
|
|
const zammad = Zammad(
|
|
{
|
|
token: "EviH_WL0p6YUlCoIER7noAZEAPsYA_fVU4FZCKdpq525Vmzzvl8d7dNuP_8d-Amb",
|
|
},
|
|
"https://demo.digiresilience.org",
|
|
);
|
|
try {
|
|
const customer = await getOrCreateUser(zammad, call.fromFormatted);
|
|
await zammad.ticket.create({
|
|
title,
|
|
group: "Finances",
|
|
note: "This ticket was created automaticaly from a recorded phone call.",
|
|
customer_id: customer.id,
|
|
article: {
|
|
body,
|
|
subject: title,
|
|
content_type: "text/html",
|
|
type: "note",
|
|
attachments: [
|
|
{
|
|
filename,
|
|
data: mp3.toString("base64"),
|
|
"mime-type": "audio/mpeg",
|
|
},
|
|
],
|
|
},
|
|
});
|
|
} catch (error: any) {
|
|
if (error.isBoom) {
|
|
logger.error({ output: error.output }, 'Zammad ticket creation failed');
|
|
throw new Error("Failed to create zamamd ticket");
|
|
}
|
|
}
|
|
};
|