@@ -59,23 +59,26 @@ function extractLoomVideoId(url: string): string | null {
5959async function fetchLoomEndpoint (
6060 videoId : string ,
6161 endpoint : string ,
62+ includeBody = true ,
6263) : Promise < string | null > {
6364 try {
65+ const options : RequestInit = { method : "POST" } ;
66+ if ( includeBody ) {
67+ options . headers = {
68+ "Content-Type" : "application/json" ,
69+ Accept : "application/json" ,
70+ } ;
71+ options . body = JSON . stringify ( {
72+ anonID : randomUUID ( ) ,
73+ deviceID : null ,
74+ force_original : false ,
75+ password : null ,
76+ } ) ;
77+ }
78+
6479 const response = await fetch (
6580 `https://www.loom.com/api/campaigns/sessions/${ videoId } /${ endpoint } ` ,
66- {
67- method : "POST" ,
68- headers : {
69- "Content-Type" : "application/json" ,
70- Accept : "application/json" ,
71- } ,
72- body : JSON . stringify ( {
73- anonID : randomUUID ( ) ,
74- deviceID : null ,
75- force_original : false ,
76- password : null ,
77- } ) ,
78- } ,
81+ options ,
7982 ) ;
8083
8184 if ( ! response . ok || response . status === 204 ) {
@@ -131,16 +134,25 @@ function isStreamingUrl(url: string): boolean {
131134}
132135
133136async function getLoomDownloadUrl ( loomVideoId : string ) : Promise < string | null > {
134- const endpoints = [ "transcoded-url" , "raw-url" ] as const ;
137+ const requestVariants : Array < { endpoint : string ; includeBody : boolean } > = [
138+ { endpoint : "transcoded-url" , includeBody : true } ,
139+ { endpoint : "raw-url" , includeBody : true } ,
140+ { endpoint : "transcoded-url" , includeBody : false } ,
141+ { endpoint : "raw-url" , includeBody : false } ,
142+ ] ;
135143
136- for ( const endpoint of endpoints ) {
137- const url = await fetchLoomEndpoint ( loomVideoId , endpoint ) ;
144+ let fallbackStreamingUrl : string | null = null ;
145+
146+ for ( const { endpoint, includeBody } of requestVariants ) {
147+ const url = await fetchLoomEndpoint ( loomVideoId , endpoint , includeBody ) ;
138148 if ( ! url ) continue ;
139149
140150 if ( ! isStreamingUrl ( url ) ) return url ;
151+
152+ if ( ! fallbackStreamingUrl ) fallbackStreamingUrl = url ;
141153 }
142154
143- return null ;
155+ return fallbackStreamingUrl ;
144156}
145157
146158async function fetchLoomOEmbed (
@@ -181,10 +193,9 @@ export async function downloadLoomVideo(
181193 }
182194
183195 try {
184- const transcodedUrl = await fetchLoomEndpoint ( videoId , "transcoded-url" ) ;
185- const rawUrl = await fetchLoomEndpoint ( videoId , "raw-url" ) ;
196+ const downloadUrl = await getLoomDownloadUrl ( videoId ) ;
186197
187- if ( ! transcodedUrl && ! rawUrl ) {
198+ if ( ! downloadUrl ) {
188199 return {
189200 success : false ,
190201 error :
0 commit comments