import { ObjectId } from "mongodb"; import type { Collection, WithId } from "mongodb"; import { getDb, getPhoneNumbersCollection } from "../index"; import type { Session } from "./sessions.types"; export const getSessionsCollection = (): Collection => getDb().collection("sessions"); const buildPhoneCandidates = (phone: string): string[] => { const raw = (phone ?? "").trim(); if (!raw) return []; const noPlus = raw.startsWith("+") ? raw.slice(1) : raw; const digitsOnly = raw.replace(/\D/g, ""); const digitsOnlyNoPlus = noPlus.replace(/\D/g, ""); return Array.from( new Set([raw, noPlus, digitsOnly, digitsOnlyNoPlus].filter(Boolean)), ); }; const buildFlowIdCandidates = (flowId: unknown): Array => { if (!flowId) return []; // Some sessions store flow_id as string, others as ObjectId. if (flowId instanceof ObjectId) { return [flowId, flowId.toString()]; } const asString = String(flowId); if (!asString) return []; if (ObjectId.isValid(asString)) { return [new ObjectId(asString), asString]; } return [asString]; }; export const findSessionById = ( sessionId: ObjectId, clientId: string, ): Promise | null> => { return getSessionsCollection().findOne({ _id: sessionId, clientId: clientId, }); }; export const findSessionOfIncomingCall = async (from: string, to: string) => { const toCandidates = buildPhoneCandidates(to); const fromCandidates = buildPhoneCandidates(from); const receiverPhoneData = await getPhoneNumbersCollection().findOne({ phone_number: { $in: toCandidates }, }); if (!receiverPhoneData) { return null; } const flowIdCandidates = buildFlowIdCandidates(receiverPhoneData.flow_id); const [session] = await getSessionsCollection() .aggregate>([ { $match: { flow_id: { $in: flowIdCandidates }, phone_numbers: { $elemMatch: { phoneNumber: { $in: fromCandidates } }, }, }, }, { $addFields: { phone_numbers: { $filter: { input: "$phone_numbers", as: "pn", cond: { $in: ["$$pn.phoneNumber", fromCandidates] }, }, }, }, }, { $limit: 1 }, ]) .toArray(); if (!session) { console.info("No session found for incoming call"); return null; } return session; };