// ==UserScript== // @name Fill out USPS scheduled pickup // @description Fill saved formdata to instantly request USPS scheduled pickups // @namespace Violentmonkey Scripts // @match https://tools.usps.com/schedule-pickup-steps.htm* // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // @homepageURL https://git.tjkeller.xyz/userscripts/about // @downloadURL https://git.tjkeller.xyz/userscripts/plain/scripts/usps-fill-out-scheduled-pickup.user.js // @version 2.0 // @author tjkeller.xyz // ==/UserScript== /* Save/load data */ const initialFields = [ "addressLineOne", "addressLineTwo", "city", "emailAddress", "firstName", "isBusinessAddress", "lastName", "middleInitial", "phoneExt", "phoneNumber", "state", "zipCode", ] const otherFields = [ "first-radio-verification", "packageLocation", "second-radio-verification", "step-two-desc-item-textarea", ] function isCheckable(input) { return input.type == "checkbox" || input.type == "radio" } function saveFilledData(key, fieldNames) { const data = {} for (let fieldName of fieldNames) { const input = document.getElementById(fieldName) if (!input) { //alert(`Failed to save. Not all fields are filled. Make sure to continue after "Check Availability"`) alert(`Field "${fieldName}" not found`) return false } const label = input.previousElementSibling const required = label ? label.innerText.startsWith("*") : false // inputs not marked required data[fieldName] = isCheckable(input) ? input.checked : input.value if (required && !data[fieldName]) { input.focus() alert(`Failed to save. Missing required data for "${label.innerText.substring(1)}"`) return false } } GM_setValue(key, data) alert(`Saved successfully. Reload to check`) return true } GM_registerMenuCommand("Save Step 1 Fields", () => saveFilledData("initialFields", initialFields)) GM_registerMenuCommand("Save Step 2 Fields", () => saveFilledData("otherFields", otherFields)) /* Fill funcs */ const magicChange = new Event("change") function fillFields(data) { for (let fieldName in data) { const input = document.getElementById(fieldName) if (isCheckable(input)) input.checked = data[fieldName] else input.value = data[fieldName] input.dispatchEvent(magicChange) } } function fillInitialFields() { const data = GM_getValue("initialFields", {}) fillFields(data) } function fillOtherFields() { const data = GM_getValue("otherFields", {}) fillFields(data) } function fillPickupTime() { const f = document.getElementById("pickup-regular-time") f.click() return f } function fillPickupDate() { const f = document.querySelector("#schedule-pickup-cal td:not(:first-child):not(.ui-datepicker-unselectable):not(.holiday):not(.ui-state-disabled)") // Gets first date that is selectable f.click() return f } function fillTerms() { const f = document.querySelector(".termsConditions") f.checked = true return f } function fillHazmat() { const f = document.querySelector("#hazmat-no") f.checked = true return f } function scrollToDetails() { document.getElementById("quantityCheck").scrollIntoView() } function showPickupDateInStepFour(pickupDateTD) { const month = parseInt(pickupDateTD.dataset.month) + 1 const year = pickupDateTD.dataset.year const day = pickupDateTD.firstElementChild.innerText const date = `${month}-${day}-${year}` const dateElement = document.createElement("div") dateElement.class = "step-four-top-header" dateElement.innerHTML = `

` dateElement.innerHTML += `Date of Pickup: ${date}` const container = document.querySelector("div.pickup-summary-gray-box-wrapper div") const sibiling = container.querySelector("div.step-four-top-header") container.insertBefore(dateElement, sibiling) return dateElement } /* Start */ fillInitialFields() document.querySelector("#webToolsAddressCheck").addEventListener("click", () => { fillOtherFields() fillPickupTime() // Works through click setTimeout(() => { showPickupDateInStepFour(fillPickupDate()) // Need to wait for this (calendar) to load in first since it's loaded dynamically fillHazmat() fillTerms() scrollToDetails() }, 750) })