I just wanted to share a little script I use to batch redeem Reward Points for Gift Cards — because doing it manually takes simply too much time and clicking.
The script requires the Tampermonkey browser extension. Currently, it only works on the English version of Makerworld, but it should be very easy to adapt it for other localizations.
Privacy:
The script does not access any personal data and runs entirely on your own machine. It simply automates a series of clicks to simulate user interaction.
Installaltion:
- Open Tampermonkey, create a New Userscript, and paste in the source code.
- Save the Script
- Done
How to Use:
(Assumes Tampermonkey and the script are already installed.)
- Navigate to https://makerworld.com/en/points — or reload the page if you arrived from elsewhere on Makerworld.
2.(The script only activates on that specific page.)* - You’ll see a big green button in the top right corner labeled “Start Gift Card Redemption.”
- Click the button to automatically redeem your points until they’re all converted.
See ths script in action (100% speed):

Limitations:
- English only: Currently, the script only works with the English localization of Makerworld.
- Fixed timing between actions: The click sequence relies on fixed wait times between actions, which has worked well for me.
You can adjust the timing by editing theawait wait(*XYZ*);lines in the code (values are in milliseconds). - Potential loading errors: Occasionally, the script might throw an error if a page element doesn’t load in time.
Simply restart the process to redeem your remaining points. - No manual stop: The script will continue running until all points are redeemed (as intended).
If you want to stop manually, reload the page. - Gift card codes are not saved automatically: Since most of my gift cards require manual review anyway, the script does not automatically save the codes. You’ll need to access your redeemed cards manually later.
- The script is designed to throw an error when no gift cards are available, but since this situation rarely occurs, I haven’t had the opportunity to test it yet.
- The script comes as is. Feel free to modify it or use it in your own project.
Source Code:
// ==UserScript==
// @name MakerWorld Gift Card Redeemer Bot
// @namespace http://tampermonkey.net/
// @version 1.2
// @description Adds a visible button to manually start the Gift Card redemption process on MakerWorld Points page with extensive debugging output in console logs if enough points are available to redeem a Gift Card automatically
// @author AU3D
// @match https://makerworld.com/en/points
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Helper function to wait a certain number of milliseconds
async function wait(milliseconds) {
return new Promise(resolve => setTimeout(resolve, milliseconds));
}
// Main function to find and click the Gift Card
async function clickGiftCard() {
console.log('[GiftCardBot] Searching for Gift Card elements...');
const cards = document.querySelectorAll('.MuiBox-root.mw-css-1np7691');
console.log(`[GiftCardBot] Found ${cards.length} cards on the page.`);
let giftCardElement = null;
// Search for the first card that contains "Gift Card" in its title
for (const card of cards) {
const titleElement = card.querySelector('.mw-css-3pz2ix');
if (titleElement) {
console.log(`[GiftCardBot] Checking card title: "${titleElement.textContent.trim()}"`);
if (titleElement.textContent.includes('Gift Card')) {
giftCardElement = card;
console.log('[GiftCardBot] Found a Gift Card!');
break;
}
} else {
console.warn('[GiftCardBot] No title element found in a card.');
}
}
if (!giftCardElement) {
console.error('[GiftCardBot] No Gift Card found on the page.');
return;
}
// Find the button inside the parent element
const buttonContainer = giftCardElement.querySelector('.MuiBox-root.mw-css-0');
const button = buttonContainer?.querySelector('button');
if (!button) {
console.error('[GiftCardBot] No redeem button found inside Gift Card element.');
return;
}
console.log('[GiftCardBot] Clicking the Gift Card redeem button...');
button.click();
await wait(300);
// Handle the opened dialog
await handleDialog();
}
// Function to handle the dialog after clicking
async function handleDialog() {
console.log('[GiftCardBot] Waiting for dialog to open...');
const dialog = document.querySelector('.MuiDialog-container.MuiDialog-scrollPaper.mw-css-fh1hs4');
if (!dialog) {
console.error('[GiftCardBot] Dialog not found.');
return;
}
console.log('[GiftCardBot] Dialog found.');
// Find the element showing the balance
const balanceElement = dialog.querySelector('.mw-css-12ezz6q');
if (!balanceElement) {
console.error('[GiftCardBot] Balance element not found inside the dialog.');
return;
}
const originalBalanceText = balanceElement.textContent.trim();
console.log(`[GiftCardBot] Raw balance text: "${originalBalanceText}"`);
// Clean the balance string: keep only digits, comma, and dot
const cleanedBalanceString = originalBalanceText.replace(/[^0-9,\.]/g, '');
console.log(`[GiftCardBot] Cleaned balance string: "${cleanedBalanceString}"`);
const balance = parseFloat(cleanedBalanceString.replace(/,/g, ''));
console.log(`[GiftCardBot] Parsed numeric balance: ${balance}`);
if (isNaN(balance)) {
console.error('[GiftCardBot] Balance parsing failed (NaN detected)!');
return;
}
// Find the required points element
const requiredPointsElement = dialog.querySelector('.mw-css-z0vrvy');
if (!requiredPointsElement) {
console.error('[GiftCardBot] Required points element (price) not found inside the dialog.');
return;
}
const originalRequiredText = requiredPointsElement.textContent.trim();
console.log(`[GiftCardBot] Raw required points text: "${originalRequiredText}"`);
// Clean the required points string
const cleanedRequiredString = originalRequiredText.replace(/[^0-9,\.]/g, '');
console.log(`[GiftCardBot] Cleaned required points string: "${cleanedRequiredString}"`);
const requiredPoints = parseFloat(cleanedRequiredString.replace(/,/g, ''));
console.log(`[GiftCardBot] Parsed required points: ${requiredPoints}`);
if (isNaN(requiredPoints)) {
console.error('[GiftCardBot] Required points parsing failed (NaN detected)!');
return;
}
// Compare balance to required points
if (balance < requiredPoints) {
console.warn(`[GiftCardBot] Not enough points to redeem (Balance: ${balance}, Required: ${requiredPoints})`);
alert('Not enough points available');
return;
}
console.log(`[GiftCardBot] Sufficient points detected (Balance: ${balance}, Required: ${requiredPoints}), proceeding to redeem.`);
// Proceed to find and click the redeem button
const redeemButtonContainer = dialog.querySelector('.mw-css-10egq61');
const redeemButton = redeemButtonContainer?.querySelector('button');
if (!redeemButton) {
console.error('[GiftCardBot] Redeem button not found inside the dialog.');
return;
}
console.log('[GiftCardBot] Clicking the redeem button...');
redeemButton.click();
await wait(300);
const confirmationDialog = document.querySelector('.mw-css-1maiz2c');
if (!confirmationDialog) {
console.error('[GiftCardBot] Confirmation dialog not found after redeem button click.');
return;
}
console.log('[GiftCardBot] Confirmation dialog opened.');
const confirmButton = confirmationDialog.querySelector('button.mw-css-7i8ckg');
if (!confirmButton) {
console.error('[GiftCardBot] Confirm purchase button not found inside confirmation dialog.');
return;
}
console.log('[GiftCardBot] Clicking confirm button...');
confirmButton.click();
await wait(1000);
const closeButton = document.querySelector('.mw-css-12i94o');
if (!closeButton) {
console.error('[GiftCardBot] Close button not found after confirmation.');
return;
}
console.log('[GiftCardBot] Clicking close button to finalize the process...');
closeButton.click();
await wait(1000);
console.log('[GiftCardBot] Completed one Gift Card redemption cycle, checking again...');
await clickGiftCard();
}
// Function to create and add the manual start button to the page
function addStartButton() {
const startButton = document.createElement('button');
startButton.innerText = 'Start Gift Card Redemption';
startButton.style.position = 'fixed';
startButton.style.top = '100px';
startButton.style.right = '20px';
startButton.style.zIndex = '9999';
startButton.style.padding = '15px 25px';
startButton.style.backgroundColor = '#28a745';
startButton.style.color = 'white';
startButton.style.border = 'none';
startButton.style.borderRadius = '8px';
startButton.style.fontSize = '18px';
startButton.style.cursor = 'pointer';
startButton.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.2)';
startButton.style.fontWeight = 'bold';
startButton.addEventListener('click', () => {
console.log('[GiftCardBot] Manual start button clicked, beginning redemption process...');
clickGiftCard();
startButton.remove(); // Optional: remove the button after first click
});
document.body.appendChild(startButton);
}
// Add the button once the page is fully loaded
window.addEventListener('load', () => {
setTimeout(addStartButton, 500);
});
})();