Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name NovaAlpha - Temu price adjustment checker
- // @namespace http://tampermonkey.net/
- // @version 0.1
- // @description Scans your Temu orders page for orders eligible for a price adjustment refund and pops up direct links to claim them
- // @author NovaAlpha
- // @match *://*.temu.com/*bgt_orders.html*
- // @grant GM_openInTab
- // ==/UserScript==
- /*
- * Run this below to remove the saved popup position/size data
- *
- localStorage.removeItem('popupTop_' + window.location.origin);
- localStorage.removeItem('popupLeft_' + window.location.origin);
- */
- (function()
- {
- 'use strict';
- var reminderDiv = document.createElement('div');
- var contentHTML = '';
- var DisplayPopup = false;
- var ordersProcessed = false;
- // Popup UI (same drag/resize/toggle popup used by the reminder script,
- // kept here so this script can stand alone)
- function createPopup()
- {
- if (DisplayPopup === true)
- {
- var reminderDiv = document.createElement('div');
- reminderDiv.id = 'yourPopupId';
- var dragHandle = document.createElement('div');
- dragHandle.style.height = '20px';
- dragHandle.style.backgroundColor = '#ccc';
- dragHandle.style.cursor = 'move';
- dragHandle.innerHTML = 'Drag here';
- dragHandle.style.textAlign = 'center';
- reminderDiv.appendChild(dragHandle);
- var toggleButton = document.createElement('button');
- toggleButton.innerHTML = 'Show / Hide';
- toggleButton.style.marginTop = '10px';
- toggleButton.style.marginBottom = '10px';
- reminderDiv.appendChild(toggleButton);
- var contentDiv = document.createElement('div');
- contentDiv.innerHTML = contentHTML;
- reminderDiv.appendChild(contentDiv);
- reminderDiv.style.position = 'fixed';
- reminderDiv.style.padding = '10px 10px 0px 10px';
- reminderDiv.style.backgroundColor = 'cyan';
- reminderDiv.style.border = '2px solid black';
- reminderDiv.style.zIndex = '10000';
- reminderDiv.style.width = localStorage.getItem('popupWidth_' + window.location.origin) || '290px';
- reminderDiv.style.maxWidth = '700px';
- reminderDiv.style.maxHeight = '850px';
- reminderDiv.style.wordWrap = 'break-word';
- reminderDiv.style.resize = 'both';
- reminderDiv.style.overflow = 'auto';
- reminderDiv.style.top = localStorage.getItem('popupTop_' + window.location.origin) || '50%';
- reminderDiv.style.left = localStorage.getItem('popupLeft_' + window.location.origin) || '10px';
- // Check if isContentVisible is not found in local storage, default to true
- var isContentVisible = localStorage.getItem('isContentVisible_' + window.location.origin);
- if (isContentVisible === null) {
- isContentVisible = true;
- } else {
- isContentVisible = isContentVisible === 'true';
- }
- if (!isContentVisible) {
- contentDiv.style.display = 'none';
- reminderDiv.style.height = 'auto';
- localStorage.setItem('popupOriginalWidth_' + window.location.origin, reminderDiv.style.width);
- dragHandle.style.width = toggleButton.offsetWidth + 'px';
- reminderDiv.style.width = 'auto';
- dragHandle.style.width = '';
- }
- toggleButton.addEventListener('click', function () {
- isContentVisible = !isContentVisible;
- localStorage.setItem('isContentVisible_' + window.location.origin, isContentVisible);
- if (!isContentVisible) {
- contentDiv.style.display = 'none';
- reminderDiv.style.height = 'auto';
- localStorage.setItem('popupOriginalWidth_' + window.location.origin, reminderDiv.style.width);
- dragHandle.style.width = toggleButton.offsetWidth + 'px';
- reminderDiv.style.width = 'auto';
- } else {
- contentDiv.style.display = 'block';
- reminderDiv.style.height = 'auto';
- reminderDiv.style.width = localStorage.getItem('popupOriginalWidth_' + window.location.origin);
- dragHandle.style.width = '';
- }
- });
- dragHandle.addEventListener('mousedown', function (e) {
- var offsetX = e.clientX - parseInt(window.getComputedStyle(reminderDiv).left);
- var offsetY = e.clientY - parseInt(window.getComputedStyle(reminderDiv).top);
- function mouseMoveHandler(e) {
- reminderDiv.style.top = (e.clientY - offsetY) + 'px';
- reminderDiv.style.left = (e.clientX - offsetX) + 'px';
- }
- function mouseUpHandler() {
- window.removeEventListener('mousemove', mouseMoveHandler);
- window.removeEventListener('mouseup', mouseUpHandler);
- localStorage.setItem('popupTop_' + window.location.origin, reminderDiv.style.top);
- localStorage.setItem('popupLeft_' + window.location.origin, reminderDiv.style.left);
- }
- window.addEventListener('mousemove', mouseMoveHandler);
- window.addEventListener('mouseup', mouseUpHandler);
- });
- document.body.appendChild(reminderDiv);
- // Calculate maximum allowable top and left positions
- var maxTop = window.innerHeight - reminderDiv.offsetHeight;
- var maxLeft = window.innerWidth - reminderDiv.offsetWidth;
- var storedTop = localStorage.getItem('popupTop_' + window.location.origin);
- var storedLeft = localStorage.getItem('popupLeft_' + window.location.origin);
- storedTop = storedTop !== null ? parseInt(storedTop) : 10;
- storedLeft = storedLeft !== null ? parseInt(storedLeft) : 10;
- reminderDiv.style.top = Math.min(Math.max(storedTop, 30), maxTop) + 'px';
- reminderDiv.style.left = Math.min(Math.max(storedLeft, 0), maxLeft) + 'px';
- reminderDiv.addEventListener('mousemove', function () {
- if (isContentVisible) {
- localStorage.setItem('popupWidth_' + window.location.origin, reminderDiv.style.width);
- localStorage.setItem('popupHeight_' + window.location.origin, reminderDiv.style.height);
- }
- });
- }
- }
- function displayPopup() {
- if (DisplayPopup === true)
- {
- var existingPopup = document.getElementById('yourPopupId');
- if (!existingPopup) {
- createPopup();
- } else {
- reminderDiv.style.position = 'fixed';
- var popupWidth = localStorage.getItem('popupWidth_' + window.location.origin) || '290px';
- var popupHeight = localStorage.getItem('popupHeight_' + window.location.origin) || 'auto';
- var maxTop = window.innerHeight - existingPopup.offsetHeight;
- var maxLeft = window.innerWidth - existingPopup.offsetWidth;
- var storedTop = localStorage.getItem('popupTop_' + window.location.origin);
- var storedLeft = localStorage.getItem('popupLeft_' + window.location.origin);
- storedTop = storedTop !== null ? parseInt(storedTop) : 10;
- storedLeft = storedLeft !== null ? parseInt(storedLeft) : 10;
- existingPopup.style.top = Math.min(Math.max(storedTop, 0), maxTop) + 'px';
- existingPopup.style.left = Math.min(Math.max(storedLeft, 0), maxLeft) + 'px';
- existingPopup.style.width = popupWidth;
- existingPopup.style.height = popupHeight;
- }
- }
- }
- // Order scanning + price adjustment eligibility check
- function extractOrderData() {
- const orders = [];
- const seenIDs = new Set();
- // Find leaf nodes whose text is an Order Time label
- const leafNodes = Array.from(document.querySelectorAll('span, div, p'))
- .filter(el => el.children.length === 0);
- leafNodes.forEach(el => {
- const text = el.textContent.trim();
- if (!/^Order\s*[Tt]ime/i.test(text) || text.length > 20) return;
- // Walk up to find a card that also contains an Order ID
- let card = el.parentElement;
- for (let depth = 0; depth < 12; depth++) {
- if (!card || card === document.body) break;
- if (/Order\s*(ID|no\.?|number)/i.test(card.textContent)) {
- // Extract all leaf text nodes within this card
- const cardLeafs = Array.from(card.querySelectorAll('span, div, p'))
- .filter(n => n.children.length === 0);
- let orderTime = null;
- let orderID = null;
- for (let i = 0; i < cardLeafs.length; i++) {
- const t = cardLeafs[i].textContent.trim();
- if (/^Order\s*[Tt]ime/i.test(t) && t.length <= 20) {
- // Next leaf with a 4-digit year is the value
- for (let j = i + 1; j < Math.min(i + 5, cardLeafs.length); j++) {
- const candidate = cardLeafs[j].textContent.trim();
- if (/\d{4}/.test(candidate) && candidate.length <= 30) {
- orderTime = candidate;
- break;
- }
- }
- }
- if (/^Order\s*(ID|no\.?):?$/i.test(t)) {
- // Next non-empty leaf is the value
- for (let j = i + 1; j < Math.min(i + 5, cardLeafs.length); j++) {
- const candidate = cardLeafs[j].textContent.trim();
- if (candidate.length > 0 && !/^Order/i.test(candidate)) {
- orderID = candidate;
- break;
- }
- }
- }
- }
- if (orderTime && orderID && !seenIDs.has(orderID)) {
- seenIDs.add(orderID);
- orders.push({ orderTime, orderID });
- }
- break;
- }
- card = card.parentElement;
- }
- });
- return orders;
- }
- async function checkPriceAdjustment(orderID) {
- const url = `https://www.temu.com/w/bgas_refund_difference.html?parent_order_sn=${orderID}&biz_source=1-000-5&after_sales_type=1&belongTab=AO&_x_sessn_id=dwjzf47d2c`;
- try {
- const resp = await fetch(url, { credentials: 'include' });
- const html = await resp.text();
- // Try to extract embedded page data (Next.js / SSR patterns)
- const embeddedPatterns = [
- /<script[^>]+id="__NEXT_DATA__"[^>]*>([\s\S]*?)<\/script>/,
- /window\.__INITIAL_STATE__\s*=\s*({[\s\S]*?});\s*<\/script>/,
- /window\.__SSR_DATA__\s*=\s*({[\s\S]*?});\s*<\/script>/,
- ];
- for (const pat of embeddedPatterns) {
- const m = html.match(pat);
- if (!m) continue;
- try {
- const str = JSON.stringify(JSON.parse(m[1]));
- console.log('[Temu Price Adj] embedded JSON for', orderID, ':', str.substring(0, 800));
- // Positive signals
- if (/["']can_apply["']\s*:\s*true/.test(str)) { console.log('[Temu Price Adj] POSITIVE: can_apply=true'); return true; }
- if (/["'](price_reduce|reduce|refund)_amount["']\s*:\s*[1-9]/.test(str)) { console.log('[Temu Price Adj] POSITIVE: amount>0'); return true; }
- if (/["'](eligible|is_eligible|can_claim)["']\s*:\s*true/.test(str)) { console.log('[Temu Price Adj] POSITIVE: eligible=true'); return true; }
- // Negative signals
- if (/["']can_apply["']\s*:\s*false/.test(str)) { console.log('[Temu Price Adj] NEGATIVE: can_apply=false'); return false; }
- if (/["'](price_reduce|reduce|refund)_amount["']\s*:\s*0[,}"']/.test(str)) { console.log('[Temu Price Adj] NEGATIVE: amount=0'); return false; }
- if (/["'](eligible|is_eligible|can_claim)["']\s*:\s*false/.test(str)) { console.log('[Temu Price Adj] NEGATIVE: eligible=false'); return false; }
- console.log('[Temu Price Adj] embedded JSON found but no eligibility signal matched for', orderID);
- } catch(e) { console.log('[Temu Price Adj] JSON parse error', e); }
- }
- // Ineligible orders redirect to the order detail page (empty main div + bgt_order_detail i18n keys)
- if (html.includes('<div id="main"></div>')) {
- console.log('[Temu Price Adj] NEGATIVE: empty main div (redirected to order detail) for', orderID);
- return false;
- }
- console.log('[Temu Price Adj] POSITIVE: price adjustment page rendered for', orderID);
- return true;
- } catch(e) {
- console.log('[Temu Price Adj] fetch error for', orderID, e);
- return true;
- }
- }
- async function processOrders() {
- if (ordersProcessed) return;
- const orders = extractOrderData();
- if (orders.length === 0) {
- console.log('[Temu Script] No orders found yet');
- return;
- }
- ordersProcessed = true;
- observer.disconnect();
- console.log('[Temu Script] Found orders:', orders);
- for (const { orderTime, orderID } of orders) {
- console.log('[Temu Script] Order:', orderID, orderTime, '| within 30 days:', isWithin30Days(orderTime));
- if (!isWithin30Days(orderTime)) continue;
- const eligible = await checkPriceAdjustment(orderID);
- console.log('[Temu Script] Price adjustment eligible:', orderID, eligible);
- if (!eligible) continue;
- const link = `https://www.temu.com/w/bgas_refund_difference.html?parent_order_sn=${orderID}&biz_source=1-000-5&after_sales_type=1&belongTab=AO&_x_sessn_id=dwjzf47d2c`;
- contentHTML += `<br><br><a href="${link}">${link}</a>`;
- DisplayPopup = true;
- GM_openInTab(link, { active: false, insert: true });
- }
- if (DisplayPopup) {
- createPopup();
- displayPopup();
- }
- }
- function isWithin30Days(dateString) {
- var orderDate = new Date(dateString);
- var currentDate = new Date();
- // Calculate the difference in milliseconds
- var difference = currentDate - orderDate;
- // Calculate the difference in days
- var daysDifference = difference / (1000 * 60 * 60 * 24);
- return daysDifference <= 30;
- }
- // Watch for DOM changes (SPA dynamic load)
- var observer = new MutationObserver(function() { if (!ordersProcessed) processOrders(); });
- observer.observe(document.body, { childList: true, subtree: true });
- // Also retry on fixed intervals as fallback
- setTimeout(processOrders, 3000);
- setTimeout(processOrders, 6000);
- setTimeout(processOrders, 12000);
- setTimeout(function() { observer.disconnect(); }, 30000);
- })();
Advertisement
Add Comment
Please, Sign In to add comment