loomDetector.ts•2.8 kB
import type { Story, StoryComment, LinkedFile } from './shortcut-types'
export interface LoomVideo {
url: string
videoId: string
source: 'description' | 'comment' | 'linked_file' | 'manual'
sourceId?: number
timestamp?: string
}
const LOOM_URL_REGEX = /https?:\/\/(?:www\.)?loom\.com\/share\/([a-zA-Z0-9]+)(?:\?[^\s]*)?/g
function extractVideoId(url: string): string {
const match = url.match(/loom\.com\/share\/([a-zA-Z0-9]+)/)
return match ? match[1] : ''
}
function extractFromText(
text: string,
source: 'description' | 'comment',
sourceId?: number
): LoomVideo[] {
const videos: LoomVideo[] = []
const matches = [...text.matchAll(LOOM_URL_REGEX)]
for (const match of matches) {
const url = match[0]
const videoId = match[1]
videos.push({
url,
videoId,
source,
sourceId,
})
}
return videos
}
export function extractLoomVideos(story: Story): LoomVideo[] {
const videos: LoomVideo[] = []
// Check description
if (story.description) {
const descriptionVideos = extractFromText(story.description, 'description')
videos.push(...descriptionVideos)
}
// Check comments
if (story.comments && Array.isArray(story.comments)) {
story.comments.forEach((comment: StoryComment) => {
if (comment.text) {
const commentVideos = extractFromText(comment.text, 'comment', comment.id)
videos.push(...commentVideos)
}
})
}
// Check linked files
if (story.linked_files && Array.isArray(story.linked_files)) {
story.linked_files.forEach((file: LinkedFile) => {
if (file.url?.includes('loom.com')) {
videos.push({
url: file.url,
videoId: extractVideoId(file.url),
source: 'linked_file',
sourceId: file.id,
})
}
})
}
// Remove duplicates based on videoId
const uniqueVideos = videos.filter(
(video, index, self) => index === self.findIndex((v) => v.videoId === video.videoId)
)
return uniqueVideos
}
export function formatLoomVideoSummary(videos: LoomVideo[]): string {
if (videos.length === 0) {
return 'No Loom videos found in this story.'
}
const summary = [`Found ${videos.length} Loom video${videos.length > 1 ? 's' : ''}:`]
videos.forEach((video, index) => {
summary.push(`\n${index + 1}. Video ID: ${video.videoId}`)
summary.push(
` Source: ${video.source}${video.sourceId ? ` (ID: ${video.sourceId})` : ''}`
)
summary.push(` URL: ${video.url}`)
})
return summary.join('\n')
}