Skip to content

Instantly share code, notes, and snippets.

@jamiephan
Last active December 20, 2024 07:04
Show Gist options
  • Save jamiephan/0c04986c7f2e62d5c87c4e8c8ce115fc to your computer and use it in GitHub Desktop.
Save jamiephan/0c04986c7f2e62d5c87c4e8c8ce115fc to your computer and use it in GitHub Desktop.
A script to automatically add ALL items to your account in quixel

Script to add all items from quixel

As quixel is being removed, all items are free to aquire. This script is to automate the process to add items to your account (As of writing, a total of 18874 items)

Note: This script only tested in the latest version of Chrome.

How to use

  1. Copy the script from below (run.js)
  2. Login into https://quixel.com
  3. Go to https://quixel.com/megascans/collections
  4. Open devtools (F12) -> Go to "Console" tab
  5. Paste in the script and press Enter.
  6. A dialog should popup confirming the execution, click "OK"
  7. Sit back and wait

Common issues

  • Getting "Forbidden" error. (Even after refresh, the whole page just shows "Forbidden")
    • There is a chance that the API adding too fast and you hit the rate limit of the API. (My testing is around after 10 pages, so ~10k items).
    • Wait after ~10-20 minutes and continue. See Common Fixes -> Restart script to continue the execution after you can load https://quixel.com.
  • The script seems to be paused/hang
    • It could be too much logging going it. Try monitor the script, if it says "END PAGE X", note the page number down (in case need restart) and clear the console by clicking the "🚫" icon in devtools.
    • See Common Fixes -> Restart script for fixing.
  • Getting the error **UNABLE TO ADD ITEM**
    • There should have the error message shown in ( ). If it is user already owns specified asset at a higher or equal resolution, then its already in your account.
  • Getting the error cannot find authentication token. Please login again
    • Clear browser cookies and re-login quixel again. Try just simply add 1 item manully. If it success, then see Common Fixes -> Restart script for continue the execution.

Common Fixes

Restart Script

  1. Note which page it was running
  2. Copy the run.js script
  3. Update the startPage = 0 on the first line to startPage = 10 (assuming page 10 was hanged)

Change Log

  1. Initial Script launch
  2. Update to clear logs to reduce chance of hanging
  3. [CURRENT] Skip adding items that already was acquired. Reduced logs. Added more info after script completion to show purchased item count. Due to now skipping purchased items, you technically don't need to specify the startPage anymore.
((async (startPage = 0, autoClearConsole = true) => {
const getCookie = (name) => {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
const callCacheApi = async (params = {}) => {
const defaultParams = {
page: 0,
maxValuesPerFacet: 1000,
hitsPerPage: 1000,
attributesToRetrieve: ["id", "name"].join(",")
}
const response = await fetch("https://proxy-algolia-prod.quixel.com/algolia/cache", {
"headers": {
"x-api-key": "2Zg8!d2WAHIUW?pCO28cVjfOt9seOWPx@2j"
},
"body": JSON.stringify({
url: "https://6UJ1I5A072-2.algolianet.com/1/indexes/assets/query?x-algolia-application-id=6UJ1I5A072&x-algolia-api-key=e93907f4f65fb1d9f813957bdc344892",
params: new URLSearchParams({ ...defaultParams, ...params }).toString()
}),
"method": "POST",
})
return await response.json()
}
const callAcl = async ({ id, name }) => {
const response = await fetch("https://quixel.com/v1/acl", {
"headers": {
"authorization": "Bearer " + authToken,
"content-type": "application/json;charset=UTF-8",
},
"body": JSON.stringify({ assetID: id }),
"method": "POST",
});
const json = await response.json()
if (json?.isError) {
console.error(` --> **UNABLE TO ADD ITEM** Item ${id} | ${name} (${json?.msg})`)
} else {
console.log(` --> ADDED ITEM Item ${id} | ${name}`)
}
}
const callAcquired = async () => {
const response = await fetch("https://quixel.com/v1/assets/acquired", {
"headers": {
"authorization": "Bearer " + authToken,
"content-type": "application/json;charset=UTF-8",
},
"method": "GET",
});
return await response.json()
}
// 1. Check token exist, quixel API needs it
console.log("-> Checking Auth API Token...")
let authToken = ""
try {
const authCookie = getCookie("auth") ?? "{}"
authToken = JSON.parse(decodeURIComponent(authCookie))?.token
if (!authToken) {
return console.error("-> Error: cannot find authentication token. Please login again.")
}
} catch (_) {
return console.error("-> Error: cannot find authentication token. Please login again.")
}
// 2. Get all currently acquired items
console.log("-> Get Acquired Items...")
const acquiredItems = (await callAcquired()).map(a => a.assetID)
// 3. Get total count of items
console.log("-> Getting Total Number of Pages....")
const { nbPages: totalPages, hitsPerPage: itemsPerPage, nbHits: totalItems } = await callCacheApi()
console.log("-> ==============================================")
console.log(`-> Total # of items: ${totalItems}`)
console.log(`-> ${totalPages} total pages with ${itemsPerPage} per page`)
console.log(`-> Total Items to add: ${(totalItems - acquiredItems.length)}.`)
console.log("-> ==============================================")
if (!confirm(`Click OK to start adding ${(totalItems - acquiredItems.length)} items in your account.`)) return
// Loop
for (let pageIdx = startPage || 0; pageIdx < totalPages; pageIdx++) {
console.log(`-> ======================= PAGE ${pageIdx + 1}/${totalPages} START =======================`)
console.log("-> Getting Items from page " + (pageIdx + 1) + " ...")
const { hits: items } = await callCacheApi({ page: pageIdx })
console.log("-> Adding non-acquired items...")
// Filter out owned items
const unownedItems = items.filter(i => !acquiredItems.includes(i.id))
const aclPromises = unownedItems.map(callAcl)
await Promise.all(aclPromises)
console.log(`-> ======================= PAGE ${pageIdx + 1}/${totalPages} COMPLETED =======================`)
if (autoClearConsole) console.clear() // Fix the issue that too much log hangs the console. Set autoClearConsole = false to keep the logs
}
console.log("-> Getting new acquired info...")
// Get acquired items again
const newItemsAcquired = (await callAcquired()).length
const newTotalCount = (await callCacheApi()).nbHits
console.log(`-> Completed. Your account now have a total of ${newItemsAcquired} out of ${newTotalCount} items.`)
alert(`-> Your account now have a total of ${newItemsAcquired} out of ${newTotalCount} items.\n\nIf you find some items missing, try refresh the page and run the script again.`)
})())
@lavinia103
Copy link

another workaround for no VPN is to connect to your mobile hotspot rather than your home WiFi, aka changing your IP, gets rid of 403 Forbidden

@repsejnworb
Copy link

Abosolute chad!

I somehow ended up with +2 assets 😆 so some fun bug.

Can't state enough how grateful I am for you sharing this

@infernocloud
Copy link

infernocloud commented Oct 3, 2024

In my fork I've added a 10 second pause between processing each page and this successfully avoided Quixel's API rate limiting and the script ran in minutes without any extra manual handling. Feel free to pull in the changes!

https://gist.github.com/infernocloud/5f20a8e85070ccfeda3da14cf7f9b6c6

Thank you for writing this script, this is awesome!

@Saveun
Copy link

Saveun commented Oct 4, 2024

Thank you

@wocmultimedia
Copy link

Thanks a lot guys!!! I just used it and worked fine. I had only a simple problem. After pasting the script the first time, it stops after 2 pages without any notice. I waited 5 minutes then seeing that nothing happened I pasted again the script changing the start page to 2 and it started again the Adding Items. I repeated it 4 times changing the starting page and I succeeded to download the whole collection.
I checked and the items are really added to my account, so it works fine.
Thanks again.

@IraShevchenko007
Copy link

Thank you!

@wocmultimedia
Copy link

Thank you!

You are welcome, Ira!!!

@maffii95
Copy link

maffii95 commented Oct 4, 2024

Captura de pantalla 2024-10-04 092845
help!

@infernocloud
Copy link

Captura de pantalla 2024-10-04 092845 help!

You need to paste the text of the JavaScript code and run that. It looks like you just typed "run.js" in the console and that won't do anything.

@Rob-bb
Copy link

Rob-bb commented Oct 5, 2024

Any script to actually download them all automatically?

@romeishka
Copy link

Hi guys! thanks for the script, but how do I get rid of this message? I can't even copy it image

Just read that message till the end. On last sentence you will see answer what to do... 🤦‍♂️🤦‍♂️🤦‍♂️

@tahysnozgl
Copy link

Thank you :)

@cliveagate
Copy link

Brilliant and thank you :)
I ran it through twice as the first time it stopped at Page 10 (while it was loading) then after about 10-15mins I ran it again and all was fine :)

@ParaLizzard
Copy link

Assets will not automatically transfer to Fab.com.
image

@romeishka
Copy link

romeishka commented Oct 6, 2024

Hello, can you help me? What should I do? Screenshot 2024-10-06 143034

Another one... 🤦‍♂️🤦‍♂️🤦‍♂️ Did you even read what is in that message and especially in last sentence? 😕

@romeishka
Copy link

Assets will not automatically transfer to Fab.com. image

Official Quixel emal:

Screenshot 2024-10-06 124945

But if you want to be sure 100% better to download it all... 😁

@pouchbunny
Copy link

In my fork I've added a 10 second pause between processing each page and this successfully avoided Quixel's API rate limiting and the script ran in minutes without any extra manual handling. Feel free to pull in the changes!

https://gist.github.com/infernocloud/5f20a8e85070ccfeda3da14cf7f9b6c6

Thank you for writing this script, this is awesome!

image

A couple other small errors while processing but seems I got an extra free one. I started at like around 300 purchased. Was quick and easy. Thank you!

@FrancescoLauretta
Copy link

FrancescoLauretta commented Oct 6, 2024

looks it run succesfully but
while I can see a long list of items in (https://quixel.com/account),
I cannot see that 18k+ under (https://quixel.com/megascans/purchased)
do I need to be worried?

Screenshot 2024-10-06 215618
Screenshot 2024-10-06 220139

@maffii95
Copy link

maffii95 commented Oct 6, 2024

Parece que funciona correctamente, pero aunque puedo ver una larga lista de elementos en ( https://quixel.com/account ), no puedo ver esos 18k+ en ( https://quixel.com/megascans/purchased ). ¿Debo preocuparme?

Captura de pantalla 2024-10-06 215618 Captura de pantalla 2024-10-06 220139

si vas a unreal, y buscas en bridge podes ver que los assets estan con una tilde sin color, significa que estan guardados pero tenes que descargarlos en unreal (eso es lo que entendi)

@maffii95
Copy link

maffii95 commented Oct 6, 2024

Captura de pantalla 2024-10-04 092845¡ayuda!

Debes pegar el texto del código JavaScript y ejecutarlo. Parece que simplemente escribiste "run.js" en la consola y eso no hará nada.

gracias, logre que funcione.

@FrancescoLauretta
Copy link

Captura de pantalla 2024-10-04 092845¡ayuda!

Debes pegar el texto del código JavaScript y ejecutarlo. Parece que simplemente escribiste "run.js" en la consola y eso no hará nada.

gracias, logre que funcione.

Screenshot 2024-10-06 224930
Screenshot 2024-10-06 225402

I run it, 1st time took about 1h to be completed

@Zarpute
Copy link

Zarpute commented Oct 7, 2024

Insane, ty so mutch !

@FM-GD
Copy link

FM-GD commented Oct 7, 2024

Absolute legend, thanks!

@SmailikHappy
Copy link

Worked on firefox, however sometime it got stuck, so webpage refresh + script rerun helped.
Thank you <3

@limdingwen
Copy link

limdingwen commented Oct 8, 2024

Note that your ability to legally use the downloaded assets depends on what button you click here: https://quixel.com/pricing

Screenshot 2024-10-08 223719

They're all free, but watch out, they come with different rights and restrictions! The 30-day free trial plan is for evaluation purposes only. The UE plan is for Unreal Engine only. The personal plan is for personal use only, or can be used commercially if you make less than a certain revenue threshold. The indie plan can be used commercially, but requires you to be below a certain revenue threshold (this is the one you want).

Edit:

If you acquired the assets for free via the Unreal Engine subscription plan or under a free trial of a Quixel plan, they will not automatically transfer over to Fab. From Fab’s launch until the end of 2024, you may download Megascans—both those you may have acquired in the past and those that may be new to you—for free from Fab. Any Megascans that you add to your library on Fab during this promotion period, you will be entitled to use under the terms of the Fab Standard License even after the promotion period ends. Please be aware that simply downloading a free Megascan on Fab in 2024 will not grant you this entitlement - you need to use the “Add to library” option.

Does this mean that if you use the Personal or Indie plan (i.e. not the UE or free trial plan), it'll transfer over? So clicking the wrong button means it won't transfer over...

To be specific: https://www.unrealengine.com/en-US/eula/content

  1. License Plans
    a. Personal Plan
    Megascans Content that you acquire from Epic while your account is enrolled in a personal plan for which you qualify may be used as any other Licensed Content. Such Megascans Content, however, may not be distributed in source format to anyone else.

You qualify for a personal plan only if you are an individual and either (i) use Megascans Content only for your personal purposes and not for any business or other commercial purpose or (ii) generate less than $100,000 USD in annual gross revenue. For purposes of this calculation, revenue includes any advances received or other funds raised. However, individuals who start on a personal plan will not be ineligible for the plan unless and until they generate more than $100,000 USD in annual gross revenue for two consecutive years.

b. Indie Plan
Megascans Content that you acquire from Epic while your account is enrolled in an indie plan for which you qualify may be used and shared as any other Licensed Content.

You qualify for an indie plan only if you, together with any controlling entity and other entities under common control with you, (i) generate less than $2,000,000 USD per year in annual gross revenue and (ii) are not affiliated with or funded by a publisher owned or controlled studio. For purposes of this calculation revenue includes any advances received or other funds raised.

c. Unreal Engine Plan (UE-Only Content)
Megascans Content that you acquire from Epic while your account is enrolled in an Unreal Engine plan may only be used and shared as UE-Only Content.

You qualify for an Unreal Engine plan if you have entered into an Unreal Engine End User License Agreement with Epic that is still active and valid.

d. Educational Plan
Megascans Content that an educational institution approved by Epic acquires under an account enrolled in an educational plan (“Educational Assets”) may only be used for non-commercial, educational purposes. You may deploy Educational Assets on computers in labs, classrooms, and other physical educational environments under your control and may allow Educational Assets to be accessed on a file server by students and instructors through a local area network or through a secure virtual private network (VPN) connection employing industry standard encryption and protection mechanisms. You may not and may not allow others to sell, license, or otherwise commercially use or exploit any Projects or services containing Educational Assets.

e. Free Assets
Megascans Content that you acquire from Epic under an account not enrolled in a Megascans plan may only be used for your internal evaluation purposes. Such Megascans Content may not be distributed to any party, either in source format or as part of a Project.

@audiBookning
Copy link

Thanks @limdingwen. That was a pretty useful and necessary info. Many people, me included, may be confused about the exact terms of the licence.

@omersonic
Copy link

What if I get a 504 gateway timeout error?

@Arwa99-lab
Copy link

I can't paste the code it keeps telling me this (Warning: Don’t paste code into the DevTools Console that you don’t understand or haven’t reviewed yourself. This could allow attackers to steal your identity or take control of your computer. Please type ‘allow pasting’ below and hit Enter to allow pasting.) even if I wrote 'allow pasting' like it said and pressed enter it still would not paste

@Tweedilderp
Copy link

As arwa99-lab said it has me worried it is malicious even if inadvertently.

Plugged the code into chatgpt and got this
Untitleda

is algolia trustworthy? i realise they supply the search api, but saw they have a public bug bounty for penetration testing so has me worried if our tokens are going through their network traffic.

Can jamiephan comment on this?

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