Instagram Media Pro - Open & Save Content

Extract, open and save Instagram media with one click. Easily save photos and videos to Discord.

// ==UserScript==
// @name             Instagram Media Pro - Open & Save Content
// @namespace        https://greasyfork.org/en/users/1431907-theeeunknown
// @version          4.5
// @description      Extract, open and save Instagram media with one click. Easily save photos and videos to Discord.
// @author           TR0LL
// @match            https://www.instagram.com/*
// @match            *://*.cdninstagram.com/*
// @match            *://*.fbcdn.net/*
// @icon             https://www.google.com/s2/favicons?sz=64&domain=instagram.com
// @grant            GM_setValue
// @grant            GM_getValue
// @grant            GM_registerMenuCommand
// @license          MIT
// ==/UserScript==

(function() {
    'use strict';
    const CONFIG = {
        discordWebhookUrl: '',
        disableNewUrlFetchMethod: false,
        prefetchAndAttachLink: false,
        hoverToFetchAndAttachLink: true,
        replaceJpegWithJpg: false,
        postFilenameTemplate: '%id%-%datetime%-%medianame%',
        storyFilenameTemplate: '%id%-%datetime%-%medianame%',
        datetimeTemplate: '%y%%m%%d%_%H%%M%%S%',
        checkInterval: 500 // ms
    };


    if (typeof GM_registerMenuCommand !== 'undefined') {
        GM_registerMenuCommand('Set Discord Webhook URL', promptForWebhookUrl);
    }
    
    function promptForWebhookUrl() {
        const currentUrl = localStorage.getItem('instagramMediaExtractorWebhook') || CONFIG.discordWebhookUrl;
        const newUrl = prompt('Enter your Discord webhook URL:', currentUrl);
        
        if (newUrl !== null && newUrl.trim() !== '') {
            localStorage.setItem('instagramMediaExtractorWebhook', newUrl.trim());
            CONFIG.discordWebhookUrl = newUrl.trim();
            alert('Discord webhook URL saved! It will be used for future notifications.');
        }
    }
    
    document.addEventListener('keydown', function(event) {
        if (event.altKey && (event.code === 'KeyW' || event.key === 'w')) {
            promptForWebhookUrl();
        }
    });

    const SVG = {
        openNewTab: `<svg id="Capa_1" style="fill:%color;" viewBox="0 0 482.239 482.239" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="m465.016 0h-344.456c-9.52 0-17.223 7.703-17.223 17.223v86.114h-86.114c-9.52 0-17.223 7.703-17.223 17.223v344.456c0 9.52 7.703 17.223 17.223 17.223h344.456c9.52 0 17.223-7.703 17.223-17.223v-86.114h86.114c9.52 0 17.223-7.703 17.223-17.223v-344.456c0-9.52-7.703-17.223-17.223-17.223zm-120.56 447.793h-310.01v-310.01h310.011v310.01zm103.337-103.337h-68.891v-223.896c0-9.52-7.703-17.223-17.223-17.223h-223.896v-68.891h310.011v310.01z"/></svg>`
    };


    const CACHE = {
        infoCache: {},
        mediaIdCache: {},
        previousUrl: ""
    };


    const SELECTORS = {
        savePostButton: 'article *:not(li)>*>*>*>div:not([class])>div[role="button"]:not([style]):not([tabindex="-1"])',
        profileCircle: 'header section svg circle',
        playSvgPath: 'path[d="M5.888 22.5a3.46 3.46 0 0 1-1.721-.46l-.003-.002a3.451 3.451 0 0 1-1.72-2.982V4.943a3.445 3.445 0 0 1 5.163-2.987l12.226 7.059a3.444 3.444 0 0 1-.001 5.967l-12.22 7.056a3.462 3.462 0 0 1-1.724.462Z"]',
        pauseSvgPath: 'path[d="M15 1c-3.3 0-6 1.3-6 3v40c0 1.7 2.7 3 6 3s6-1.3 6-3V4c0-1.7-2.7-3-6-3zm18 0c-3.3 0-6 1.3-6 3v40c0 1.7 2.7 3 6 3s6-1.3 6-3V4c0-1.7-2.7-3-6-3z"]',
        saveButtonPolygon: 'polygon[points="20 21 12 13.44 4 21 4 3 20 3 20 21"]',
        saveButtonPath: 'path[d="M20 22a.999.999 0 0 1-.687-.273L12 14.815l-7.313 6.912A1 1 0 0 1 3 21V3a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1Z"]'
    };


    const PATTERNS = {
        postId: /^\/p\/([^/]+)\//,
        postUrl: /instagram\.com\/p\/[\w-]+\//,
        storyUrl: /instagram\.com\/stories\/([\w.-]+)\/(\d+)/
    };


    const currentHostname = window.location.hostname;

    if (currentHostname === 'www.instagram.com') {



        document.addEventListener('keydown', handleKeyDown);
        const checkExistTimer = setInterval(checkAndAddButtons, CONFIG.checkInterval);


        function handleKeyDown(event) {
            if (window.location.href === 'https://www.instagram.com/') return;
            
            const mockEventTemplate = { 
                stopPropagation: function() {}, 
                preventDefault: function() {} 
            };


            if (event.altKey && (event.code === 'KeyI' || event.key === 'i')) {
                const buttons = document.getElementsByClassName('open-btn');
                if (buttons.length > 0) {
                    const mockEvent = { ...mockEventTemplate, currentTarget: buttons[buttons.length - 1] };
                    if (CONFIG.hoverToFetchAndAttachLink) handleMouseEnter(mockEvent);
                    handleButtonClick(mockEvent);
                }
            }
            

            if (event.altKey && (event.code === 'KeyL' || event.key === 'l')) {
                let btns = document.querySelectorAll('button[aria-label="Next"], button._afxw[aria-label="Next"]');
                if (btns.length > 0) btns[btns.length-1].click();
                else {
                    btns = document.getElementsByClassName('_9zm2');
                    if (btns.length > 0) btns[0].click();
                }
            }
            
            if (event.altKey && (event.code === 'KeyJ' || event.key === 'j')) {
                let btns = document.querySelectorAll('button[aria-label="Previous"], button._afxw[aria-label="Previous"]');
                if (btns.length > 0) btns[btns.length-1].click();
                else {
                    btns = document.getElementsByClassName('_9zm0');
                    if (btns.length > 0) btns[0].click();
                }
            }
        }


        function isPostPage() {
            return Boolean(window.location.pathname.match(PATTERNS.postId));
        }


        function queryHas(root, selector, has) {
            const nodes = root.querySelectorAll(selector);
            for (let i = 0; i < nodes.length; ++i) {
                if (nodes[i].querySelector(has)) return nodes[i];
            }
            return null;
        }


        function checkAndAddButtons() {
            const curUrl = window.location.href;
            

            const rgb = getComputedStyle(document.body).backgroundColor.match(/[.?\d]+/g);
            const iconColor = (rgb?.length >= 3 && (parseInt(rgb[0])*0.299+parseInt(rgb[1])*0.587+parseInt(rgb[2])*0.114)<=150) ? 'white' : 'black';


            if (CACHE.previousUrl !== curUrl) {
                document.querySelectorAll('.custom-btn').forEach(btn => btn.remove());
                CACHE.previousUrl = curUrl;
            }


            document.querySelectorAll('article:not(:has(.custom-btn))').forEach(article => {
                const buttonAnchor = (Array.from(article.querySelectorAll(SELECTORS.savePostButton))).pop();
                if (buttonAnchor) addCustomButton(buttonAnchor, iconColor, appendToPost);
            });
            

            if (isPostPage() && !document.querySelector('main > article .custom-btn')) {
                const saveBtn = 
                    queryHas(document, 'div[role="button"] > div[role="button"]:not([style])', SELECTORS.saveButtonPolygon) || 
                    queryHas(document, 'div[role="button"] > div[role="button"]:not([style])', SELECTORS.saveButtonPath);
                    
                if (saveBtn?.parentNode?.querySelector('svg')) {
                    addCustomButton(saveBtn.parentNode.querySelector('svg'), iconColor, appendToIndependentPost);
                }
            }
            

            if (!document.querySelector('main > div > header .custom-btn') && !curUrl.includes("stor")) {
                const profileAnchor = document.querySelector(SELECTORS.profileCircle);
                if (profileAnchor) addCustomButton(profileAnchor, iconColor, appendToHeader);
            }
            

            if (!document.querySelector('section header .custom-btn') && curUrl.includes('/stories/')) {
                const playPauseSvg = 
                    queryHas(document, 'svg', SELECTORS.playSvgPath) || 
                    queryHas(document, 'svg', SELECTORS.pauseSvgPath);
                    
                if (playPauseSvg) addCustomButton(playPauseSvg.parentNode, 'white', appendToStory);
            }
        }


        function appendToPost(node, btn) { node.append(btn); }
        function appendToIndependentPost(node, btn) { node.parentNode.parentNode.append(btn); }
        function appendToHeader(node, btn) { node.parentNode.parentNode.parentNode.appendChild(btn); }
        function appendToStory(node, btn) {
            if (node.parentNode.parentNode.parentNode.querySelector('.custom-btn')) {
                return;
            }
            node.parentNode.parentNode.parentNode.append(btn);
        }


        function addCustomButton(node, iconColor, appendNodeFunc) {
            const openBtn = createCustomButton(SVG.openNewTab, iconColor, 'open-btn', 'Open in new tab', '16px');
            appendNodeFunc(node, openBtn);
            
            if (CONFIG.prefetchAndAttachLink || CONFIG.hoverToFetchAndAttachLink) {
                handleMouseEnter({ currentTarget: openBtn });
            }
        }


        function createCustomButton(svg, iconColor, className, title, marginLeft) {
            const newBtn = document.createElement('a');
            newBtn.innerHTML = svg.replace('%color', iconColor);
            newBtn.className = 'custom-btn ' + className;
            newBtn.title = title;
            newBtn.style.cssText = `cursor: pointer; margin-left: ${marginLeft}; margin-top: 8px; display: inline-flex; align-items: center; z-index: 999;`;
            newBtn.onclick = handleButtonClick;
            
            if (CONFIG.hoverToFetchAndAttachLink) {
                newBtn.onmouseenter = handleMouseEnter;
            }
            

            newBtn.target = '_blank';
            newBtn.rel = 'noopener noreferrer';
            
            return newBtn;
        }


        function handleButtonClick(e) {
            const target = e.currentTarget;
            e.stopPropagation();
            

            if (!target.getAttribute('href') || target.getAttribute('href').startsWith('blob:')) {
                e.preventDefault();
                
                if (window.location.pathname.includes('/stories/')) {
                    handleStoryClick(target);
                } else if (document.querySelector('main > div > header')?.contains(target)) {
                    handleProfileClick(target);
                } else {
                    handlePostClick(target);
                }
            }
        }


        async function handleMouseEnter(e) {
            const target = e.currentTarget;
            
            if (!CONFIG.hoverToFetchAndAttachLink) return;
            if (target.getAttribute('href') && !target.getAttribute('href').startsWith('blob:')) return;
            
            let url = null;
            try {
                if (window.location.pathname.includes('/stories/')) {
                    const node = findStorySection(target);
                    if (node) url = await getStoryUrl(target, node);
                } else if (document.querySelector('main > div > header')?.contains(target)) {
                    url = getProfileUrl(target);
                } else {
                    const node = findArticleNode(target);
                    if (node) {
                        const result = await getPostUrl(target, node);
                        url = result?.url;
                    }
                }
            } catch(err) {
            }
            
            if (url && !url.startsWith('blob:')) {
                target.setAttribute('href', url);
            } else {
                target.removeAttribute('href');
            }
        }


        async function handleProfileClick(target) {
            const url = getProfileUrl(target);
            if (url && !url.startsWith('blob:')) {
                target.href = url;
            }
        }


        async function handlePostClick(target) {
            const articleNode = findArticleNode(target);
            if (!articleNode) return;
            
            try {
                const result = await getPostUrl(target, articleNode);
                const url = result?.url;
                if (url && !url.startsWith('blob:')) {
                    target.href = url;
                }
            } catch(e) {
            }
        }


        async function handleStoryClick(target) {
            const sectionNode = findStorySection(target);
            if (!sectionNode) return;
            
            try {
                const url = await getStoryUrl(target, sectionNode);
                if (url && !url.startsWith('blob:')) {
                    target.href = url;
                }
            } catch(e) {
            }
        }


        
        function getProfileUrl(target) {
            const imgElem = document.querySelector('header img');
            return imgElem ? imgElem.src : null;
        }
        
        function findArticleNode(target) {
            let node = target;
            while (node && node.tagName !== 'ARTICLE' && node.tagName !== 'MAIN') {
                node = node.parentNode;
            }
            return node;
        }
        
        async function getPostUrl(target, articleNode) {
            let list = articleNode.querySelectorAll('li[style][class]');
            let url = null;
            let mediaIndex = 0;
            
            if (list.length === 0) {
                if (!CONFIG.disableNewUrlFetchMethod) url = await getUrlFromInfoApi(articleNode);
                if (url === null) {
                    let v = articleNode.querySelector('video');
                    if (v) {
                        url = v.getAttribute('src');
                        if (v.hasAttribute('videoURL')) url = v.getAttribute('videoURL');
                        else if (url === null || url.includes('blob')) url = await fetchVideoURL(articleNode, v);
                    } else if (articleNode.querySelector('article div[role] div > img')) {
                        url = articleNode.querySelector('article div[role] div > img').getAttribute('src');
                    }
                }
            } else {
                const pV = location.pathname.startsWith('/p/');
                let dE = [...articleNode.querySelectorAll(`div._acnb`)];
                mediaIndex = dE.reduce((r, e, i) => (e.classList.length === 2 ? i : r), 0);
                
                if (!CONFIG.disableNewUrlFetchMethod) url = await getUrlFromInfoApi(articleNode, mediaIndex);
                
                if (url === null) {
                    const lE = [...articleNode.querySelectorAll(`:scope > div > div:nth-child(${pV ? 1 : 2}) > div > div:nth-child(1) ul li[style*="translateX"]`)];
                    const lW = Math.max(...lE.map(e => e.clientWidth));
                    const pM = lE.reduce((r, e) => {
                        const tM = e.style.transform.match(/-?(\d+)/);
                        if (tM?.[1]) {
                            const p = Math.round(Number(tM[1]) / lW);
                            return { ...r, [p]: e };
                        }
                        return r;
                    }, {});
                    
                    const n = pM[mediaIndex];
                    if (n) {
                        if (n.querySelector('video')) {
                            let v = n.querySelector('video');
                            url = v.getAttribute('src');
                            if (v.hasAttribute('videoURL')) url = v.getAttribute('videoURL');
                            else if (url === null || url.includes('blob')) url = await fetchVideoURL(articleNode, v);
                        } else if (n.querySelector('img')) {
                            url = n.querySelector('img').getAttribute('src');
                        }
                    } else {
                        const fI = articleNode.querySelector('ul li img[src]');
                        const fV = articleNode.querySelector('ul li video');
                        if (fV) {
                            url = fV.getAttribute('src');
                            if (fV.hasAttribute('videoURL')) url = fV.getAttribute('videoURL');
                            else if (url === null || url.includes('blob')) url = await fetchVideoURL(articleNode, fV);
                        } else if (fI) {
                            url = fI.getAttribute('src');
                        }
                    }
                }
            }
            
            return { url, mediaIndex };
        }
        
        function findHighlightsIndex() {
            let c = document.querySelector('div[style^="transform"]')?.parentElement;
            if (!c) return 0;
            let p = c.parentElement;
            if (!p) return 0;
            let d = p.children;
            return Array.from(d).indexOf(c);
        }
        
        async function getUrlFromInfoApi(articleNode, mediaIdx = 0) {
            try {
                const aP = /"X-IG-App-ID":"([\d]+)"/;
                const mP = /instagram:\/\/media\?id=(\d+)|["' ]media_id["' ]:["' ](\d+)["' ]/;
                
                function fA() {
                    let b = document.querySelectorAll("body > script");
                    for (let i = 0; i < b.length; ++i) {
                        let m = b[i].text.match(aP);
                        if (m) return m[1];
                    }
                    return null;
                }
                
                async function fM() {
                    function m1() {
                        let h = window.location.href;
                        let m = h.match(/www.instagram.com\/stories\/[^\/]+\/(\d+)/);
                        if (!h.includes('highlights') && m) return m[1];
                    }
                    
                    async function m3() {
                        let p = await findPostId(articleNode);
                        if (!p) return null;
                        if (!(p in CACHE.mediaIdCache)) {
                            let u = `https://www.instagram.com/p/${p}/`;
                            let r = await fetch(u);
                            let t = await r.text();
                            let i = t ? t.match(mP) : null;
                            let m = null;
                            if (i) m = i.slice(1).find(id => id !== undefined) || null;
                            if (!m) return null;
                            CACHE.mediaIdCache[p] = m;
                        }
                        return CACHE.mediaIdCache[p];
                    }
                    
                    function m2() {
                        let s = document.querySelectorAll('script[type="application/json"]');
                        for (let i = 0; i < s.length; i++) {
                            let m = s[i].text.match(/"pk":"(\d+)","id":"[\d_]+"/);
                            if (m) {
                                if (!window.location.href.includes('highlights')) return m[1];
                                let ms = Array.from(s[i].text.matchAll(/"pk":"(\d+)","id":"[\d_]+"/g), m => m[1]);
                                const x = findHighlightsIndex();
                                if (ms.length > x) return ms[x];
                            }
                        }
                    }
                    
                    return m1() || await m3() || m2();
                }
                
                function gU(i) {
                    if ("video_versions" in i && i.video_versions.length > 0) return i.video_versions[0].url;
                    else if ("image_versions2" in i && i.image_versions2.candidates.length > 0) return i.image_versions2.candidates[0].url;
                    return null;
                }
                
                let a = fA();
                if (!a) return null;
                
                let h = {
                    method: 'GET',
                    headers: {
                        Accept: '*/*',
                        'X-IG-App-ID': a
                    },
                    credentials: 'include',
                    mode: 'cors'
                };
                
                let m = await fM();
                if (!m) return null;
                
                if (!(m in CACHE.infoCache)) {
                    let u = `https://i.instagram.com/api/v1/media/${m}/info/`;
                    let r = await fetch(u, h);
                    if (r.status !== 200) return null;
                    CACHE.infoCache[m] = await r.json();
                }
                
                let j = CACHE.infoCache[m];
                if (!j?.items?.length) return null;
                
                if ('carousel_media' in j.items[0]) {
                    if (j.items[0].carousel_media.length > mediaIdx) return gU(j.items[0].carousel_media[mediaIdx]);
                    else return null;
                } else return gU(j.items[0]);
            } catch (e) {
                return null;
            }
        }
        
        function findPostName(articleNode) {
            let i = articleNode.querySelector('article section + * a[href^="/"][href$="/"]');
            if (i) return i;
            
            let a = articleNode.querySelector('canvas ~ * img');
            if (a) {
                a = a.getAttribute('alt');
                let l = articleNode.querySelectorAll('a');
                for (let i = 0; i < l.length; i++) {
                    const p = l[i].getAttribute('href').replace(/\//g, '');
                    if (a?.includes(p)) return l[i];
                }
            } else {
                const e = document.querySelector('h2[dir]');
                if (e) return e.innerText;
            }
            
            return null;
        }
        
        function findPostId(articleNode) {
            let a = articleNode.querySelectorAll('a');
            for (let i = 0; i < a.length; ++i) {
                let l = a[i].getAttribute('href');
                if (l) {
                    let m = l.match(PATTERNS.postId);
                    if (m) return m[1];
                }
            }
            return null;
        }
        
        async function fetchVideoURL(articleNode, videoElem) {
            let p = videoElem.getAttribute('poster');
            if (!p) return null;
            
            let t = articleNode.querySelectorAll('time');
            if (t.length === 0) return null;
            
            let l = t[t.length - 1].parentNode?.parentNode;
            if (!l?.href) return null;
            
            let pU = l.href;
            const pP = /\/([^\/?]*)\?/;
            let pM = p.match(pP);
            if (!pM?.[1]) return null;
            
            let fN = pM[1];
            try {
                let r = await fetch(pU);
                if (!r.ok) throw new Error();
                
                let c = await r.text();
                const pt = new RegExp(`"${fN}".*?video_versions.*?url":"([^"]*)"`, 's');
                let m = c.match(pt);
                
                if (!m?.[1]) {
                    const aP = new RegExp(`"video_url":"([^"]+)"`);
                    m = c.match(aP);
                    if (!m?.[1]) return null;
                }
                
                let vU = JSON.parse(`"${m[1].replace(/\\u([\da-f]{4})/gi, (m, g) => String.fromCharCode(parseInt(g, 16)))}"`.replace(/\\"/g, '"'));
                videoElem.setAttribute('videoURL', vU);
                return vU;
            } catch (e) {
                return null;
            }
        }
        
        function findStorySection(target) {
            let node = target;
            while (node && node.tagName !== 'SECTION') {
                node = node.parentNode;
            }
            return node;
        }
        
        async function getStoryUrl(target, sectionNode) {
            let url = null;
            
            if (!CONFIG.disableNewUrlFetchMethod) {
                url = await getUrlFromInfoApi(sectionNode);
            }
            
            if (!url) {
                if (sectionNode.querySelector('video > source')) {
                    url = sectionNode.querySelector('video > source').getAttribute('src');
                } else if (sectionNode.querySelector('img[decoding="sync"]')) {
                    let img = sectionNode.querySelector('img[decoding="sync"]');
                    let srcset = img.getAttribute('srcset');
                    
                    if (srcset) {
                        url = srcset.split(/ \d+w/g)[0].trim();
                    }
                    
                    if (!url || url.length === 0) {
                        url = img.getAttribute('src');
                    }
                } else if (sectionNode.querySelector('video')) {
                    url = sectionNode.querySelector('video').getAttribute('src');
                }
            }
            
            return url;
        }

    } else if (currentHostname.endsWith('.cdninstagram.com') || currentHostname.endsWith('.fbcdn.net')) {
        

        async function sendToDiscord(imageUrl, actionType, filename = 'media') {
            if (!imageUrl || typeof imageUrl !== 'string' || imageUrl.startsWith('blob:')) return;
            
            if (!CONFIG.discordWebhookUrl || CONFIG.discordWebhookUrl.trim() === '') {
                promptForWebhookUrl();
                if (!CONFIG.discordWebhookUrl || CONFIG.discordWebhookUrl.trim() === '') {
                    return;
                }
            }

            try {
                const isVideo = /\.mp4|\/video\/|_n\.mp4/i.test(imageUrl);
                const isImage = /\.jpg|\.jpeg|\.png|\.webp|_n\.jpg|_n\.png/i.test(imageUrl);
                
                let simpleFilename = filename.split('?')[0].replace(/[^a-zA-Z0-9_\-.]/g, '_');
                const fileExt = isVideo ? '.mp4' : '.jpg';
                if (!simpleFilename.endsWith(fileExt)) {
                    simpleFilename += fileExt;
                }
                
                const response = await fetch(imageUrl);
                if (!response.ok) throw new Error('Failed to fetch media');
                
                const blob = await response.blob();
                
                const formData = new FormData();
                
                formData.append('content', `Instagram Media ${actionType}`);
                
                const fileType = isVideo ? 'video/mp4' : 'image/jpeg';
                const file = new File([blob], simpleFilename, { type: fileType });
                formData.append('file', file);
                
                const webhookResponse = await fetch(CONFIG.discordWebhookUrl, {
                    method: 'POST',
                    body: formData
                });
                
                if (!webhookResponse.ok) throw new Error('Discord webhook failed');
                
            } catch (error) {
                try {
                    const payload = {
                        content: `Instagram Media ${actionType}`,
                        embeds: [{
                            url: imageUrl,
                            image: {
                                url: imageUrl
                            }
                        }]
                    };
                    
                    await fetch(CONFIG.discordWebhookUrl, {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify(payload)
                    });
                } catch (e) {
                    try {
                        const textPayload = {
                            content: `Instagram Media ${actionType}: ${imageUrl}`
                        };
                        
                        await fetch(CONFIG.discordWebhookUrl, {
                            method: 'POST',
                            headers: { 'Content-Type': 'application/json' },
                            body: JSON.stringify(textPayload)
                        });
                    } catch (finalError) {
                    }
                }
            }
        }

        const currentMediaUrl = window.location.href;


        if (currentMediaUrl && /\.(jpg|jpeg|png|webp|mp4|mov)(\?|$)/i.test(currentMediaUrl)) {
            let filename = 'media_file';
            try {
                const urlPath = new URL(currentMediaUrl).pathname;
                const lastPart = urlPath.substring(urlPath.lastIndexOf('/') + 1);
                const potentialFilename = lastPart.split('?')[0];
                
                if (potentialFilename && potentialFilename.length > 1) {
                    filename = potentialFilename;
                }
            } catch (e) {
            }


            sendToDiscord(currentMediaUrl, 'Opened Direct', filename);
        }
    }

})();