mirror of
https://github.com/kjanat/livedash-node.git
synced 2026-01-16 09:52:09 +01:00
feat: add rawTranscriptContent field to SessionImport model
feat: enhance server initialization with environment validation and import processing scheduler test: add Jest setup for unit tests and mock console methods test: implement unit tests for environment management and validation test: create unit tests for transcript fetcher functionality
This commit is contained in:
151
lib/transcriptFetcher.ts
Normal file
151
lib/transcriptFetcher.ts
Normal file
@ -0,0 +1,151 @@
|
||||
// Transcript fetching utility
|
||||
import fetch from "node-fetch";
|
||||
|
||||
export interface TranscriptFetchResult {
|
||||
success: boolean;
|
||||
content?: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch transcript content from a URL
|
||||
* @param url The transcript URL
|
||||
* @param username Optional username for authentication
|
||||
* @param password Optional password for authentication
|
||||
* @returns Promise with fetch result
|
||||
*/
|
||||
export async function fetchTranscriptContent(
|
||||
url: string,
|
||||
username?: string,
|
||||
password?: string
|
||||
): Promise<TranscriptFetchResult> {
|
||||
try {
|
||||
if (!url || !url.trim()) {
|
||||
return {
|
||||
success: false,
|
||||
error: 'No transcript URL provided',
|
||||
};
|
||||
}
|
||||
|
||||
// Prepare authentication header if credentials provided
|
||||
const authHeader =
|
||||
username && password
|
||||
? "Basic " + Buffer.from(`${username}:${password}`).toString("base64")
|
||||
: undefined;
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
'User-Agent': 'LiveDash-Transcript-Fetcher/1.0',
|
||||
};
|
||||
|
||||
if (authHeader) {
|
||||
headers.Authorization = authHeader;
|
||||
}
|
||||
|
||||
// Fetch the transcript with timeout
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 30000); // 30 second timeout
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers,
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
|
||||
if (!response.ok) {
|
||||
return {
|
||||
success: false,
|
||||
error: `HTTP ${response.status}: ${response.statusText}`,
|
||||
};
|
||||
}
|
||||
|
||||
const content = await response.text();
|
||||
|
||||
if (!content || content.trim().length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
error: 'Empty transcript content',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
content: content.trim(),
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
|
||||
// Handle common network errors
|
||||
if (errorMessage.includes('ENOTFOUND')) {
|
||||
return {
|
||||
success: false,
|
||||
error: 'Domain not found',
|
||||
};
|
||||
}
|
||||
|
||||
if (errorMessage.includes('ECONNREFUSED')) {
|
||||
return {
|
||||
success: false,
|
||||
error: 'Connection refused',
|
||||
};
|
||||
}
|
||||
|
||||
if (errorMessage.includes('timeout')) {
|
||||
return {
|
||||
success: false,
|
||||
error: 'Request timeout',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error: errorMessage,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate if a URL looks like a valid transcript URL
|
||||
* @param url The URL to validate
|
||||
* @returns boolean indicating if URL appears valid
|
||||
*/
|
||||
export function isValidTranscriptUrl(url: string): boolean {
|
||||
if (!url || typeof url !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const parsedUrl = new URL(url);
|
||||
return parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract session ID from transcript content if possible
|
||||
* This is a helper function that can be enhanced based on transcript format
|
||||
* @param content The transcript content
|
||||
* @returns Extracted session ID or null
|
||||
*/
|
||||
export function extractSessionIdFromTranscript(content: string): string | null {
|
||||
if (!content) return null;
|
||||
|
||||
// Look for common session ID patterns
|
||||
const patterns = [
|
||||
/session[_-]?id[:\s]*([a-zA-Z0-9-]+)/i,
|
||||
/id[:\s]*([a-zA-Z0-9-]{8,})/i,
|
||||
/^([a-zA-Z0-9-]{8,})/m, // First line might be session ID
|
||||
];
|
||||
|
||||
for (const pattern of patterns) {
|
||||
const match = content.match(pattern);
|
||||
if (match && match[1]) {
|
||||
return match[1].trim();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user