Greasy Fork is available in English.

Direct Download for products from Elgato marketplace (working in 2025)

Downloads Plugins and more from the Elgato store. Reprograms the "Open in Stream Deck" button on product pages

Du musst eine Erweiterung wie Tampermonkey, Greasemonkey oder Violentmonkey installieren, um dieses Skript zu installieren.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

Sie müssten eine Skript Manager Erweiterung installieren damit sie dieses Skript installieren können

(Ich habe schon ein Skript Manager, Lass mich es installieren!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Direct Download for products from Elgato marketplace (working in 2025)
// @namespace    com.elgato
// @description  Downloads Plugins and more from the Elgato store. Reprograms the "Open in Stream Deck" button on product pages
// @author       Thomas R.
// @version      1.0.0
// @license      MIT
// @match        http*://marketplace.elgato.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=marketplace.elgato.com
// @require      https://greasyfork.org/scripts/374849-library-onelementready-es6/code/Library%20%7C%20onElementReady%20ES6.js
// @grant        GM_xmlhttpRequest
// ==/UserScript==

const downloadFile = async (url, filename) => {
    GM_xmlhttpRequest({
        method: 'GET',
        url: url,
        responseType: 'blob',
        onload: function(response) {
            const blob = response.response;
            const a = document.createElement('a');
            a.href = URL.createObjectURL(blob);
            a.download = filename;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(a.href);
        },
        onerror: function(err) {
            console.error('Download error:', err);
        }
    });
};

const handleDownload = async (event) => {
    event.preventDefault();
    event.stopImmediatePropagation();
    event.currentTarget.querySelectorAll("*").forEach(element => element.style.pointerEvents = 'none');

    const sessionResponse = await fetch('https://marketplace.elgato.com/api/auth/session');
    const sessionJSON = await sessionResponse.json();
    const productId = __NEXT_DATA__.props.pageProps.content.variants[0].id;
    const productName = __NEXT_DATA__.props.pageProps.content.name
    const purchaseResponse = await fetch(`https://mp-gateway.elgato.com/items/${productId}/purchase-link`, {
        method: 'GET',
        headers: {
            'Authorization': `Bearer ${sessionJSON.accessToken}`,
            'Content-Type': 'application/json'
        }});
    const purchaseJSON = await purchaseResponse.json();
    console.log(purchaseJSON.direct_link, `${productName}.zip`);
    downloadFile(purchaseJSON.direct_link, `${productName}.zip`);
}

const init = async () => {
    onElementReady('button[aria-label="Open in Stream Deck"]', false, (element) => {
        console.log(window)
        if (location.pathname.startsWith("/product")) {
            element.addEventListener("click",handleDownload);
        }
    });

    // we can't use clientside navigation because of __NEXT_DATA__
    navigation.addEventListener("navigate", e => {
        if(e.navigationType === 'push' && e.downloadRequest === null ) {
            location = e.destination.url
        }
    });
}

init();