Skip to content

Commit 16f8b73

Browse files
KwiatekMikiwukko
authored andcommitted
api: support new xiaohongshu links, add fallbacks to getRedirectingURL
Co-authored-by: KwiatekMiki <hi@kwiatekmiki.pl> Closes #1394
1 parent b9042a9 commit 16f8b73

File tree

6 files changed

+33
-17
lines changed

6 files changed

+33
-17
lines changed

api/src/misc/utils.js

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { request } from 'undici';
1+
import { request } from "undici";
22
const redirectStatuses = new Set([301, 302, 303, 307, 308]);
33

44
export async function getRedirectingURL(url, dispatcher, headers) {
@@ -8,18 +8,34 @@ export async function getRedirectingURL(url, dispatcher, headers) {
88
headers,
99
redirect: 'manual'
1010
};
11+
const getParams = {
12+
...params,
13+
method: 'GET',
14+
};
1115

12-
let location = await request(url, params).then(r => {
16+
const callback = (r) => {
1317
if (redirectStatuses.has(r.statusCode) && r.headers['location']) {
1418
return r.headers['location'];
1519
}
16-
}).catch(() => null);
20+
}
1721

18-
location ??= await fetch(url, params).then(r => {
19-
if (redirectStatuses.has(r.status) && r.headers.has('location')) {
20-
return r.headers.get('location');
21-
}
22-
}).catch(() => null);
22+
/*
23+
try request() with HEAD & GET,
24+
then do the same with fetch
25+
(fetch is required for shortened reddit links)
26+
*/
27+
28+
let location = await request(url, params)
29+
.then(callback).catch(() => null);
30+
31+
location ??= await request(url, getParams)
32+
.then(callback).catch(() => null);
33+
34+
location ??= await fetch(url, params)
35+
.then(callback).catch(() => null);
36+
37+
location ??= await fetch(url, getParams)
38+
.then(callback).catch(() => null);
2339

2440
return location;
2541
}

api/src/processing/service-config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ export const services = {
207207
patterns: [
208208
"explore/:id?xsec_token=:token",
209209
"discovery/item/:id?xsec_token=:token",
210-
"a/:shareId"
210+
":shareType/:shareId",
211211
],
212212
altDomains: ["xhslink.com"],
213213
},

api/src/processing/service-patterns.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export const testers = {
7878

7979
"xiaohongshu": pattern =>
8080
pattern.id?.length <= 24 && pattern.token?.length <= 64
81-
|| pattern.shareId?.length <= 24,
81+
|| pattern.shareId?.length <= 24 && pattern.shareType?.length === 1,
8282

8383
"newgrounds": pattern =>
8484
pattern.id?.length <= 12 || pattern.audioId?.length <= 12,

api/src/processing/services/xiaohongshu.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ const https = (url) => {
66
return url.replace(/^http:/i, 'https:');
77
}
88

9-
export default async function ({ id, token, shareId, h265, isAudioOnly, dispatcher }) {
9+
export default async function ({ id, token, shareType, shareId, h265, isAudioOnly, dispatcher }) {
1010
let noteId = id;
1111
let xsecToken = token;
1212

1313
if (!noteId) {
1414
const patternMatch = await resolveRedirectingURL(
15-
`https://xhslink.com/a/${shareId}`,
15+
`https://xhslink.com/${shareType}/${shareId}`,
1616
dispatcher
1717
);
1818

api/src/processing/url.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ function aliasURL(url) {
9999

100100
case "xhslink":
101101
if (url.hostname === 'xhslink.com' && parts.length === 3) {
102-
url = new URL(`https://www.xiaohongshu.com/a/${parts[2]}`);
102+
url = new URL(`https://www.xiaohongshu.com/${parts[1]}/${parts[2]}`);
103103
}
104104
break;
105105

api/src/util/tests/xiaohongshu.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[
22
{
33
"name": "video (might have expired)",
4-
"url": "https://www.xiaohongshu.com/explore/67cc17a3000000000e00726a?xsec_token=CBSFRtbF57so920elY1kbIX4fE1nhrwlpGZs9m6pIFpwo=",
4+
"url": "https://www.xiaohongshu.com/explore/685e63e1000000000b02ee3b?xsec_token=ABN8EQJCDMPcFX9RRggeIPSHLIJ8zkGceFDyBewLGUz30=",
55
"canFail": true,
66
"params": {},
77
"expected": {
@@ -11,7 +11,7 @@
1111
},
1212
{
1313
"name": "picker with multiple live photos (might have expired)",
14-
"url": "https://www.xiaohongshu.com/explore/67c691b4000000000d0159cc?xsec_token=CB8p1eyB5DiFkwlUpy1BTeVsI9oOve6ppNjuDzo8V8p5w=",
14+
"url": "https://www.xiaohongshu.com/explore/687128a2000000001203d94c?xsec_token=CBlDi5QDXDWZu2uUmbUrpKwg8lEL3uC10mc59lGf43r9w=",
1515
"canFail": true,
1616
"params": {},
1717
"expected": {
@@ -21,7 +21,7 @@
2121
},
2222
{
2323
"name": "one photo (might have expired)",
24-
"url": "https://www.xiaohongshu.com/explore/676e132d000000000b016f68?xsec_token=ABRv6LKzizOFeSaf2HnnBkdBqniB5Ak1fI8tMAHzO31jA",
24+
"url": "https://www.xiaohongshu.com/explore/64726b99000000000800e115?xsec_token=ABoD3qPHqVZolCfS-J8UP9QQaPXZ6Z6PVyODrhaiUg27U=",
2525
"canFail": true,
2626
"params": {},
2727
"expected": {
@@ -31,7 +31,7 @@
3131
},
3232
{
3333
"name": "short link (might have expired)",
34-
"url": "https://xhslink.com/a/czn4z6c1tic4",
34+
"url": "https://xhslink.com/m/2wAnaTkLRc1",
3535
"canFail": true,
3636
"params": {},
3737
"expected": {

0 commit comments

Comments
 (0)