题记- 就特么一个功能,自动根据区域填亚马逊邮编地址,马德,这一定是重复搞轮子。

做过亚马逊的都知道,因为session 有时间期限,或者某些站点没有经常使用,所以经常浏览页面的时候因为邮编不对,需要切换,不切换一定会有个问题,就是页面展现不全。另外,加亚马逊在中国的服务器实在是慢,手动切换确实没必要。

我也不知道市场上有无类似的插件。搜了几个关键词,没有找到,毕竟这东西没啥商业价值。秉着void 刚下载想测试下的想法,我就是试试自己开发一个插件吧,也许以后一发不可收拾,然后获得vc, 然后梦醒了。

这个插件的名字叫做Auto ZIP Code Setter ,别问我,Gemini 取得。

从来没有开发过chrome 插件,注册的时候才发现成为开发者还需要交5美金,靠,一想5美金心痛,虽然我一定会薅回来。所以就着vibe coding 的思路开始开发。

思路也很简单它无非就是js操作。后台测试了conselo,基本上确认可以实现,就开始使用void(感谢马斯克慷慨的grok api计划,150美金根本用不完),然后自己稍微review了代码。大概30分钟就出来了demo,靠,这比flask 容易多了。

然后我智慧的做了了个icon,发布反而很麻烦,设计权限,远程代码检测,图片等。这个以后再说,不过我的权限要求非常低,审核4个小时就过了。

以下是js 代码

console.log("Auto ZIP Code content script loaded. v1.3");

const targetConfigs = {
  "www.amazon.com": {
    openModalSelector: "#nav-global-location-popover-link, #glow-ingress-block",
    zipInputInModalSelector: "#GLUXZipUpdateInput",
    submitModalSelector: "#GLUXZipUpdate .a-button-input, input[aria-labelledby='GLUXZipUpdate-announce']",
    zipCode: "95001",
    currentLocationDisplaySelector: "#glow-ingress-line2",
    expectedLocationText: "95001"
  },
  "www.amazon.co.uk": {
    openModalSelector: "#nav-global-location-popover-link, #glow-ingress-block",
    zipInputInModalSelector: "#GLUXZipUpdateInput",
    submitModalSelector: "#GLUXZipUpdate .a-button-input, input[aria-labelledby='GLUXZipUpdate-announce']",
    zipCode: "LS14 5ED",
    currentLocationDisplaySelector: "#glow-ingress-line2",
    expectedLocationText: "LS14 5ED"
  },
  "www.amazon.fr": {
    openModalSelector: "#nav-global-location-popover-link, #glow-ingress-block",
    zipInputInModalSelector: "#GLUXZipUpdateInput",
    submitModalSelector: "#GLUXZipUpdate .a-button-input, input[aria-labelledby='GLUXZipUpdate-announce']",
    zipCode: "75000",
    currentLocationDisplaySelector: "#glow-ingress-line2",
    expectedLocationText: "75000"
  },
  "www.amazon.es": {
    openModalSelector: "#nav-global-location-popover-link, #glow-ingress-block",
    zipInputInModalSelector: "#GLUXZipUpdateInput",
    submitModalSelector: "#GLUXZipUpdate .a-button-input, input[aria-labelledby='GLUXZipUpdate-announce']",
    zipCode: "23001",
    currentLocationDisplaySelector: "#glow-ingress-line2",
    expectedLocationText: "23001"
  },
  "www.amazon.de": {
    openModalSelector: "#nav-global-location-popover-link, #glow-ingress-block",
    zipInputInModalSelector: "#GLUXZipUpdateInput",
    submitModalSelector: "#GLUXZipUpdate .a-button-input, input[aria-labelledby='GLUXZipUpdate-announce']",
    zipCode: "10178",
    currentLocationDisplaySelector: "#glow-ingress-line2",
    expectedLocationText: "10178"
  },
  "www.amazon.it": {
    openModalSelector: "#nav-global-location-popover-link, #glow-ingress-block",
    zipInputInModalSelector: "#GLUXZipUpdateInput",
    submitModalSelector: "#GLUXZipUpdate .a-button-input, input[aria-labelledby='GLUXZipUpdate-announce']",
    zipCode: "07100",
    currentLocationDisplaySelector: "#glow-ingress-line2",
    expectedLocationText: "07100"
  }
};

const currentHostname = window.location.hostname;
const config = targetConfigs[currentHostname];

function log(message) {
  console.log(`[AutoZIP Extension]: ${message}`);
}

async function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function waitForElement(selectorString, timeout = 10000) {
  const startTime = Date.now();
  log(`Waiting for element(s): ${selectorString} on ${currentHostname}`);
  const selectors = selectorString.split(',').map(s => s.trim()).filter(s => s);

  while (Date.now() - startTime < timeout) {
    for (const selector of selectors) {
      const element = document.querySelector(selector);
      if (element && (element.offsetParent !== null || window.getComputedStyle(element).display !== 'none')) {
        log(`Element found: ${selector}`);
        return element;
      }
    }
    await delay(500);
  }
  log(`Element(s) NOT FOUND after ${timeout}ms: ${selectorString}`);
  return null;
}

async function executeLocationChange() {
  if (!config) {
    log("No configuration found for this site: " + currentHostname);
    return;
  }

  log(`Starting location change process for: ${currentHostname} with ZIP/Postcode: ${config.zipCode}`);

  if (config.currentLocationDisplaySelector && config.expectedLocationText) {
    const locationDisplayElement = await waitForElement(config.currentLocationDisplaySelector, 3000);
    if (locationDisplayElement && locationDisplayElement.textContent.includes(config.expectedLocationText)) {
      log(`Location already set to include "${config.expectedLocationText}". No action needed.`);
      return;
    }
    log("Current location does not match expected, or display element not found initially. Proceeding with update.");
  }

  const openModalButton = await waitForElement(config.openModalSelector);
  if (!openModalButton) {
    log("Could not find the button/link to open the location modal. Aborting.");
    return;
  }
  log("Clicking to open location modal...");
  openModalButton.click();

  const zipInput = await waitForElement(config.zipInputInModalSelector, 15000);
  if (!zipInput) {
    log("ZIP/Postcode input field inside modal not found. Aborting.");
    return;
  }
  log("ZIP/Postcode input field in modal found.");

  zipInput.value = "";
  await delay(100);
  zipInput.value = config.zipCode;
  log(`Set ZIP/Postcode input value to: ${config.zipCode}`);

  zipInput.dispatchEvent(new Event('input', { bubbles: true, cancelable: true }));
  zipInput.dispatchEvent(new Event('change', { bubbles: true, cancelable: true }));
  zipInput.dispatchEvent(new Event('blur', { bubbles: true, cancelable: true }));

  await delay(500);

  const submitButton = await waitForElement(config.submitModalSelector);
  if (!submitButton) {
    log("Submit button inside modal not found. Aborting.");
    return;
  }
  log("Clicking submit button in modal...");
  submitButton.click();

  log("Location change process has been attempted.");

  if (config.currentLocationDisplaySelector && config.expectedLocationText) {
    await delay(3000);
    log("Attempting to verify location update...");
    const updatedLocationDisplay = await waitForElement(config.currentLocationDisplaySelector, 7000);
    if (updatedLocationDisplay && updatedLocationDisplay.textContent.includes(config.expectedLocationText)) {
      log(`SUCCESS: Location display appears to be updated to include "${config.expectedLocationText}".`);
    } else if (updatedLocationDisplay) {
      log(`VERIFICATION: Location display text is now "${updatedLocationDisplay.textContent.trim()}". Manual check might be needed.`);
    } else {
      log("VERIFICATION: Could not find location display element after update attempt.");
    }
  }
}

if (document.readyState === "complete" || document.readyState === "interactive" || document.readyState === "loaded") {
  log("Document ready, scheduling location change in 3 seconds...");
  setTimeout(executeLocationChange, 3000);
} else {
  log("Document not ready, adding DOMContentLoaded listener with 3s delay.");
  window.addEventListener('DOMContentLoaded', () => {
    log("DOMContentLoaded event fired, scheduling location change in 3 seconds...");
    setTimeout(executeLocationChange, 3000);
  });
}

d6b5531bda4a4dcd8970b98171bb8ef0_auto.png