napcat-sdk 0.0.0-snapshot.0 → 0.1.0-beta.8
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/.node-version +1 -0
- package/dist/index.cjs +653 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1054 -0
- package/dist/index.d.mts +1054 -0
- package/dist/index.mjs +612 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +36 -8
- package/src/index.ts +4 -0
- package/src/logger.ts +27 -0
- package/src/napcat.ts +497 -0
- package/src/onebot.ts +1381 -0
- package/src/segment.ts +59 -0
- package/src/types.ts +34 -0
- package/tsconfig.json +1 -26
- package/tsdown.config.ts +12 -0
- package/bun.lock +0 -20
- package/index.js +0 -1
- package/index.ts +0 -195
- package/readme.md +0 -2
package/src/segment.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ExtractByType } from './types'
|
|
2
|
+
import type { SendElement } from './onebot'
|
|
3
|
+
|
|
4
|
+
function createSegment<T extends SendElement['type'], D>(type: T, data: D): SendElement {
|
|
5
|
+
return { type, ...data } as SendElement
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 消息片段构造器
|
|
10
|
+
*/
|
|
11
|
+
export const segment = {
|
|
12
|
+
/** 创建一个文本消息片段 */
|
|
13
|
+
text: (text: string): SendElement => createSegment('text', { text }),
|
|
14
|
+
/** 创建一个艾特消息片段 */
|
|
15
|
+
at: (qq: 'all' | (string & {})): SendElement => createSegment('at', { qq }),
|
|
16
|
+
/** 创建一个 QQ 表情消息片段 */
|
|
17
|
+
face: (id: number): SendElement => createSegment('face', { id }),
|
|
18
|
+
/** 创建一个回复消息片段 */
|
|
19
|
+
reply: (id: string): SendElement => createSegment('reply', { id }),
|
|
20
|
+
/** 创建一个图片消息片段 */
|
|
21
|
+
image: (file: string, options?: Omit<ExtractByType<SendElement, 'image'>, 'type' | 'file'>): SendElement =>
|
|
22
|
+
createSegment('image', { file, ...options }),
|
|
23
|
+
/** 创建一个语音消息片段 */
|
|
24
|
+
record: (file: string, options?: Omit<ExtractByType<SendElement, 'record'>, 'type' | 'file'>): SendElement =>
|
|
25
|
+
createSegment('record', { file, ...options }),
|
|
26
|
+
/** 创建一个视频消息片段 */
|
|
27
|
+
video: (file: string, options?: Omit<ExtractByType<SendElement, 'video'>, 'type' | 'file'>): SendElement =>
|
|
28
|
+
createSegment('video', { file, ...options }),
|
|
29
|
+
/** 创建一个动态表情消息片段 */
|
|
30
|
+
mface: (options: Omit<ExtractByType<SendElement, 'mface'>, 'type'>): SendElement =>
|
|
31
|
+
createSegment('mface', { ...options }),
|
|
32
|
+
/** 创建一个大表情消息片段 */
|
|
33
|
+
bface: (id: number): SendElement => createSegment('bface', { id }),
|
|
34
|
+
/** 创建一个 联系人/群 分享消息片段 */
|
|
35
|
+
contact: (type: 'qq' | 'group', id: string): SendElement => createSegment('contact', { id, sub_type: type }),
|
|
36
|
+
/** 创建一个戳一戳消息片段 */
|
|
37
|
+
poke: (): SendElement => createSegment('poke', {}),
|
|
38
|
+
/** 创建一个音乐消息片段 */
|
|
39
|
+
music: (platform: 'qq' | '163' | 'kugou' | 'migu' | 'kuwo', id: string): SendElement =>
|
|
40
|
+
createSegment('music', { platform, id }),
|
|
41
|
+
/** 创建一个自定义音乐消息片段 */
|
|
42
|
+
musicCustom: (
|
|
43
|
+
title: string,
|
|
44
|
+
audio: string,
|
|
45
|
+
url: string,
|
|
46
|
+
options?: Omit<ExtractByType<SendElement, 'music'>, 'type' | 'platform' | 'url' | 'audio' | 'title'>,
|
|
47
|
+
): SendElement => createSegment('music', { platform: 'custom', url, audio, title, ...options }),
|
|
48
|
+
/** 创建一个合并转发消息片段 */
|
|
49
|
+
forward: (id: string): SendElement => createSegment('forward', { id }),
|
|
50
|
+
/** 创建一个 JSON 消息片段 */
|
|
51
|
+
json: (data: string): SendElement => createSegment('json', { data }),
|
|
52
|
+
/** 创建一个文件消息片段 */
|
|
53
|
+
file: (file: string, options?: Omit<ExtractByType<SendElement, 'file'>, 'type' | 'file'>): SendElement =>
|
|
54
|
+
createSegment('file', { file, ...options }),
|
|
55
|
+
/** 创建一个 Markdown 消息片段 */
|
|
56
|
+
markdown: (): SendElement => createSegment('markdown', {}),
|
|
57
|
+
/** 创建一个轻应用消息片段 */
|
|
58
|
+
lightapp: (): SendElement => createSegment('lightapp', {}),
|
|
59
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Logger } from './logger'
|
|
2
|
+
import type { OneBotEventMap } from './onebot'
|
|
3
|
+
|
|
4
|
+
export interface MiokiOptions {
|
|
5
|
+
/** NapCat 访问令牌 */
|
|
6
|
+
token: string
|
|
7
|
+
/** NapCat 服务器协议,默认为 ws */
|
|
8
|
+
protocol?: 'ws' | 'wss'
|
|
9
|
+
/** NapCat 服务器主机,默认为 localhost */
|
|
10
|
+
host?: string
|
|
11
|
+
/** NapCat 服务器端口,默认为 3333 */
|
|
12
|
+
port?: number
|
|
13
|
+
/** 日志记录器,默认为控制台日志记录器 */
|
|
14
|
+
logger?: Logger
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type OptionalKeys<T> = {
|
|
18
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? K : never
|
|
19
|
+
}[keyof T]
|
|
20
|
+
|
|
21
|
+
export type OptionalProps<T> = Pick<T, OptionalKeys<T>>
|
|
22
|
+
|
|
23
|
+
export type ExtractByType<T, K> = T extends { type: K } ? T : never
|
|
24
|
+
|
|
25
|
+
export interface EventMap extends OneBotEventMap {
|
|
26
|
+
/** WebSocket 连接已打开 */
|
|
27
|
+
'ws.open': void
|
|
28
|
+
/** WebSocket 连接已关闭 */
|
|
29
|
+
'ws.close': void
|
|
30
|
+
/** WebSocket 连接发生错误 */
|
|
31
|
+
'ws.error': Event
|
|
32
|
+
/** 收到 WebSocket 消息 */
|
|
33
|
+
'ws.message': any
|
|
34
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -1,28 +1,3 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
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
|
-
}
|
|
2
|
+
"extends": "../../tsconfig.json"
|
|
28
3
|
}
|
package/tsdown.config.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { defineConfig } from 'tsdown'
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
entry: ['./src/index.ts'],
|
|
5
|
+
dts: true,
|
|
6
|
+
sourcemap: true,
|
|
7
|
+
target: 'node24',
|
|
8
|
+
treeshake: true,
|
|
9
|
+
tsconfig: './tsconfig.json',
|
|
10
|
+
format: ['cjs', 'esm'],
|
|
11
|
+
failOnWarn: false,
|
|
12
|
+
})
|
package/bun.lock
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
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
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const name = 'napcat-sdk'
|
package/index.ts
DELETED
|
@@ -1,195 +0,0 @@
|
|
|
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/readme.md
DELETED