mioki 0.0.0-snapshot.0

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/bun.lock ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "workspaces": {
4
+ "": {
5
+ "name": "scm-task",
6
+ "devDependencies": {
7
+ "@types/bun": "latest",
8
+ },
9
+ },
10
+ },
11
+ "packages": {
12
+ "@types/bun": ["@types/bun@1.3.3", "", { "dependencies": { "bun-types": "1.3.3" } }, "sha512-ogrKbJ2X5N0kWLLFKeytG0eHDleBYtngtlbu9cyBKFtNL3cnpDZkNdQj8flVf6WTZUX5ulI9AY1oa7ljhSrp+g=="],
13
+
14
+ "@types/node": ["@types/node@24.10.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ=="],
15
+
16
+ "bun-types": ["bun-types@1.3.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-z3Xwlg7j2l9JY27x5Qn3Wlyos8YAp0kKRlrePAOjgjMGS5IG6E7Jnlx736vH9UVI4wUICwwhC9anYL++XeOgTQ=="],
17
+
18
+ "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
19
+ }
20
+ }
package/index.js ADDED
@@ -0,0 +1 @@
1
+ export const name = 'mioki'
package/index.ts ADDED
@@ -0,0 +1,195 @@
1
+ #!/usr/bin/env -S node --no-warnings
2
+
3
+ const ulpToken = process.env.ULP_TOKEN || process.argv[2]
4
+
5
+ const UA =
6
+ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36'
7
+ const UAWeWork =
8
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 wxwork/4.1.38 MicroMessenger/7.0.1 Language/zh ColorScheme/Light wwmver/3.26.38.377'
9
+
10
+ async function main() {
11
+ const list = await getArticleList()
12
+ const [a1, a2] = randItems(list, 2)
13
+
14
+ if (!a1 || !a2) {
15
+ throw new Error('没有获取到足够的文章')
16
+ }
17
+
18
+ await doSignin()
19
+ await wait(300)
20
+
21
+ await doLike(a1)
22
+ await wait(300)
23
+ await doComment(a1)
24
+ await wait(300)
25
+ await doShare(a1)
26
+ await wait(300)
27
+
28
+ await doLike(a2)
29
+ await wait(300)
30
+ await doComment(a2)
31
+ await wait(300)
32
+ await doShare(a2)
33
+
34
+ debug('任务结束')
35
+ }
36
+
37
+ main()
38
+
39
+ interface Article {
40
+ id: string
41
+ title: string
42
+ dirId: string
43
+ orderId: string
44
+ teamId: string
45
+ updateTime: string
46
+ }
47
+
48
+ async function getArticleList(options?: {
49
+ page?: number
50
+ pageSize?: number
51
+ teamType?: string
52
+ }): Promise<Article[]> {
53
+ const { page = 2, pageSize = 10, teamType = 1 } = options ?? {}
54
+ const response = await fetch('https://sheingroup.net/be-scm/api/scmArticle/findNewsByTeam', {
55
+ headers: {
56
+ 'content-type': 'application/json',
57
+ cookie: `ulp-token=${ulpToken}`,
58
+ 'User-Agent': UA,
59
+ Referer: 'https://sheingroup.net/portal/scm/informationPage',
60
+ },
61
+ method: 'POST',
62
+ body: JSON.stringify({ pageIndex: page, pageSize, teamType }),
63
+ })
64
+
65
+ const data = (await response.json()) as any
66
+
67
+ if (+data.code !== 0) {
68
+ throw new Error(`Error fetching article list: ${JSON.stringify(data)}`)
69
+ }
70
+
71
+ return (
72
+ data?.info?.records?.map((item: any) => ({
73
+ id: item?.id ?? '',
74
+ title: item?.scmArticleTitle ?? '',
75
+ dirId: item?.scmDirId ?? '',
76
+ orderId: item?.scmOrderId ?? '',
77
+ teamId: item?.scmTeamId ?? '',
78
+ updateTime: new Date(item?.updateTime ?? '').toLocaleString('zh-CN'),
79
+ })) ?? []
80
+ )
81
+ }
82
+
83
+ export async function doSignin() {
84
+ const response = await fetch('https://sheingroup.net/be-scm/ggp/user/signin/checkInNow', {
85
+ headers: {
86
+ 'Content-Type': 'application/json',
87
+ 'User-Agent': UA,
88
+ Cookie: `ulp-token=${ulpToken}`,
89
+ Referer: 'https://sheingroup.net/portal/scm/interact',
90
+ },
91
+ method: 'POST',
92
+ })
93
+
94
+ debug('签到:', await response.text())
95
+ }
96
+
97
+ export async function doLike(article: Article) {
98
+ const hasLike =
99
+ ((await (await fetch('https://sheingroup.net/be-scm/api/scmLike/checkAOE')).json()) as any)
100
+ ?.info === true
101
+
102
+ debug(`文章 ${article.id} 是否点过赞: ${hasLike}`)
103
+
104
+ if (hasLike) {
105
+ await fetch('https://sheingroup.net/be-scm/api/scmLike/cancelAOE', {
106
+ headers: {
107
+ 'content-type': 'application/json',
108
+ Cookie: `ulp-token=${ulpToken}`,
109
+ 'User-Agent': UA,
110
+ Referer: `https://sheingroup.net/portal/scm/articleDetails?articleId=${article.id}&teamId=${article.teamId}`,
111
+ },
112
+ body: JSON.stringify({ scmRelateId: article.id, scmRelateType: 1 }),
113
+ method: 'POST',
114
+ })
115
+
116
+ debug(`取消点赞: ${article.id}`)
117
+ }
118
+
119
+ const response = await fetch('https://sheingroup.net/be-scm/api/scmLike/saveAOE', {
120
+ headers: {
121
+ 'content-type': 'application/json',
122
+ Cookie: `ulp-token=${ulpToken}`,
123
+ 'User-Agent': UA,
124
+ Referer: `https://sheingroup.net/portal/scm/articleDetails?articleId=${article.id}&teamId=${article.teamId}`,
125
+ },
126
+ body: JSON.stringify({ scmRelateId: article.id, scmRelateType: 1 }),
127
+ method: 'POST',
128
+ })
129
+
130
+ debug(`点赞文章: ${article.id}`, await response.text())
131
+ }
132
+
133
+ export async function doComment(article: Article, content: string = '点赞') {
134
+ const response = await fetch('https://sheingroup.net/be-scm/api/common/scmComment/comment', {
135
+ headers: {
136
+ 'content-type': 'application/json',
137
+ cookie: `ulp-token=${ulpToken}`,
138
+ 'User-Agent': UA,
139
+ Referer: `https://sheingroup.net/portal/scm/articleDetails?articleId=${article.id}&teamId=${article.teamId}`,
140
+ },
141
+ body: JSON.stringify({
142
+ scmContent: '点赞',
143
+ scmUserId: '10049738',
144
+ scmRelateType: 1,
145
+ scmRelateId: article.id,
146
+ }),
147
+ method: 'POST',
148
+ })
149
+
150
+ debug(`评论文章: ${article.id}, 内容: ${content}`, await response.text())
151
+ }
152
+
153
+ export async function doShare(article: Article) {
154
+ const response = await fetch(
155
+ `https://scm.sheincorp.cn/api/scmArticle/share?orderId=${article.orderId}`,
156
+ {
157
+ headers: {
158
+ 'Content-Type': 'application/json',
159
+ 'User-Agent': UAWeWork,
160
+ Referer: `https://scm.sheincorp.cn/m/articleDetail?articleId=${article.id}&dirId=${article.dirId}&teamId=${article.teamId}&redirectFrom=pc`,
161
+ Cookie: `ulp-token=${ulpToken}`,
162
+ },
163
+ method: 'POST',
164
+ }
165
+ )
166
+
167
+ debug(`分享文章: ${article.id}`, await response.text())
168
+ }
169
+
170
+ function debug(...args: any[]) {
171
+ console.debug(`[${new Date().toLocaleString('zh-CN')}]`, ...args)
172
+ }
173
+
174
+ export function randItem<T>(items: T[]): T {
175
+ if (!items || items.length === 0) {
176
+ throw new Error('No items to choose from')
177
+ }
178
+
179
+ return items[Math.floor(Math.random() * items.length)] as T
180
+ }
181
+
182
+ export function randItems<T>(items: T[], len = 2): T[] {
183
+ if (!items || items.length <= len) {
184
+ throw new Error('No items to choose from or not enough items')
185
+ }
186
+
187
+ return items
188
+ .slice()
189
+ .sort(() => Math.random() - 0.5)
190
+ .slice(0, len) as T[]
191
+ }
192
+
193
+ export async function wait(ms: number): Promise<void> {
194
+ return new Promise(resolve => setTimeout(resolve, ms))
195
+ }
package/package.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "mioki",
3
+ "type": "module",
4
+ "version": "0.0.0-snapshot.0",
5
+ "description": "package for mioki",
6
+ "main": "index.js",
7
+ "keywords": ["mioki"],
8
+ "scripts": {},
9
+ "author": "Viki <hi@viki.moe>",
10
+ "license": "MIT"
11
+ }
package/readme.md ADDED
@@ -0,0 +1,2 @@
1
+ # mioki
2
+ package for mioki
package/tsconfig.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "compilerOptions": {
3
+ // Environment setup & latest features
4
+ "lib": ["ESNext"],
5
+ "target": "ESNext",
6
+ "module": "ESNext",
7
+ "moduleDetection": "force",
8
+ "jsx": "react-jsx",
9
+ "allowJs": true,
10
+
11
+ // Bundler mode
12
+ "moduleResolution": "bundler",
13
+ "allowImportingTsExtensions": true,
14
+ "verbatimModuleSyntax": true,
15
+ "noEmit": true,
16
+
17
+ // Best practices
18
+ "strict": true,
19
+ "skipLibCheck": true,
20
+ "noFallthroughCasesInSwitch": true,
21
+ "noUncheckedIndexedAccess": true,
22
+
23
+ // Some stricter flags (disabled by default)
24
+ "noUnusedLocals": false,
25
+ "noUnusedParameters": false,
26
+ "noPropertyAccessFromIndexSignature": false
27
+ }
28
+ }