rsshub 1.0.0-master.f71451d → 1.0.0-master.f75997f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/config.ts +14 -0
- package/lib/errors/index.test.ts +2 -2
- package/lib/middleware/template.tsx +12 -3
- package/lib/routes/0x80/index.ts +87 -0
- package/lib/routes/0x80/namespace.ts +7 -0
- package/lib/routes/aljazeera/index.ts +17 -14
- package/lib/routes/apple/podcast.ts +64 -0
- package/lib/routes/bilibili/cache.ts +1 -1
- package/lib/routes/bing/daily-wallpaper.ts +9 -8
- package/lib/routes/byau/namespace.ts +6 -0
- package/lib/routes/byau/xinwen/index.ts +72 -0
- package/lib/routes/cpcaauto/index.ts +255 -0
- package/lib/routes/cpcaauto/namespace.ts +8 -0
- package/lib/routes/dehenglaw/index.ts +128 -0
- package/lib/routes/dehenglaw/namespace.ts +8 -0
- package/lib/routes/dehenglaw/templates/description.art +7 -0
- package/lib/routes/gov/stats/index.ts +25 -22
- package/lib/routes/gxmzu/ai.ts +1 -1
- package/lib/routes/gxmzu/lib.ts +9 -26
- package/lib/routes/gxmzu/utils/index.ts +31 -13
- package/lib/routes/gxmzu/yjs.ts +1 -1
- package/lib/routes/jou/utils/index.ts +35 -25
- package/lib/routes/lofter/tag.ts +3 -3
- package/lib/routes/lofter/user.ts +3 -3
- package/lib/routes/njxzc/utils/index.ts +31 -13
- package/lib/routes/qingting/podcast.ts +61 -39
- package/lib/routes/reuters/common.ts +2 -2
- package/lib/routes/sara/index.ts +66 -0
- package/lib/routes/sara/namespace.ts +6 -0
- package/lib/routes/tencent/news/author.ts +13 -11
- package/lib/routes/test/index.ts +11 -1
- package/lib/routes/twitter/api/mobile-api/login.ts +29 -28
- package/lib/routes/twitter/namespace.ts +2 -2
- package/lib/routes/twitter/user.ts +5 -0
- package/lib/routes/u3c3/index.ts +1 -1
- package/lib/routes/u3c3/namespace.ts +1 -1
- package/lib/routes/u9a9/index.ts +2 -2
- package/lib/routes/u9a9/namespace.ts +1 -1
- package/lib/routes/zsxq/group.ts +63 -0
- package/lib/routes/zsxq/namespace.ts +6 -0
- package/lib/routes/zsxq/types.ts +149 -0
- package/lib/routes/zsxq/user.ts +58 -0
- package/lib/routes/zsxq/utils.ts +70 -0
- package/lib/setup.test.ts +183 -12
- package/lib/utils/render.ts +1 -1
- package/lib/utils/request-rewriter/get.ts +8 -1
- package/lib/utils/wechat-mp.test.ts +411 -32
- package/lib/utils/wechat-mp.ts +447 -76
- package/lib/views/{rss3-ums.ts → rss3.ts} +2 -2
- package/package.json +14 -14
package/lib/routes/u9a9/index.ts
CHANGED
|
@@ -9,17 +9,17 @@ const baseUrl = 'https://u9a9.com';
|
|
|
9
9
|
|
|
10
10
|
export const route: Route = {
|
|
11
11
|
path: ['/:preview?', '/search/:keyword/:preview?'],
|
|
12
|
+
example: '/u9a9/search/新片速递',
|
|
12
13
|
radar: [
|
|
13
14
|
{
|
|
14
15
|
source: ['u9a9.com/'],
|
|
15
16
|
target: '',
|
|
16
17
|
},
|
|
17
18
|
],
|
|
18
|
-
name: '
|
|
19
|
+
name: 'Search',
|
|
19
20
|
maintainers: ['TonyRL'],
|
|
20
21
|
handler,
|
|
21
22
|
url: 'u9a9.com/',
|
|
22
|
-
url: 'u9a9.com/',
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
async function handler(ctx) {
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Data, Route } from '@/types';
|
|
2
|
+
import type { Context } from 'hono';
|
|
3
|
+
import { config } from '@/config';
|
|
4
|
+
import ConfigNotFoundError from '@/errors/types/config-not-found';
|
|
5
|
+
import type { GroupInfoResponse, TopicsResponse } from './types';
|
|
6
|
+
import { customFetch, generateTopicDataItem } from './utils';
|
|
7
|
+
|
|
8
|
+
export const route: Route = {
|
|
9
|
+
name: '星球',
|
|
10
|
+
categories: ['social-media'],
|
|
11
|
+
path: '/group/:id/:scope?',
|
|
12
|
+
example: '/zsxq/group/88855458825252',
|
|
13
|
+
parameters: {
|
|
14
|
+
id: '星球id,从网页端url中获取',
|
|
15
|
+
scope: '栏目分类,默认为"all",见下表',
|
|
16
|
+
},
|
|
17
|
+
maintainers: ['KarasuShin'],
|
|
18
|
+
radar: [
|
|
19
|
+
{
|
|
20
|
+
source: ['wx.zsxq.com/dweb2/index/group/:id'],
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
features: {
|
|
24
|
+
requireConfig: [
|
|
25
|
+
{
|
|
26
|
+
name: 'ZSXQ_ACCESS_TOKEN',
|
|
27
|
+
description:
|
|
28
|
+
'知识星球访问令牌,获取方式:\n1. 登录知识星球网页版\n2. 打开浏览器开发者工具,切换到 Application 面板\n3. 点击侧边栏中的Storage -> Cookies -> https://wx.zsxq.com\n4. 复制 Cookie 中的 zsxq_access_token 值',
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
handler,
|
|
33
|
+
description: `| all | digests | by_owner | questions | tasks |
|
|
34
|
+
| ---- | ------ | --------- | -------- | ------ |
|
|
35
|
+
| 最新 | 精华 | 只看星主 | 问答 | 作业 |`,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
async function handler(ctx: Context): Promise<Data> {
|
|
39
|
+
const groupId = ctx.req.param('id');
|
|
40
|
+
const scope = ctx.req.param('scope') ?? 'all';
|
|
41
|
+
const accessToken = config.zsxq.accessToken;
|
|
42
|
+
|
|
43
|
+
if (!accessToken) {
|
|
44
|
+
throw new ConfigNotFoundError('该 RSS 源由于配置不正确而被禁用:令牌丢失。');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let count = Number(ctx.req.query('limit')) || 20;
|
|
48
|
+
if (count > 30) {
|
|
49
|
+
count = 30;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const { group } = await customFetch<GroupInfoResponse>(`/groups/${groupId}`);
|
|
53
|
+
|
|
54
|
+
const { topics } = await customFetch<TopicsResponse>(`/groups/${groupId}/topics?scope=${scope}&count=${count}`);
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
title: `知识星球 - ${group.name}`,
|
|
58
|
+
description: group.description,
|
|
59
|
+
image: group.background_url,
|
|
60
|
+
link: `https://wx.zsxq.com/dweb2/index/group/${groupId}`,
|
|
61
|
+
item: generateTopicDataItem(topics),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
export interface BasicResponse<T> {
|
|
2
|
+
succeeded: boolean;
|
|
3
|
+
resp_data: T;
|
|
4
|
+
code?: number;
|
|
5
|
+
info?: string;
|
|
6
|
+
error?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface BasicTopic {
|
|
10
|
+
comments_count: number;
|
|
11
|
+
create_time: string;
|
|
12
|
+
digested: boolean;
|
|
13
|
+
group: {
|
|
14
|
+
group_id: number;
|
|
15
|
+
name: string;
|
|
16
|
+
type: string;
|
|
17
|
+
background_url: string;
|
|
18
|
+
};
|
|
19
|
+
latest_likes: {
|
|
20
|
+
create_time: string;
|
|
21
|
+
owner: {
|
|
22
|
+
avatar_url: string;
|
|
23
|
+
name: string;
|
|
24
|
+
number: number;
|
|
25
|
+
user_id: number;
|
|
26
|
+
};
|
|
27
|
+
}[];
|
|
28
|
+
likes_count: number;
|
|
29
|
+
readers_count: number;
|
|
30
|
+
reading_count: number;
|
|
31
|
+
rewards_count: number;
|
|
32
|
+
topic_id: number;
|
|
33
|
+
type: string;
|
|
34
|
+
user_specific: {
|
|
35
|
+
liked: false;
|
|
36
|
+
subscribed: false;
|
|
37
|
+
};
|
|
38
|
+
title?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface TalkTopic extends BasicTopic {
|
|
42
|
+
type: 'talk';
|
|
43
|
+
talk: {
|
|
44
|
+
text?: string;
|
|
45
|
+
images?: TopicImage[];
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface QATopic extends BasicTopic {
|
|
50
|
+
type: 'q&a';
|
|
51
|
+
answer?: {
|
|
52
|
+
owner: {
|
|
53
|
+
avatar_url: string;
|
|
54
|
+
description: string;
|
|
55
|
+
location: string;
|
|
56
|
+
name: string;
|
|
57
|
+
user_id: number;
|
|
58
|
+
};
|
|
59
|
+
text?: string;
|
|
60
|
+
images?: TopicImage[];
|
|
61
|
+
};
|
|
62
|
+
answered: boolean;
|
|
63
|
+
question: {
|
|
64
|
+
images?: TopicImage[];
|
|
65
|
+
text?: string;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
interface TaskTopic extends BasicTopic {
|
|
70
|
+
type: 'task';
|
|
71
|
+
task: {
|
|
72
|
+
images?: TopicImage[];
|
|
73
|
+
text?: string;
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
interface SolutionTopic extends BasicTopic {
|
|
78
|
+
type: 'solution';
|
|
79
|
+
solution: {
|
|
80
|
+
task_id: number;
|
|
81
|
+
text?: string;
|
|
82
|
+
images?: TopicImage[];
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
interface UserInfo {
|
|
87
|
+
chat: {
|
|
88
|
+
identifier: string;
|
|
89
|
+
};
|
|
90
|
+
user: {
|
|
91
|
+
avatar_url: string;
|
|
92
|
+
introduction: string;
|
|
93
|
+
location: string;
|
|
94
|
+
name: string;
|
|
95
|
+
unique_id: string;
|
|
96
|
+
user_id: number;
|
|
97
|
+
};
|
|
98
|
+
user_specific: {
|
|
99
|
+
followed: boolean;
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
interface GroupInfo {
|
|
104
|
+
group: {
|
|
105
|
+
admin_ids: number[];
|
|
106
|
+
alive_time: string;
|
|
107
|
+
background_url: string;
|
|
108
|
+
category: {
|
|
109
|
+
category_id: number;
|
|
110
|
+
title: string;
|
|
111
|
+
};
|
|
112
|
+
create_time: string;
|
|
113
|
+
description: string;
|
|
114
|
+
group_id: number;
|
|
115
|
+
guest_ids: number[];
|
|
116
|
+
name: string;
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface TopicImage {
|
|
121
|
+
image_id: number;
|
|
122
|
+
large: {
|
|
123
|
+
height: number;
|
|
124
|
+
width: number;
|
|
125
|
+
url: string;
|
|
126
|
+
};
|
|
127
|
+
original: {
|
|
128
|
+
height: number;
|
|
129
|
+
width: number;
|
|
130
|
+
url: string;
|
|
131
|
+
size: number;
|
|
132
|
+
};
|
|
133
|
+
thumbnail: {
|
|
134
|
+
height: number;
|
|
135
|
+
width: number;
|
|
136
|
+
url: string;
|
|
137
|
+
};
|
|
138
|
+
type: string;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export type Topic = TalkTopic | QATopic | TaskTopic | SolutionTopic;
|
|
142
|
+
|
|
143
|
+
export type UserInfoResponse = BasicResponse<UserInfo>;
|
|
144
|
+
|
|
145
|
+
export type GroupInfoResponse = BasicResponse<GroupInfo>;
|
|
146
|
+
|
|
147
|
+
export type TopicsResponse = BasicResponse<{
|
|
148
|
+
topics: Topic[];
|
|
149
|
+
}>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Data, Route } from '@/types';
|
|
2
|
+
import type { Context } from 'hono';
|
|
3
|
+
import { config } from '@/config';
|
|
4
|
+
import ConfigNotFoundError from '@/errors/types/config-not-found';
|
|
5
|
+
import type { TopicsResponse, UserInfoResponse } from './types';
|
|
6
|
+
import { customFetch, generateTopicDataItem } from './utils';
|
|
7
|
+
|
|
8
|
+
export const route: Route = {
|
|
9
|
+
name: '用户足迹',
|
|
10
|
+
categories: ['social-media'],
|
|
11
|
+
path: '/user/:id',
|
|
12
|
+
example: '/zsxq/user/2414218251',
|
|
13
|
+
parameters: {
|
|
14
|
+
id: '用户id,从网页端url中获取',
|
|
15
|
+
},
|
|
16
|
+
maintainers: ['KarasuShin'],
|
|
17
|
+
radar: [
|
|
18
|
+
{
|
|
19
|
+
source: ['wx.zsxq.com/dweb2/index/footprint/:id'],
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
features: {
|
|
23
|
+
requireConfig: [
|
|
24
|
+
{
|
|
25
|
+
name: 'ZSXQ_ACCESS_TOKEN',
|
|
26
|
+
description:
|
|
27
|
+
'知识星球访问令牌,获取方式:\n1. 登录知识星球网页版\n2. 打开浏览器开发者工具,切换到 Application 面板\n3. 点击侧边栏中的Storage -> Cookies -> https://wx.zsxq.com\n4. 复制 Cookie 中的 zsxq_access_token 值',
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
handler,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
async function handler(ctx: Context): Promise<Data> {
|
|
35
|
+
const uid = ctx.req.param('id');
|
|
36
|
+
const accessToken = config.zsxq.accessToken;
|
|
37
|
+
|
|
38
|
+
if (!accessToken) {
|
|
39
|
+
throw new ConfigNotFoundError('该 RSS 源由于配置不正确而被禁用:令牌丢失。');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let count = Number(ctx.req.query('limit')) || 20;
|
|
43
|
+
if (count > 30) {
|
|
44
|
+
count = 30;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const userInfo = await customFetch<UserInfoResponse>(`/users/${uid}`);
|
|
48
|
+
|
|
49
|
+
const { topics } = await customFetch<TopicsResponse>(`/users/${uid}/topics/footprint?count=${count}`);
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
title: `知识星球 - ${userInfo.user.name}`,
|
|
53
|
+
description: userInfo.user.introduction,
|
|
54
|
+
image: userInfo.user.avatar_url,
|
|
55
|
+
link: `https://wx.zsxq.com/dweb2/index/footprint/${uid}`,
|
|
56
|
+
item: generateTopicDataItem(topics),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import got from '@/utils/got';
|
|
2
|
+
import type { TopicImage, Topic, BasicResponse } from './types';
|
|
3
|
+
import { parseDate } from '@/utils/parse-date';
|
|
4
|
+
import { config } from '@/config';
|
|
5
|
+
import type { DataItem } from '@/types';
|
|
6
|
+
|
|
7
|
+
export async function customFetch<T extends BasicResponse<any>>(path: string, retryCount = 0): Promise<T['resp_data']> {
|
|
8
|
+
const apiUrl = 'https://api.zsxq.com/v2';
|
|
9
|
+
|
|
10
|
+
const response = await got(apiUrl + path, {
|
|
11
|
+
headers: {
|
|
12
|
+
cookie: `zsxq_access_token=${config.zsxq.accessToken};`,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
const { succeeded, code, resp_data } = response.data as T;
|
|
16
|
+
if (succeeded) {
|
|
17
|
+
return resp_data;
|
|
18
|
+
}
|
|
19
|
+
// sometimes the request will fail with code 1059, retry will solve the problem
|
|
20
|
+
if (code === 1059 && retryCount < 3) {
|
|
21
|
+
return customFetch(path, ++retryCount);
|
|
22
|
+
}
|
|
23
|
+
throw new Error('something wrong');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function parseTopicContent(text: string = '', images: TopicImage[] = []) {
|
|
27
|
+
let result = text.replaceAll('\n', '<br>');
|
|
28
|
+
result = result.replaceAll(/<e type="web" href="(.*?)" title="(.*?)" \/>/g, (_, p1, p2) => `<a href=${decodeURIComponent(p1)}>${decodeURIComponent(p2)}</a>`);
|
|
29
|
+
result = result.replaceAll(/<e type="hashtag".*?title="(.*?)" \/>/g, (_, p1) => {
|
|
30
|
+
const title = decodeURIComponent(p1);
|
|
31
|
+
return `<span>${title}</span>`;
|
|
32
|
+
});
|
|
33
|
+
result += images.map((image) => `<img src="${image.original?.url ?? image.large?.url ?? image.thumbnail?.url}">`).join('<br>');
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function generateTopicDataItem(topics: Topic[]): DataItem[] {
|
|
38
|
+
return topics.map((topic) => {
|
|
39
|
+
let description: string | undefined;
|
|
40
|
+
let title = '';
|
|
41
|
+
switch (topic.type) {
|
|
42
|
+
case 'talk':
|
|
43
|
+
title = topic.talk?.text?.split('\n')[0] ?? '文章';
|
|
44
|
+
description = parseTopicContent(topic.talk?.text, topic.talk?.images);
|
|
45
|
+
break;
|
|
46
|
+
case 'q&a':
|
|
47
|
+
title = topic.question?.text?.split('\n')[0] ?? '问答';
|
|
48
|
+
description = parseTopicContent(topic.question?.text, topic.question?.images);
|
|
49
|
+
if (topic.answered) {
|
|
50
|
+
description += '<br><br>';
|
|
51
|
+
description += parseTopicContent(topic.answer?.text, topic.answer?.images);
|
|
52
|
+
}
|
|
53
|
+
break;
|
|
54
|
+
case 'task':
|
|
55
|
+
title = topic.task?.text?.split('\n')[0] ?? '作业';
|
|
56
|
+
description = parseTopicContent(topic.task?.text, topic.task?.images);
|
|
57
|
+
break;
|
|
58
|
+
case 'solution':
|
|
59
|
+
title = topic.solution?.text?.split('\n')[0] ?? '写作业';
|
|
60
|
+
description = parseTopicContent(topic.solution?.text, topic.solution?.images);
|
|
61
|
+
break;
|
|
62
|
+
default:
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
title: topic.title ?? title,
|
|
66
|
+
description,
|
|
67
|
+
pubDate: parseDate(topic.create_time),
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
}
|
package/lib/setup.test.ts
CHANGED
|
@@ -2,6 +2,29 @@ import { afterAll, afterEach } from 'vitest';
|
|
|
2
2
|
import { setupServer } from 'msw/node';
|
|
3
3
|
import { http, HttpResponse } from 'msw';
|
|
4
4
|
|
|
5
|
+
const genWeChatMpPage = (rich_media_content: string, scripts: string[] | string) => {
|
|
6
|
+
if (!Array.isArray(scripts)) {
|
|
7
|
+
scripts = [scripts];
|
|
8
|
+
}
|
|
9
|
+
let pageHtml = `
|
|
10
|
+
<meta name="description" content="summary" />
|
|
11
|
+
<meta name="author" content="author" />
|
|
12
|
+
<meta property="og:title" content="title" />
|
|
13
|
+
<meta property="og:image" content="https://mmbiz.qpic.cn/rsshub_test/og_img_1/0?wx_fmt=jpeg" />
|
|
14
|
+
<meta property="twitter:card" content="summary" />
|
|
15
|
+
<div class="rich_media_content" id="js_content" style="visibility: hidden;">
|
|
16
|
+
${rich_media_content}
|
|
17
|
+
</div>
|
|
18
|
+
<div class="wx_follow_nickname">mpName</div>`;
|
|
19
|
+
for (const script of scripts) {
|
|
20
|
+
pageHtml += `
|
|
21
|
+
<script type="text/javascript" nonce="000000000">
|
|
22
|
+
${script}
|
|
23
|
+
</script>`;
|
|
24
|
+
}
|
|
25
|
+
return pageHtml;
|
|
26
|
+
};
|
|
27
|
+
|
|
5
28
|
const server = setupServer(
|
|
6
29
|
http.post(`https://api.openai.mock/v1/chat/completions`, () =>
|
|
7
30
|
HttpResponse.json({
|
|
@@ -33,21 +56,169 @@ const server = setupServer(
|
|
|
33
56
|
</ul>
|
|
34
57
|
</div>`)
|
|
35
58
|
),
|
|
36
|
-
http.get(`https://mp.weixin.qq.com/rsshub_test/
|
|
59
|
+
http.get(`https://mp.weixin.qq.com/rsshub_test/appMsg`, () =>
|
|
60
|
+
HttpResponse.text(
|
|
61
|
+
genWeChatMpPage(
|
|
62
|
+
`
|
|
63
|
+
description
|
|
64
|
+
<iframe class="video_iframe rich_pages" data-ratio="1.7777777777777777" data-w="864"data-src="https://v.qq.com/rsshub_test/?vid=fake"></iframe>
|
|
65
|
+
<mpvoice name="title" voice_encode_fileid="rsshub_test"></mpvoice>
|
|
66
|
+
`,
|
|
67
|
+
`
|
|
68
|
+
var item_show_type = "0";
|
|
69
|
+
var real_item_show_type = "0";
|
|
70
|
+
var appmsg_type = "9";
|
|
71
|
+
var ct = "${1_636_626_300}";
|
|
72
|
+
var msg_source_url = "https://mp.weixin.qq.com/rsshub_test/fake";
|
|
73
|
+
window.ip_wording = {
|
|
74
|
+
countryName: '中国',
|
|
75
|
+
countryId: '156',
|
|
76
|
+
provinceName: '福建',
|
|
77
|
+
provinceId: '',
|
|
78
|
+
cityName: '',
|
|
79
|
+
cityId: ''
|
|
80
|
+
};`
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
),
|
|
84
|
+
http.get(`https://mp.weixin.qq.com/rsshub_test/img`, () =>
|
|
85
|
+
HttpResponse.text(
|
|
86
|
+
genWeChatMpPage('fake_description', [
|
|
87
|
+
`
|
|
88
|
+
var item_show_type = "8";
|
|
89
|
+
var real_item_show_type = "8";
|
|
90
|
+
var appmsg_type = "9";
|
|
91
|
+
var ct = "${1_636_626_300}";
|
|
92
|
+
`,
|
|
93
|
+
`
|
|
94
|
+
window.picture_page_info_list = [
|
|
95
|
+
{
|
|
96
|
+
cdn_url: 'https://mmbiz.qpic.cn/rsshub_test/fake_img_1/0?wx_fmt=jpeg',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
cdn_url: 'https://mmbiz.qpic.cn/rsshub_test/fake_img_2/0?wx_fmt=jpeg',
|
|
100
|
+
},
|
|
101
|
+
].slice(0, 20);
|
|
102
|
+
`,
|
|
103
|
+
])
|
|
104
|
+
)
|
|
105
|
+
),
|
|
106
|
+
http.get(`https://mp.weixin.qq.com/rsshub_test/audio`, () =>
|
|
107
|
+
HttpResponse.text(
|
|
108
|
+
genWeChatMpPage('fake_description', [
|
|
109
|
+
`
|
|
110
|
+
var item_show_type = "7";
|
|
111
|
+
var real_item_show_type = "7";
|
|
112
|
+
var appmsg_type = "9";
|
|
113
|
+
var ct = "${1_636_626_300}";
|
|
114
|
+
`,
|
|
115
|
+
`
|
|
116
|
+
reportOpt = {
|
|
117
|
+
voiceid: "",
|
|
118
|
+
uin: "",
|
|
119
|
+
biz: "",
|
|
120
|
+
mid: "",
|
|
121
|
+
idx: ""
|
|
122
|
+
};
|
|
123
|
+
window.cgiData = {
|
|
124
|
+
voiceid: "rsshub_test_voiceid_1",
|
|
125
|
+
duration: "6567" * 1,
|
|
126
|
+
};
|
|
127
|
+
`,
|
|
128
|
+
])
|
|
129
|
+
)
|
|
130
|
+
),
|
|
131
|
+
http.get(`https://mp.weixin.qq.com/rsshub_test/video`, () =>
|
|
132
|
+
HttpResponse.text(
|
|
133
|
+
genWeChatMpPage(
|
|
134
|
+
'fake_description',
|
|
135
|
+
`
|
|
136
|
+
var item_show_type = "5";
|
|
137
|
+
var real_item_show_type = "5";
|
|
138
|
+
var appmsg_type = "9";
|
|
139
|
+
var ct = "${1_636_626_300}";
|
|
140
|
+
`
|
|
141
|
+
)
|
|
142
|
+
)
|
|
143
|
+
),
|
|
144
|
+
http.get(`https://mp.weixin.qq.com/rsshub_test/fallback`, () =>
|
|
145
|
+
HttpResponse.text(
|
|
146
|
+
genWeChatMpPage(
|
|
147
|
+
'fake_description',
|
|
148
|
+
`
|
|
149
|
+
var item_show_type = "99988877";
|
|
150
|
+
var real_item_show_type = "99988877";
|
|
151
|
+
var appmsg_type = "9";
|
|
152
|
+
var ct = "${1_636_626_300}";
|
|
153
|
+
`
|
|
154
|
+
)
|
|
155
|
+
)
|
|
156
|
+
),
|
|
157
|
+
http.get(`https://mp.weixin.qq.com/s/rsshub_test`, () => HttpResponse.redirect(`https://mp.weixin.qq.com/rsshub_test/fallback`)),
|
|
158
|
+
http.get(`https://mp.weixin.qq.com/s?__biz=rsshub_test&mid=1&idx=1&sn=1`, () => HttpResponse.redirect(`https://mp.weixin.qq.com/rsshub_test/fallback`)),
|
|
159
|
+
http.get(`https://mp.weixin.qq.com/mp/rsshub_test/waf`, () =>
|
|
160
|
+
HttpResponse.text(
|
|
161
|
+
`<html>
|
|
162
|
+
<head>
|
|
163
|
+
<title>Title</title>
|
|
164
|
+
<script>console.log</script>
|
|
165
|
+
</head>
|
|
166
|
+
<body class="zh_CN " ontouchstart="">
|
|
167
|
+
<script>console.log</script>
|
|
168
|
+
<style>.style{}</style>
|
|
169
|
+
<div class="weui-msg">
|
|
170
|
+
<div id="tips" style="display:none;" class="top_tips warning"></div>
|
|
171
|
+
<div class="weui-msg__icon-area">
|
|
172
|
+
<i class="weui-icon-info-circle weui-icon_msg"></i>
|
|
173
|
+
</div>
|
|
174
|
+
<div class="weui-msg__text-area pc-area">
|
|
175
|
+
<h2 class="weui-msg__title">环境异常</h2>
|
|
176
|
+
<p class="weui-msg__desc">当前环境异常,完成验证后即可继续访问。</p>
|
|
177
|
+
</div>
|
|
178
|
+
<div class="weui-msg__opr-area">
|
|
179
|
+
<p class="weui-btn-area">
|
|
180
|
+
<a class="weui-btn weui-btn_primary" id="js_verify">去验证</a>
|
|
181
|
+
</p>
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
</body></html>`
|
|
185
|
+
)
|
|
186
|
+
),
|
|
187
|
+
http.get(`https://mp.weixin.qq.com/s/rsshub_test_hit_waf`, () => HttpResponse.redirect(`https://mp.weixin.qq.com/mp/rsshub_test/waf`)),
|
|
188
|
+
http.get(`https://mp.weixin.qq.com/s/unknown_page`, () =>
|
|
189
|
+
HttpResponse.text(
|
|
190
|
+
`<html>
|
|
191
|
+
<head>
|
|
192
|
+
<title>Title</title>
|
|
193
|
+
<script>console.log</script>
|
|
194
|
+
</head>
|
|
195
|
+
<body class="zh_CN " ontouchstart="">
|
|
196
|
+
<script>console.log</script>
|
|
197
|
+
<style>.style{}</style>
|
|
198
|
+
<p>
|
|
199
|
+
Unknown paragraph
|
|
200
|
+
</p>
|
|
201
|
+
</body></html>`
|
|
202
|
+
)
|
|
203
|
+
),
|
|
204
|
+
http.get(`https://mp.weixin.qq.com/s/deleted_page`, () =>
|
|
37
205
|
HttpResponse.text(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
206
|
+
`<html>
|
|
207
|
+
<head>
|
|
208
|
+
<title>Title</title>
|
|
209
|
+
<script>console.log</script>
|
|
210
|
+
</head>
|
|
211
|
+
<body class="zh_CN " ontouchstart="">
|
|
212
|
+
<script>console.log</script>
|
|
213
|
+
<style>.style{}</style>
|
|
214
|
+
<p>
|
|
215
|
+
该内容已被发布者删除
|
|
216
|
+
</p>
|
|
217
|
+
</body></html>`
|
|
49
218
|
)
|
|
50
219
|
),
|
|
220
|
+
http.get(`https://mp.weixin.qq.com/s/rsshub_test_redirect_no_location`, () => HttpResponse.text('', { status: 302 })),
|
|
221
|
+
http.get(`https://mp.weixin.qq.com/s/rsshub_test_recursive_redirect`, () => HttpResponse.redirect(`https://mp.weixin.qq.com/s/rsshub_test_recursive_redirect`)),
|
|
51
222
|
http.get(`http://rsshub.test/headers`, ({ request }) =>
|
|
52
223
|
HttpResponse.json({
|
|
53
224
|
...Object.fromEntries(request.headers.entries()),
|
package/lib/utils/render.ts
CHANGED
|
@@ -59,7 +59,14 @@ const getWrappedGet: <T extends Get>(origin: T) => T = (origin) =>
|
|
|
59
59
|
if (!options.agent && proxy.agent) {
|
|
60
60
|
const proxyRegex = new RegExp(proxy.proxyObj.url_regex);
|
|
61
61
|
|
|
62
|
-
if (
|
|
62
|
+
if (
|
|
63
|
+
proxyRegex.test(url.toString()) &&
|
|
64
|
+
url.protocol.startsWith('http') &&
|
|
65
|
+
url.host !== proxy.proxyUrlHandler?.host &&
|
|
66
|
+
url.host !== 'localhost' &&
|
|
67
|
+
!url.host.startsWith('127.') &&
|
|
68
|
+
!(config.puppeteerWSEndpoint?.includes(url.host) ?? false)
|
|
69
|
+
) {
|
|
63
70
|
options.agent = proxy.agent;
|
|
64
71
|
}
|
|
65
72
|
}
|