171 audio_count: audios.length, 172 transcript_chars: transcriptText.length, 173 transcribed_at: transcribedAt, 174 }; 175} 176 177async function updateTranscriptState(context, appelRowId, transcript, additionalFields = {}) { 178 await context.call("tables", "rows_update", { 179 table: "appels", 180 id: appelRowId, 181 fields: { transcript, ...additionalFields }, 182 }); 183} 184 185function terminalAnalysisFields(appel, status) { 186 return { 187 ai_analysis_status: status, 188 ...(!clean(appel.reservation_id) && ["", "pending_analysis"].includes(clean(appel.ai_outcome)) 189 ? { ai_outcome: status === "unclassified" ? "unclassified" : "analysis_failed" } 190 : {}), 191 }; 192} 193 194async function transcribe(context, storageFileId) { 195 const signed = await context.call("storage", "files_get_url", { 196 id: Number(storageFileId), 197 ttl_seconds: 30 * 60, 198 }); 199 if (!clean(signed?.url)) throw new Error(`Storage URL unavailable for file ${storageFileId}`); 200 201 const response = await context.integration("deepgram", "deepgram_listen", { 202 url: signed.url, 203 language: "fr", 204 model: "nova-3", 205 smart_format: true, 206 punctuate: true, 207 diarize: true, 208 }); 209 if (response && typeof response === "object" && response.success === false) { 210 throw new Error(`Deepgram transcription failed: ${clean(response.error || response.status) || "unknown error"}`); 211 } 212 const body = response?.data ?? response ?? {}; 213 const transcript = body?.results?.channels?.[0]?.alternatives?.[0]?.transcript 214 ?? body?.transcript; 215 if (typeof transcript !== "string") { 216 throw new Error("Deepgram returned an unexpected response"); 217 } 218 return transcript; 219} 220 221function objectValue(value) { 222 if (value && typeof value === "object" && !Array.isArray(value)) return value; 223 if (typeof value === "string") { 224 try { 225 const parsed = JSON.parse(value); 226 return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {}; 227 } catch { 228 return {}; 229 } 230 } 231 return {}; 232} 233 234function arrayValue(value) { 235 if (Array.isArray(value)) return value.filter((item) => item && typeof item === "object"); 236 if (typeof value === "string") { 237 try { 238 const parsed = JSON.parse(value); 239 return Array.isArray(parsed) ? parsed.filter((item) => item && typeof item === "object") : []; 240 } catch { 241 return []; 242 } 243 } 244 return [];