Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save SuppliedOrange/09c4b1723a9679d3b3568d5328553a37 to your computer and use it in GitHub Desktop.

Select an option

Save SuppliedOrange/09c4b1723a9679d3b3568d5328553a37 to your computer and use it in GitHub Desktop.

Here is a prebuilt lib for it:

/**
 * Fallback manual authorization token.
 * Populate this only if the Vencord Webpack cache is unavailable.
 * @type {string}
 */
const MANUAL_TOKEN = "";


/**
 * Base endpoint URL for the Discord Gorilla activity.
 * @type {string}
 */
const BASE_URL = "https://discord.com/api/v9/gorilla/activity";


/**
 * Safely extracts the Discord authorization token.
 * Prioritizes Vencord's internal Webpack cache, falling back to MANUAL_TOKEN if necessary.
 *
 * @returns {string|null} The authorization token, or null if unavailable.
 */
const getToken = () => {

    const vencordToken = window.Vencord?.Webpack?.findByProps("getToken")?.getToken();

    return MANUAL_TOKEN || vencordToken;

};


/**
 * Generates a dynamic telemetry payload for the x-super-properties header.
 * Utilizes the current browser environment to construct an authentic client profile.
 *
 * @returns {string} Base64 encoded JSON string representing client properties.
 */
const getDynamicSuperProperties = () => {

    const buildNumber = window.GLOBAL_ENV?.BUILD_NUMBER ?? 522736;

    const userAgent = navigator.userAgent || "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36";

    const browserVersionMatch = userAgent.match(/Chrome\/(\d+\.\d+\.\d+\.\d+)/);

    const browserVersion = browserVersionMatch?.[1] || "144.0.0.0";

    const properties = {
        os: "Windows",
        browser: "Chrome",
        device: "",
        system_locale: "en-US",
        has_client_mods: false,
        browser_user_agent: userAgent,
        browser_version: browserVersion,
        os_version: "10",
        referrer: "",
        referring_domain: "",
        referrer_current: "", 
        referring_domain_current: "",
        release_channel: "stable",
        client_build_number: buildNumber,
        client_event_source: null,
        client_launch_id: null,
        launch_signature: null,
        client_heartbeat_session_id: null,
        client_app_state: "focused"
    };

    return btoa(JSON.stringify(properties));

};


/**
 * Executes an authenticated POST request to the specified activity endpoint.
 *
 * @param {string} endpoint - The specific API endpoint route.
 * @returns {Promise<Object>} The JSON response payload.
 * @throws {Error} Throws an error if no authorization token is located.
 */
const sendGorillaAction = async (endpoint) => {

    const token = getToken();

    if (!token) {

        throw new Error("[Auth] No Discord token found. Please populate MANUAL_TOKEN.");

    }

    const response = await fetch(`${BASE_URL}/${endpoint}`, {
        method: "POST",
        headers: {
            "accept": "*/*",
            "accept-language": "en-US",
            "authorization": token,
            "priority": "u=1, i",
            "sec-ch-ua": "\"Not(A:Brand\";v=\"8\", \"Chromium\";v=\"144\"",
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": "\"Windows\"",
            "sec-fetch-dest": "empty",
            "sec-fetch-mode": "cors",
            "sec-fetch-site": "same-origin",
            "x-super-properties": getDynamicSuperProperties()
        },
        referrer: "https://discord.com/channels/@me",
        body: null,
        mode: "cors",
        credentials: "include"
    });

    if (!response.ok) {

        console.error(`[Error] Request to ${endpoint} failed with status ${response.status}`);

    }

    return response.json();

};


/**
 * Initiates and completes a crafting lifecycle.
 * Exposed to the global window object for console execution.
 *
 * @async
 * @global
 * @returns {Promise<Object|undefined>} The state changes resulting from the action.
 */
window.craft = async () => {

    console.log("πŸ”¨ [Craft] Starting...");

    await sendGorillaAction("crafting/start");
    
    console.log("πŸ”¨ [Craft] Completing...");

    const result = await sendGorillaAction("crafting/complete");

    return result?.changes;

};


/**
 * Initiates and completes a combat lifecycle.
 * Exposed to the global window object for console execution.
 *
 * @async
 * @global
 * @returns {Promise<Object|undefined>} The state changes resulting from the action.
 */
window.battle = async () => {

    console.log("βš”οΈ [Battle] Starting...");

    await sendGorillaAction("combat/start");

    console.log("βš”οΈ [Battle] Completing...");

    const result = await sendGorillaAction("combat/complete");

    return result?.changes;

};


/**
 * Completes a pending adventure gathering lifecycle and initiates a new one.
 * Exposed to the global window object for console execution.
 *
 * @async
 * @global
 * @returns {Promise<Object|undefined>} The state changes resulting from the action.
 */
window.adventure = async () => {

    console.log("πŸŽ’ [Adventure] Starting adventure...");

    await sendGorillaAction("gathering/start");
    
    console.log("πŸŽ’ [Adventure] Completing adventure...");

    const result = await sendGorillaAction("gathering/complete");

    return result?.changes;

};


console.log("%cβœ… Gorilla Automation Loaded!", "color: #43b581; font-weight: bold; font-size: 14px;");

console.log("Commands: await battle(), await craft(), await adventure()");

Yeah, it's AI-Generated because I don't like typing. But I'll walk you through it.

The JWT token is basically this:

{

"os": "Windows",

"browser": "Chrome",

"device": "",

"system_locale": "en-US",

"has_client_mods": false,

"browser_user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",

"browser_version": "144.0.0.0",

"os_version": "10",

"referrer": "",

"referring_domain": "",

"referrer_current": "wherever u are rn",

"referring_domain_current": "discord.com",

"release_channel": "stable",

"client_build_number": 522736,

"client_event_source": null,

"client_launch_id": "XXXX",

"launch_signature": "XXXX",

"client_heartbeat_session_id": "XXXX",

"client_app_state": "focused"

}

I basically stripped everything that wasn't necessary (the server didn't care about). I reconstruct the JWT with minimal stuff needed for auth as seen above.

I removed a lot of other headers that didn't seem to be required.

Will this raise flags? Probably. Will this work? Yes.

Will you need to modify this to not look like a bot? Absolutely. You may include more headers and more JWT fields if you have Vencord and can directly access the required properties.

Made this in an hour but happy to help / learn.

@SuppliedOrange
Copy link
Copy Markdown
Author

make sure discord doesnt listen to mouseclick / mousemove events when u do this asw bcs apparently that gets flagged too?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment