分享一个有意思的命令:极速查明天的平信
USPS Informed Delivery 油猴脚本可自动查明天信件,有用户成功验证。
1. 关键信息
- 命令通过USPS Informed Delivery API查询信件图像,需替换TOKEN、ZIP11、DATE(#1)。
- TOKEN有效期约5分钟(#3)。
- 部分用户实测只能看到当天信件,明天无效(#6)。
- 若返回"mailpieces":[],表示该日期无记录,需等信件入库(#8)。
- #9 指出该命令对应的正是USPS Informed Delivery免费服务。
- #10 补充:数据库在每天早上email发送前就已更新,因此可以提前查看服务器上已有的信件图像。
- #11 提供完整油猴脚本(userscript),自动在USPS Informed Delivery页面添加“Tomorrow”标签页,无需手动抓取token和curl命令,即可直接查看明天信件图像。
- #13 用户成功通过脚本/命令查看到明天信件图像,并上传截图:/uploads/short-url/gQwaftlbXod6dBXYqars9SY4CZ.png?dl=1
2. 羊毛/优惠信息
无
3. 最新动态
- 分享curl命令直接下载信件图像(#1)。
- 有用户提及油猴脚本可查看但非100%成功(#7)。
- #9 确认该服务本质为免费USPS Informed Delivery。
- #10 强调数据库更新早于email通知,可更早查信。
- #11 发布完整油猴脚本,自动注入“Tomorrow”标签页,支持点击切换、自动刷新、图片加载,并处理token过期和错误提示。
- #13 用户发布截图证实已成功提前获取明天信件图像。
4. 争议或不同意见
- #6 实测只能看当天,与#1声称可查未来1-2天矛盾。
- #5 称看到未来2天IRS信,但未说明是否成功下载。
- #13 的成功案例表明,明天信件查询在特定条件下可行(需信件已入库、token有效),并非完全无效。
5. 行动建议
- 抓取最新TOKEN后立即使用,避免过期。
- 优先查询当天日期,未来日期需等信件入库后再试。
- 可结合Informed Delivery邮件通知辅助验证,也可在email发送前直接查数据库。
- 推荐安装#11的油猴脚本,自动处理token、日期切换和图像加载,降低使用门槛。
- 参考#13的成功经验:在信件实际投递日前一天(美国东部时间早晨后)尝试查询,成功率较高。
USPS 的分拣中心(Sorting Facility), 信件通常在到达你家邮递员手中前的 12 到 24 小时 就已经完成了数字化扫描。一旦扫描完成,数据就会同步到 Informed Delivery 的云端数据库,因此你提前就能看到它们。 # --- 极速查信分享版 --- # 使用说明: # 1. 在 最新TOKEN 替换你从Safari抓取的最新 Bearer # 2. 在 ZIP11 替换你自己的 11 位地址编码(抓包可见) # 3. 在 DATE 处填入想查询的日期,一般是未来1-2天 TOKEN="最新TOKEN"; \ ZIP11="90210432199"; \ DATE="2026-05-08"; \ curl -s -X POST 'https://apis-id.usps.com/informed-delivery/v3/dashboard/mail-pieces/search' \ -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" \ --data-raw "{\"ZIP11\":\"$ZIP11\",\"deliveryDate\":\"$DATE\",\"source\":\"CP\"}" | \ grep -o 'https://apis-id.usps.com/informed-delivery-images/v2/mail-piece-images/[^"]*' | \ while read -r url; do curl -s -H "Authorization: Bearer $TOKEN" "$url" -O; done; \ open . /uploads/short-url/hqbBU4wrY96qXh7mLAMjCuLzsi7.png?dl=1 替换后,复制粘贴给termial,会自动下载信件图。
token多久过期。
一般5分钟吧
每天早上他会有邮件通知当天会有什么邮件,也不着急啊
然后看到未来2天的一封IRS的信
实际测了一下,只能看到当天的letters,明天的好像看不到。 就是当天的并行使用相同的 token 是有效的,明天的就无效了。
貌似版上有人发过油猴脚本,能去usps网站直接看,虽然也不是100%。 不知道这个方法成功率怎么样?
"mailpieces":[] 这表示 USPS 系统中目前没有该日期的信件记录 。等信件入库。
这个就是 USPS Informed Delivery 吧,免费的服务
对。但是email每天早上发。 数据库并不是发email时候才更新。 所以可以提前看服务器上有什么
whhv: 极速查信 谢谢 lz. vibe 成了 userscript 入口是加了的这个 button,用起来方便一些 /uploads/short-url/tnefXLBR45EswlISW5Cyw0jpS5A.png?dl=1 // ==UserScript== // @name USPS Informed Delivery Tomorrow Tab // @namespace https://informeddelivery.usps.com/ // @version 0.2.24 // @description Add a native-looking Tomorrow tab to USPS Informed Delivery and show tomorrow mail inline. // @match https://informeddelivery.usps.com/portal/* // @run-at document-start // @grant none // Reference: https://www.uscardforum.com/t/topic/504477 // ==/UserScript== (() => { 'use strict'; if (window.__uspsTomorrowTabLite) return; window.__uspsTomorrowTabLite = true; const TOMORROW_ID = 'usps-tomorrow-tab-item', PANEL_ID = 'usps-tomorrow-tab-panel', STYLE_ID = 'usps-tomorrow-tab-style'; const PAGE_EVENT = 'usps-tomorrow-tab:search-observed', ROUTE_EVENT = 'usps-tomorrow-tab:route-change', SELECTED_VIEW_KEY = 'uspsTomorrowTab:selectedView'; const SEARCH_URL = 'https://apis-id.usps.com/informed-delivery/v3/dashboard/mail-pieces/search', IMAGE_BASE_URL = 'https://apis-id.usps.com/informed-delivery-images/v2/'; const SUPPORTED_PATHS = new Set(['/portal/dashboard', '/portal/mailpiecedash']), STARTUP_REFRESHES = [0, 150, 400, 900, 3000], SEARCH_REFRESHES = [0, 150, 400, 900, 3000, 7000, 12000], CLICK_REFRESHES = [0, 250, 1000, 3000]; const RESTORE_TIMEOUT_MS = 12000, MISSING_ATTR = '__missing__'; const clean = value => typeof value === 'string' ? value.trim() : ''; const parseJson = text => { try { return JSON.parse(text); } catch { return null; } }; const authError = message => Object.assign(new Error(message), { auth: true }); const errorMessage = error => clean(error?.message) || 'Unknown error.'; const byId = id => document.getElementById(id), q = selector => document.querySelector(selector); const pathKey = pathname => (String(pathname || location.pathname).replace(/\/+$/, '').toLowerCase() || '/'); const supported = pathname => SUPPORTED_PATHS.has(pathKey(pathname)); const nativeList = () => byId('CurrentMailpieces') || q('#CP_nontracked .cp_container'); const stripTabs = strip => Array.from(strip?.children || []).filter(node => node.id !== TOMORROW_ID); const getBearerToken = () => clean(localStorage.getItem('bearerToken')); const tomorrowDate = () => { const next = new Date(); next.setHours(0, 0, 0, 0); next.setDate(next.getDate() + 1); return next.toISOString().slice(0, 10); }; const makeTomorrow = (date, patch = {}) => ({ date, loading: false, error: '', count: null, pieces: [], ...patch }); const copyPiece = piece => ({ directHref: piece.directHref, imageName: piece.imageName, url: piece.url, message: piece.message }); const copyTomorrow = tomorrow => ({ ...tomorrow, loading: false, pieces: tomorrow.pieces.map(copyPiece) }); const persistedTomorrow = () => { try { return sessionStorage.getItem(SELECTED_VIEW_KEY) === 'tomorrow'; } catch { return false; } }; const state = { zip11: '', encryptedZip11: '', selected: 'native', pendingRestoreTomorrow: persistedTomorrow(), tomorrowDate: tomorrowDate(), cache: new Map(), objectUrls: new Set(), loadPromise: null }; state.tomorrow = makeTomorrow(state.tomorrowDate); let refreshTimer = 0, refreshBurstToken = 0, restoreObserver = null, restoreTimeout = 0, restoreFrameToken = 0; installPageBridge(); installRouteBridge(); window.addEventListener(PAGE_EVENT, handleObservedSearch); window.addEventListener(ROUTE_EVENT, requestRefresh); window.addEventListener('popstate', requestRefresh); document.addEventListener('click', handleClick, true); window.addEventListener('beforeunload', revokeObjectUrls); refreshBurst(STARTUP_REFRESHES); function setSelectedView(view) { state.selected = view === 'tomorrow' ? 'tomorrow' : 'native'; try { state.selected === 'tomorrow' ? sessionStorage.setItem(SELECTED_VIEW_KEY, 'tomorrow') : sessionStorage.removeItem(SELECTED_VIEW_KEY); } catch {} } const setTomorrowLoading = patch => { state.tomorrow = makeTomorrow(state.tomorrowDate, { loading: true, ...patch }); }; const setTomorrowError = message => { state.tomorrow = makeTomorrow(state.tomorrowDate, { error: message }); }; const rememberObjectUrl = blob => { const url = URL.createObjectURL(blob); state.objectUrls.add(url); return url; }; const restoreAttr = (node, name, value) => value === MISSING_ATTR ? node.removeAttribute(name) : node.setAttribute(name, value); const tomorrowLabel = () => typeof state.tomorrow.count === 'number' ? String(state.tomorrow.count) : (!state.zip11 || state.tomorrow.loading ? '...' : state.tomorrow.error ? '?' : '...'); function requestRefresh() { clearTimeout(refreshTimer); refreshTimer = setTimeout(refresh, 40); } function refreshBurst(delays) { const token = ++refreshBurstToken; for (const delay of delays) setTimeout(() => token === refreshBurstToken && requestRefresh(), delay); } function installPageBridge() { const script = document.createElement('script'); script.textContent = `(${function pageBridge(eventName) { 'use strict'; if (window.__uspsTomorrowTabBridgeInstalled) return; window.__uspsTomorrowTabBridgeInstalled = true; const SEARCH_PATH = '/informed-delivery/v3/dashboard/mail-pieces/search'; const nativeOpen = XMLHttpRequest.prototype.open, nativeSend = XMLHttpRequest.prototype.send; const parseJson = text => { if (typeof text !== 'string' || !text) return null; try { return JSON.parse(text); } catch { return null; } }; const normalizeUrl = url => { try { return new URL(url, location.href); } catch { return null; } }; // This has to run in page context so we can see USPS's own XHR traffic. XMLHttpRequest.prototype.open = function (method, url) { this.__uspsTomorrowMethod = method; this.__uspsTomorrowUrl = url; return nativeOpen.apply(this, arguments); }; XMLHttpRequest.prototype.send = function (body) { const method = String(this.__uspsTomorrowMethod || '').toUpperCase(), parsed = normalizeUrl(this.__uspsTomorrowUrl); if (method === 'POST' && parsed?.pathname === SEARCH_PATH) { this.addEventListener('load', function () { if (this.status < 200 || this.status >= 300) return; const requestBody = parseJson(typeof body === 'string' ? body : ''), responseBody = parseJson(this.responseText); if (!requestBody || !responseBody) return; window.dispatchEvent(new CustomEvent(eventName, { detail: { zip11: typeof requestBody.ZIP11 === 'string' ? requestBody.ZIP11 : '', deliveryDate: typeof requestBody.deliveryDate === 'string' ? requestBody.deliveryDate : '', encryptedZip11: typeof responseBody.encryptedZIP11 === 'string' ? responseBody.encryptedZIP11 : '' } })); }); } return nativeSend.apply(this, arguments); }; }})(${JSON.stringify(PAGE_EVENT)});`; (document.documentElement || document.head || document.body).appendChild(script); script.remove(); } function installRouteBridge() { for (const method of ['pushState', 'replaceState']) { const nativeMethod = history[method]; if (nativeMethod.__uspsTomorrowWrapped) continue; history[method] = function () { const result = nativeMethod.apply(this, arguments); window.dispatchEvent(new Event(ROUTE_EVENT)); return result; }; history[method].__uspsTomorrowWrapped = true; } } function cancelPendingRestore() { restoreFrameToken += 1; if (restoreObserver) restoreObserver.disconnect(); if (restoreTimeout) clearTimeout(restoreTimeout); restoreObserver = null; restoreTimeout = 0; } function tryPendingRestore() { if (!state.pendingRestoreTomorrow || !state.zip11 || !supported()) return; const strip = findDayStrip(), list = nativeList(); if (!strip || !list || !strip.isConnected || !list.isConnected) return; const token = ++restoreFrameToken; // Restoring too early was a source of hangs, so require the same strip/list // pair to survive across two animation frames before switching back. const stable = () => state.pendingRestoreTomorrow && state.zip11 && supported() && strip.isConnected && list.isConnected && findDayStrip() === strip && nativeList() === list; requestAnimationFrame(() => { if (restoreFrameToken !== token || !stable()) return; requestAnimationFrame(() => { if (restoreFrameToken !== token || !stable()) return; state.pendingRestoreTomorrow = false; cancelPendingRestore(); setSelectedView('tomorrow'); requestRefresh(); loadTomorrow(false); }); }); } function startPendingRestore() { if (!state.pendingRestoreTomorrow || !state.zip11) return cancelPendingRestore(); if (!restoreObserver) { const root = nativeList()?.parentNode || findDayStrip()?.parentNode; if (root) { restoreObserver = new MutationObserver(tryPendingRestore); restoreObserver.observe(root, { childList: true, subtree: true }); } if (!restoreTimeout) restoreTimeout = setTimeout(cancelPendingRestore, RESTORE_TIMEOUT_MS); } tryPendingRestore(); } function handleObservedSearch(event) { const detail = event?.detail || {}; let changed = false, identityChanged = false; if (detail.zip11 && detail.zip11 !== state.zip11) { identityChanged = !!state.zip11 && state.zip11 !== detail.zip11; state.zip11 = detail.zip11; changed = true; } if (detail.encryptedZip11 && detail.encryptedZip11 !== state.encryptedZip11) { identityChanged ||= !!state.encryptedZip11 && state.encryptedZip11 !== detail.encryptedZip11; state.encryptedZip11 = detail.encryptedZip11; changed = true; } syncTomorrowDate(); if (identityChanged) clearCache(); if (changed && state.zip11 && !state.cache.has(state.tomorrowDate)) loadTomorrow(true); refreshBurst(SEARCH_REFRESHES); startPendingRestore(); } function handleClick(event) { if (!supported()) return; const tomorrowTab = event.target?.closest?.(`#${TOMORROW_ID}`); if (tomorrowTab) { event.preventDefault(); event.stopPropagation(); if (tomorrowTab.classList.contains('utt-disabled')) return; state.pendingRestoreTomorrow = false; cancelPendingRestore(); setSelectedView('tomorrow'); requestRefresh(); refreshBurst(CLICK_REFRESHES); loadTomorrow(false); return; } const strip = findDayStrip(); if (!strip || !strip.contains(event.target)) return; state.pendingRestoreTomorrow = false; cancelPendingRestore(); setSelectedView('native'); requestRefresh(); refreshBurst(CLICK_REFRESHES); } function refresh() { syncTomorrowDate(); if (!supported()) return teardown(); const list = nativeList(); if (!list) return teardown(); ensureStyle(); ensurePanel(list); const strip = findDayStrip(); if (strip) ensureTomorrowTab(strip); else byId(TOMORROW_ID)?.remove(); startPendingRestore(); updateView(list); if (state.zip11 && !state.cache.has(state.tomorrowDate) && !state.loadPromise && !state.tomorrow.error) loadTomorrow(true); } function teardown() { cancelPendingRestore(); byId(TOMORROW_ID)?.remove(); byId(PANEL_ID)?.remove(); const strip = findDayStrip(); if (strip) restoreDemotedTabs(strip); setHidden(nativeList(), false); } function syncTomorrowDate() { const next = tomorrowDate(); if (next === state.tomorrowDate) return; state.tomorrowDate = next; clearCache(); } function revokeObjectUrls() { for (const url of state.objectUrls) URL.revokeObjectURL(url); state.objectUrls.clear(); } function clearCache() { revokeObjectUrls(); state.cache.clear(); state.loadPromise = null; state.tomorrow = makeTomorrow(state.tomorrowDate); } const findDayStrip = () => Array.from(document.querySelectorAll('#CP_dayList ul, #cp_week')).find(node => stripTabs(node).length) || null; const tabIsActive = tab => !!(tab && (tab.getAttribute('aria-selected') === 'true' || tab.getAttribute('aria-current') === 'page' || /\b(active|selected|current)\b/i.test(clean(tab.className)))); function tabContext(strip) { const tabs = stripTabs(strip), active = tabs.find(tabIsActive) || tabs[0] || null; const today = tabs.find(tab => /\btoday\b/i.test(clean(tab.textContent))) || tabs[tabs.length - 1] || active; return { active, today, inactive: tabs.find(tab => tab !== active) || today || active }; } function setHidden(node, hidden) { if (!node) return; if (hidden) { if (!Object.prototype.hasOwnProperty.call(node.dataset, 'uttPrevDisplay')) node.dataset.uttPrevDisplay = node.style.display || ''; node.style.display = 'none'; return; } if (!Object.prototype.hasOwnProperty.call(node.dataset, 'uttPrevDisplay')) return void node.style.removeProperty('display'); node.style.display = node.dataset.uttPrevDisplay; delete node.dataset.uttPrevDisplay; if (!node.style.display) node.style.removeProperty('display'); } function setFirstText(root, label) { const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT); let node = null, changed = false; while ((node = walker.nextNode())) { if (!clean(node.nodeValue)) continue; node.nodeValue = changed ? '' : label; changed = true; } if (!changed) root.textContent = label; } function sanitizeClone(root, label) { if (!root || root.nodeType !== 1) return root; // Clones are only visual shells; strip IDs and interactive targets so they // do not collide with USPS's live DOM or accidentally navigate. root.removeAttribute('id'); root.style.removeProperty('display'); delete root.dataset?.uttPrevDisplay; if (label != null) setFirstText(root, label); for (const node of root.querySelectorAll('[id],a,button')) { node.removeAttribute('id'); if (node.tagName === 'A') node.setAttribute('href', '#'), node.setAttribute('tabindex', '-1'); if (node.tagName === 'BUTTON') node.setAttribute('type', 'button'), node.setAttribute('tabindex', '-1'); } return root; } function restoreDemotedTabs(strip) { for (const tab of stripTabs(strip)) { if (!Object.prototype.hasOwnProperty.call(tab.dataset, 'uttSavedClass')) continue; tab.className = tab.dataset.uttSavedClass; restoreAttr(tab, 'aria-selected', tab.dataset.uttSavedAriaSelected); restoreAttr(tab, 'aria-current', tab.dataset.uttSavedAriaCurrent); delete tab.dataset.uttSavedClass; delete tab.dataset.uttSavedAriaSelected; delete tab.dataset.uttSavedAriaCurrent; } } function demoteNativeSelection(strip) { restoreDemotedTabs(strip); const active = stripTabs(strip).find(tabIsActive); if (!active) return; active.dataset.uttSavedClass = active.className; active.dataset.uttSavedAriaSelected = active.getAttribute('aria-selected') || MISSING_ATTR; active.dataset.uttSavedAriaCurrent = active.getAttribute('aria-current') || MISSING_ATTR; active.className = active.className.replace(/\b(active|selected|current)\b/gi, ' ').replace(/\s+/g, ' ').trim(); active.setAttribute('aria-selected', 'false'); active.removeAttribute('aria-current'); } function ensureTomorrowTab(strip) { const { active, today, inactive } = tabContext(strip); if (!today) return byId(TOMORROW_ID)?.remove(); const template = state.selected === 'tomorrow' ? (active || today) : (today !== active ? today : inactive || today); const next = sanitizeClone(template.cloneNode(true), `Tomorrow (${tomorrowLabel()})`); const disabled = !state.zip11 || (state.tomorrow.loading && state.tomorrow.count == null); next.id = TOMORROW_ID; // The synthetic tab needs to own its selected styling instead of relying on // whichever native tab happened to be cloned during this refresh. if (state.selected === 'tomorrow') { if (!/\bactive\b/i.test(next.className)) next.className = `${next.className} active`.trim(); next.setAttribute('aria-selected', 'true'); next.setAttribute('aria-current', 'page'); } else { next.className = next.className.replace(/\bactive\b/gi, ' ').replace(/\s+/g, ' ').trim(); next.removeAttribute('aria-selected'); next.removeAttribute('aria-current'); } next.classList.toggle('utt-disabled', disabled); disabled ? next.setAttribute('aria-disabled', 'true') : next.removeAttribute('aria-disabled'); const current = byId(TOMORROW_ID); if (current && current.parentNode === strip && current.nextSibling === today && current.outerHTML === next.outerHTML) return; current?.remove(); strip.insertBefore(next, today); } function ensurePanel(list) { let panel = byId(PANEL_ID); if (!panel) { panel = document.createElement('div'); panel.id = PANEL_ID; panel.hidden = true; panel.innerHTML = '<div class="utt-status" data-role="status"></div><div class="utt-results" data-role="results"></div>'; } if (panel.parentNode !== list.parentNode || panel.nextSibling !== list) list.parentNode.insertBefore(panel, list); return panel; } const noMailState = () => { const wrapper = document.createElement('div'); wrapper.className = 'masonry'; wrapper.innerHTML = '<div class="noMail">You currently have no mail tomorrow. Please check back later.</div><br>'; return wrapper; }; const pieceTemplate = () => { const node = nativeList()?.firstElementChild || nativeList(); return node ? sanitizeClone(node.cloneNode(true)) : null; }; function renderPieceNode(piece, template) { let node = template ? template.cloneNode(true) : null, image = node?.querySelector('img'); if (piece.url) { if (image) { image.src = piece.url; image.alt = 'Tomorrow mailpiece cover'; image.removeAttribute('srcset'); image.removeAttribute('sizes'); return node; } node = document.createElement('div'); node.className = 'utt-fallback'; image = document.createElement('img'); image.src = piece.url; image.alt = 'Tomorrow mailpiece cover'; image.className = 'utt-fallback-image'; node.appendChild(image); return node; } if (image) { const note = document.createElement('div'); note.className = 'utt-note'; note.textContent = piece.message || 'No cover image available.'; image.replaceWith(note); return node; } node = document.createElement('div'); node.className = 'utt-fallback'; node.textContent = piece.message || 'No cover image available.'; return node; } function renderPanel(panel) { const statusNode = panel.querySelector('[data-role="status"]'), resultsNode = panel.querySelector('[data-role="results"]'); if (!statusNode || !resultsNode) return; let status = ''; if (state.selected === 'tomorrow') { if (!state.zip11) status = 'Waiting for dashboard data.'; else if (state.tomorrow.error) status = state.tomorrow.error; else if (state.tomorrow.loading && !state.tomorrow.pieces.length) status = 'Loading tomorrow mail...'; } statusNode.hidden = !status; statusNode.textContent = status; resultsNode.replaceChildren(); if (state.selected !== 'tomorrow') return; if (state.tomorrow.count === 0) return void resultsNode.appendChild(noMailState()); if (!state.tomorrow.pieces.length) return; const template = pieceTemplate(); for (const piece of state.tomorrow.pieces) resultsNode.appendChild(renderPieceNode(piece, template)); } function updateView(list) { const panel = byId(PANEL_ID), strip = findDayStrip(); if (strip) state.selected === 'tomorrow' ? demoteNativeSelection(strip) : restoreDemotedTabs(strip); if (!panel) return; panel.hidden = state.selected !== 'tomorrow'; setHidden(list, state.selected === 'tomorrow'); renderPanel(panel); } const toPiece = mailpiece => { const image = mailpiece?.campaign?.replacementImage || mailpiece?.image, link = image?.links?.[0]; return { directHref: clean(link?.href), imageName: clean(image?.imageName), url: '', message: link?.href || image?.imageName ? 'Loading cover...' : 'No cover image available.' }; }; async function fetchJson(url, init) { const response = await fetch(url, init), text = await response.text(); if (response.status === 401 || response.status === 403) throw authError('USPS rejected the request.'); if (!response.ok) throw new Error(`USPS request failed (${response.status}): ${(parseJson(text) || {}).message || text || response.statusText}`); return parseJson(text) || {}; } async function fetchBlobUrl(url, init, multipart) { const response = await fetch(url, init); if (response.status === 401 || response.status === 403) throw authError('USPS rejected the image request.'); if (!response.ok) throw new Error(`USPS image request failed (${response.status}).`); if (!multipart) return rememberObjectUrl(await response.blob()); const contentType = clean(response.headers.get('content-type')).toLowerCase(); if (contentType.startsWith('image/')) return rememberObjectUrl(await response.blob()); if (!contentType.startsWith('multipart/form-data') || typeof response.formData !== 'function') return ''; for (const part of (await response.formData()).values()) if (part instanceof Blob) return rememberObjectUrl(part); return ''; } function isAuthenticatedImageUrl(url) { const value = clean(url); if (!value) return false; try { const parsed = new URL(value, location.href); return parsed.protocol.startsWith('http') && (parsed.pathname.includes('/informed-delivery-images/') || parsed.pathname.includes('/mail-piece-images/')); } catch { return false; } } async function resolvePieceUrl(piece, bearerToken) { if (clean(piece.directHref).startsWith('https://www.usps.com/email/id')) return piece.directHref; if (isAuthenticatedImageUrl(piece.directHref)) return fetchBlobUrl(piece.directHref, { headers: { Authorization: `Bearer ${bearerToken}` } }); if (!state.encryptedZip11 || !piece.imageName) return ''; return fetchBlobUrl(`${IMAGE_BASE_URL}${encodeURIComponent(state.encryptedZip11)}?images=${encodeURIComponent(piece.imageName)}`, { headers: { Accept: 'multipart/form-data', Authorization: `Bearer ${bearerToken}` } }, true); } async function populatePiecePreview(piece, bearerToken) { if (!piece.directHref && !piece.imageName) return void (piece.message = 'No cover image available.'); try { piece.url = await resolvePieceUrl(piece, bearerToken); piece.message = piece.url ? '' : 'No cover image available.'; } catch (error) { piece.message = error?.auth ? 'Session expired. Refresh the dashboard or sign in again.' : 'No cover image available.'; } if (state.selected === 'tomorrow') renderPanel(byId(PANEL_ID)); } async function loadTomorrow(background) { syncTomorrowDate(); const cached = state.cache.get(state.tomorrowDate); if (cached) return void (state.tomorrow = copyTomorrow(cached), requestRefresh()); if (!state.zip11) return void (!background && requestRefresh()); if (state.loadPromise) return state.loadPromise; const bearerToken = getBearerToken(); if (!bearerToken) return void (setTomorrowError('Missing USPS session token. Refresh the dashboard or sign in again.'), requestRefresh()); // Keep one in-flight fetch per date; later refreshes/render passes just reuse // the same promise or the completed snapshot from `state.cache`. setTomorrowLoading(); if (!background || state.selected === 'tomorrow') requestRefresh(); state.loadPromise = (async () => { try { const response = await fetchJson(SEARCH_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${bearerToken}` }, body: JSON.stringify({ ZIP11: state.zip11, deliveryDate: state.tomorrowDate, source: 'CP', maxMailPieces: 100, campaigns: true }) }); if (clean(response.encryptedZIP11)) state.encryptedZip11 = response.encryptedZIP11; const pieces = (Array.isArray(response.mailpieces) ? response.mailpieces : []).map(toPiece); setTomorrowLoading({ count: pieces.length, pieces }); requestRefresh(); await Promise.allSettled(pieces.map(piece => populatePiecePreview(piece, bearerToken))); state.tomorrow.loading = false; state.cache.set(state.tomorrowDate, copyTomorrow(state.tomorrow)); } catch (error) { setTomorrowError(error?.auth ? 'USPS rejected the request. Refresh the dashboard or sign in again.' : `Unable to load tomorrow mail: ${errorMessage(error)}`); } finally { state.loadPromise = null; requestRefresh(); } })(); return state.loadPromise; } function ensureStyle() { if (byId(STYLE_ID)) return; const style = document.createElement('style'); style.id = STYLE_ID; style.textContent = [ `#${TOMORROW_ID}{cursor:pointer}`, `#${TOMORROW_ID}.utt-disabled{opacity:.55;pointer-events:none}`, `#${PANEL_ID}{margin:0 0 18px}`, `#${PANEL_ID} .utt-status{margin:0 0 14px;color:#2d2d72;font-size:14px;line-height:1.4}`, `#${PANEL_ID} .utt-note,#${PANEL_ID} .utt-fallback{padding:16px;color:#2d2d72;font-size:14px;line-height:1.4}`, `#${PANEL_ID} .utt-fallback-image{display:block;width:100%;max-width:540px;height:auto}` ].join('\n'); (document.head || document.documentElement).appendChild(style); } })();
研究一个脚本竟然被"进化"了,感谢!
/uploads/short-url/gQwaftlbXod6dBXYqars9SY4CZ.png?dl=1 哈哈哈已经出来了!