-
Notifications
You must be signed in to change notification settings - Fork 7.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(route): Add New Route for UPS Tracking #17941
Changes from 3 commits
b88daab
2274ea3
612d9cd
437d524
b98da60
66b15c6
8e92abc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import type { Namespace } from '@/types'; | ||
|
||
export const namespace: Namespace = { | ||
name: 'UPS', | ||
url: 'ups.com', | ||
description: 'United Parcel Service (UPS) updates, news, and tracking RSS feeds.', | ||
|
||
zh: { | ||
name: 'UPS(联合包裹服务公司)', | ||
description: '联合包裹服务公司(UPS)的更新、新闻和追踪 RSS 源。', | ||
}, | ||
}; |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,107 @@ | ||||||||
import { Route } from '@/types'; | ||||||||
import { load } from 'cheerio'; | ||||||||
import { parseDate } from '@/utils/parse-date'; | ||||||||
import puppeteer from '@/utils/puppeteer'; | ||||||||
|
||||||||
export const route: Route = { | ||||||||
path: '/track/:trackingNumber', | ||||||||
categories: ['other'], | ||||||||
example: '/ups/track/1Z78R6790470567520', | ||||||||
parameters: { trackingNumber: 'The UPS tracking number (e.g., 1Z78R6790470567520).' }, | ||||||||
features: { | ||||||||
requireConfig: false, | ||||||||
requirePuppeteer: false, | ||||||||
antiCrawler: false, | ||||||||
supportBT: false, | ||||||||
supportPodcast: false, | ||||||||
supportScihub: false, | ||||||||
}, | ||||||||
radar: [ | ||||||||
{ | ||||||||
source: ['ups.com/track?loc=en_US&tracknum=:trackingNumber'], | ||||||||
target: '/ups/track/:trackingNumber', | ||||||||
}, | ||||||||
], | ||||||||
name: 'UPS Tracking', | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not repeat namespace name RSSHub/lib/routes/ups/namespace.ts Line 4 in 612d9cd
|
||||||||
maintainers: ['Aquabet'], | ||||||||
handler, | ||||||||
}; | ||||||||
|
||||||||
async function handler(ctx) { | ||||||||
const { trackingNumber } = ctx.req.param(); | ||||||||
const url = `https://www.ups.com/track?loc=en_US&tracknum=${trackingNumber}`; | ||||||||
|
||||||||
const browser = await puppeteer(); | ||||||||
const page = await browser.newPage(); | ||||||||
|
||||||||
await page.setRequestInterception(true); | ||||||||
|
||||||||
// skip loading images, stylesheets, and fonts | ||||||||
page.on('request', (request) => { | ||||||||
if (['image', 'stylesheet', 'font'].includes(request.resourceType())) { | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
request.abort(); | ||||||||
} else { | ||||||||
request.continue(); | ||||||||
} | ||||||||
}); | ||||||||
|
||||||||
await page.goto(url, { waitUntil: 'domcontentloaded' }); | ||||||||
|
||||||||
await page.waitForSelector('tr[id^="stApp_ShpmtProg_LVP_progress_row_"]', { | ||||||||
timeout: 30000, | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not wait for 30s, the browser will be closed by RSSHub Lines 57 to 59 in f5fc827
|
||||||||
}); | ||||||||
|
||||||||
const content = await page.content(); | ||||||||
browser.close(); | ||||||||
const $ = load(content); | ||||||||
|
||||||||
// Extract tracking events | ||||||||
const items = $('tr[id^="stApp_ShpmtProg_LVP_progress_row_"]') | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be better if you can intercept the response of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using the official UPS API There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Double-check your devtools network logs, this request does show up when you visit the site and I believe it doesn't require OAuth |
||||||||
.toArray() | ||||||||
.flatMap((el) => { | ||||||||
const $el = $(el); | ||||||||
|
||||||||
// Extract status, location, and datetime | ||||||||
const status = $el | ||||||||
.find(`td[id^="stApp_ShpmtProg_LVP_milestone_nameKey_"]`) | ||||||||
.contents() | ||||||||
.filter(function () { | ||||||||
return this.type === 'text' && this.data.trim() !== ''; | ||||||||
}) | ||||||||
.toArray() | ||||||||
.map((element) => element.data) | ||||||||
.join('') | ||||||||
.trim(); | ||||||||
|
||||||||
const location = $el.find(`span[id^="stApp_milestoneLocation"]`).text().trim(); | ||||||||
const dateTimeText = $el.find(`span[id^="stApp_milestoneDateTime"]`).text().trim(); | ||||||||
|
||||||||
if (!dateTimeText) { | ||||||||
return []; | ||||||||
} | ||||||||
|
||||||||
const cleanedDateTimeText = dateTimeText.normalize('NFKC').replaceAll(/\s+/g, ' ').replaceAll('A.M.', 'AM').replaceAll('P.M.', 'PM').trim(); | ||||||||
|
||||||||
// Separate date and time | ||||||||
const [date, time] = cleanedDateTimeText.split(', '); | ||||||||
const formattedDateTime = `${date} ${time}`; | ||||||||
|
||||||||
return { | ||||||||
title: `${status}: ${location}`, | ||||||||
link: url, | ||||||||
description: ` | ||||||||
Status: ${status} <br> | ||||||||
Location: ${location} <br> | ||||||||
Date and Time: ${date} ${time} | ||||||||
`.trim(), | ||||||||
pubDate: parseDate(formattedDateTime, 'MM/DD/YYYY h:mm A'), | ||||||||
}; | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please create a guid as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. UPS does not provide a separate page for each tracking record. That's why I'm linking each record to the tracking page. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Without provide a guid for feed item, RSSHub will use |
||||||||
}); | ||||||||
|
||||||||
// Return RSS data | ||||||||
return { | ||||||||
title: `UPS Tracking - ${trackingNumber}`, | ||||||||
link: url, | ||||||||
item: items, | ||||||||
}; | ||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
source
cannot match search parameter