Skip to content

Commit 7b4e617

Browse files
committed
[add] Lark document copy API & JWT verifier middleware
[optimize] update Upstream packages [migrate] upgrade Lark notification to Interactive Card
1 parent bd3e9a1 commit 7b4e617

File tree

9 files changed

+747
-617
lines changed

9 files changed

+747
-617
lines changed

.github/scripts/transform-message.ts

Lines changed: 193 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ type GitHubSchema = components['schemas'];
55

66
type GitHubUser = GitHubSchema['simple-user'];
77

8-
interface GitHubAction
9-
extends Record<'event_name' | 'actor' | 'server_url' | 'repository', string> {
8+
interface GitHubAction extends Record<
9+
'event_name' | 'actor' | 'server_url' | 'repository',
10+
string
11+
> {
1012
action?: string;
1113
ref?: string;
1214
ref_name?: string;
@@ -21,34 +23,68 @@ interface GitHubAction
2123
}
2224

2325
// Helper functions
26+
const ACTION_TEXT_MAP: Record<string, string> = {
27+
created: '创建',
28+
opened: '创建',
29+
submitted: '创建',
30+
closed: '关闭',
31+
reopened: '重新打开',
32+
labeled: '添加标签',
33+
unlabeled: '移除标签',
34+
assigned: '指派',
35+
unassigned: '取消指派',
36+
edited: '编辑',
37+
deleted: '删除',
38+
synchronize: '更新',
39+
review_requested: '请求审核',
40+
};
41+
2442
const getActionText = (action?: string) =>
25-
action === 'closed' ? '关闭' : action?.includes('open') ? '打开' : '编辑';
43+
action ? ACTION_TEXT_MAP[action] || action : '编辑';
2644

27-
const createLink = (href: string, text = href) => ({ tag: 'a', href, text });
45+
const createLink = (href: string, text = href) => `[${text}](${href})`;
2846

29-
const createText = (text: string) => ({ tag: 'text', text });
47+
const createUserLink = (user: any) =>
48+
user ? createLink(user.html_url, user.login) : '无';
3049

31-
// create user link
32-
const createUserLink = (user: GitHubUser) =>
33-
user ? createLink(user.html_url, user.login) : createText('无');
50+
// Convert GitHub markdown to Lark card supported format
51+
const sanitizeMarkdown = (text: string): string =>
52+
text
53+
// Remove code blocks
54+
.replace(/```[\s\S]*?```/g, '[代码块]')
55+
// Remove inline code
56+
.replace(/`[^`]+`/g, match => match.slice(1, -1))
57+
// Convert images to link text
58+
.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '🖼️ [$1]($2)')
59+
// Convert ### headers to bold
60+
.replace(/^###\s+(.+)$/gm, '**$1**')
61+
// Convert ## headers to bold
62+
.replace(/^##\s+(.+)$/gm, '**$1**')
63+
// Convert # headers to bold
64+
.replace(/^#\s+(.+)$/gm, '**$1**')
65+
// Remove HTML comments
66+
.replace(/<!--[\s\S]*?-->/g, '')
67+
// Remove HTML tags (keep content)
68+
.replace(/<[^>]+>/g, '')
69+
// Remove excess empty lines
70+
.replace(/\n{3,}/g, '\n\n')
71+
// Truncate long content
72+
.slice(0, 800) + (text.length > 800 ? '\n...' : '');
3473

35-
const createContentItem = (
36-
label: string,
37-
value?: string | { tag: string; text: string },
38-
) =>
39-
[
40-
createText(label),
41-
typeof value === 'string'
42-
? createText(value || '无')
43-
: value || createText('无'),
44-
] as [object, object];
74+
const createContentItem = (label: string, value?: string) =>
75+
`**${label}** ${value ? sanitizeMarkdown(value) : '无'}`;
76+
77+
interface LarkMessageElement {
78+
tag: string;
79+
content: string | [object, object][];
80+
}
4581

4682
type EventHandler = (
4783
event: GitHubAction,
4884
actionText: string,
4985
) => {
5086
title: string;
51-
content: [object, object][];
87+
elements: LarkMessageElement[];
5288
};
5389

5490
// Event handlers
@@ -60,109 +96,159 @@ const eventHandlers: Record<string, EventHandler> = {
6096
server_url,
6197
repository,
6298
actor,
63-
}) => ({
64-
title: 'GitHub 代码提交',
65-
content: [
66-
[createText('提交链接:'), createLink(head_commit!.url)],
67-
[
68-
createText('代码分支:'),
69-
createLink(`${server_url}/${repository}/tree/${ref_name}`, ref),
99+
}) => {
100+
const commitUrl =
101+
head_commit?.url || `${server_url}/${repository}/tree/${ref_name}`;
102+
const commitMessage =
103+
head_commit?.message || 'Create/Delete/Update Branch (No head commit)';
104+
105+
return {
106+
title: 'GitHub 代码提交',
107+
elements: [
108+
{
109+
tag: 'markdown',
110+
content: [
111+
createContentItem('提交链接:', createLink(commitUrl)),
112+
createContentItem(
113+
'代码分支:',
114+
createLink(
115+
`${server_url}/${repository}/tree/${ref_name}`,
116+
ref_name,
117+
),
118+
),
119+
createContentItem(
120+
'提交作者:',
121+
createLink(`${server_url}/${actor}`, actor),
122+
),
123+
createContentItem('提交信息:', commitMessage),
124+
].join('\n'),
125+
},
70126
],
71-
[createText('提交作者:'), createLink(`${server_url}/${actor}`, actor)],
72-
[createText('提交信息:'), createText(head_commit!.message)],
73-
],
74-
}),
127+
};
128+
},
75129

76130
issues: ({ event: { issue } }, actionText) => ({
77131
title: `GitHub issue ${actionText}${issue?.title}`,
78-
content: [
79-
[createText('链接:'), createLink(issue!.html_url)],
80-
[
81-
createText('作者:'),
82-
createLink(issue!.user!.html_url!, issue!.user!.login),
83-
],
84-
[
85-
createText('指派:'),
86-
issue?.assignee
87-
? createLink(issue.assignee.html_url!, issue.assignee.login)
88-
: createText('无'),
89-
],
90-
[
91-
createText('标签:'),
92-
createText(issue?.labels?.map(({ name }) => name).join(', ') || '无'),
93-
],
94-
[createText('里程碑:'), createText(issue?.milestone?.title || '无')],
95-
[createText('描述:'), createText(issue?.body || '无')],
132+
elements: [
133+
{
134+
tag: 'markdown',
135+
content: [
136+
createContentItem('链接:', createLink(issue!.html_url)),
137+
createContentItem('作者:', createUserLink(issue!.user!)),
138+
createContentItem(
139+
'指派:',
140+
issue?.assignee ? createUserLink(issue.assignee) : '无',
141+
),
142+
createContentItem(
143+
'标签:',
144+
issue?.labels?.map(({ name }) => name).join(', ') || '无',
145+
),
146+
createContentItem('里程碑:', issue?.milestone?.title || '无'),
147+
createContentItem('描述:', issue?.body || '无'),
148+
].join('\n'),
149+
},
96150
],
97151
}),
98152

99153
pull_request: ({ event: { pull_request } }, actionText) => ({
100154
title: `GitHub PR ${actionText}${pull_request?.title}`,
101-
content: [
102-
[createText('链接:'), createLink(pull_request!.html_url)],
103-
[
104-
createText('作者:'),
105-
createLink(pull_request!.user.html_url, pull_request!.user.login),
106-
],
107-
[
108-
createText('指派:'),
109-
pull_request?.assignee
110-
? createLink(
111-
pull_request.assignee.html_url,
112-
pull_request.assignee.login,
113-
)
114-
: createText('无'),
115-
],
116-
[
117-
createText('标签:'),
118-
createText(
119-
pull_request?.labels?.map(({ name }) => name).join(', ') || '无',
120-
),
121-
],
122-
[
123-
createText('里程碑:'),
124-
createText(pull_request?.milestone?.title || '无'),
125-
],
126-
[createText('描述:'), createText(pull_request?.body || '无')],
155+
elements: [
156+
{
157+
tag: 'markdown',
158+
content: [
159+
createContentItem('链接:', createLink(pull_request!.html_url)),
160+
createContentItem('作者:', createUserLink(pull_request!.user)),
161+
createContentItem(
162+
'指派:',
163+
pull_request?.assignee
164+
? createUserLink(pull_request.assignee)
165+
: '无',
166+
),
167+
createContentItem(
168+
'标签:',
169+
pull_request?.labels?.map(({ name }) => name).join(', ') || '无',
170+
),
171+
createContentItem('里程碑:', pull_request?.milestone?.title || '无'),
172+
createContentItem('描述:', pull_request?.body || '无'),
173+
].join('\n'),
174+
},
127175
],
128176
}),
129177

130178
discussion: ({ event: { discussion } }, actionText) => ({
131179
title: `GitHub 讨论 ${actionText}${discussion?.title || '无'}`,
132-
content: [
133-
createContentItem('链接:', discussion?.html_url),
134-
createContentItem(
135-
'作者:',
136-
createUserLink(discussion!.user as GitHubUser),
137-
),
138-
createContentItem('描述:', discussion?.body || '无'),
180+
elements: [
181+
{
182+
tag: 'markdown',
183+
content: [
184+
createContentItem('链接:', createLink(discussion!.html_url)),
185+
createContentItem(
186+
'作者:',
187+
createUserLink(discussion!.user as GitHubUser),
188+
),
189+
createContentItem('描述:', discussion?.body || '无'),
190+
].join('\n'),
191+
},
139192
],
140193
}),
141194

142195
issue_comment: ({ event: { comment, issue } }) => ({
143196
title: `GitHub issue 评论:${issue?.title || '未知 issue'}`,
144-
content: [
145-
createContentItem('链接:', comment?.html_url),
146-
createContentItem('作者:', createUserLink(comment!.user!)),
147-
createContentItem('描述:', comment?.body || '无'),
197+
elements: [
198+
{
199+
tag: 'markdown',
200+
content: [
201+
createContentItem('链接:', createLink(comment!.html_url)),
202+
createContentItem('作者:', createUserLink(comment!.user!)),
203+
createContentItem('描述:', comment?.body || '无'),
204+
].join('\n'),
205+
},
148206
],
149207
}),
150208

151209
discussion_comment: ({ event: { comment, discussion } }) => ({
152210
title: `GitHub 讨论评论:${discussion?.title || '无'}`,
153-
content: [
154-
createContentItem('链接:', comment?.html_url),
155-
createContentItem('作者:', createUserLink(comment!.user!)),
156-
createContentItem('描述:', comment?.body || '无'),
211+
elements: [
212+
{
213+
tag: 'markdown',
214+
content: [
215+
createContentItem('链接:', createLink(comment!.html_url)),
216+
createContentItem('作者:', createUserLink(comment!.user!)),
217+
createContentItem('描述:', comment?.body || '无'),
218+
].join('\n'),
219+
},
157220
],
158221
}),
159222

160223
release: ({ event: { release } }) => ({
161224
title: `GitHub Release 发布:${release!.name || release!.tag_name}`,
162-
content: [
163-
createContentItem('链接:', release!.html_url),
164-
createContentItem('作者:', createUserLink(release!.author)),
165-
createContentItem('描述:', release!.body!),
225+
elements: [
226+
{
227+
tag: 'markdown',
228+
content: [
229+
createContentItem('链接:', createLink(release!.html_url)),
230+
createContentItem('作者:', createUserLink(release!.author)),
231+
createContentItem('描述:', release?.body || '无'),
232+
].join('\n'),
233+
},
234+
],
235+
}),
236+
237+
pull_request_review_comment: ({ event: { comment, pull_request } }) => ({
238+
title: `GitHub PR 代码评论:${pull_request?.title || '未知 PR'}`,
239+
elements: [
240+
{
241+
tag: 'markdown',
242+
content: [
243+
createContentItem('链接:', createLink(comment!.html_url)),
244+
createContentItem('作者:', createUserLink(comment!.user!)),
245+
createContentItem(
246+
'PR:',
247+
createLink(pull_request!.html_url, `#${pull_request!.number}`),
248+
),
249+
createContentItem('评论:', comment?.body || '无'),
250+
].join('\n'),
251+
},
166252
],
167253
}),
168254
};
@@ -185,12 +271,22 @@ const processEvent = (event: GitHubAction) => {
185271
}
186272
};
187273

188-
// Main execution:Processing GitHub Events and Outputting Results
274+
// Main execution
189275
const event = JSON.parse((await stdin()) || '{}') as GitHubAction;
190-
const zh_cn = processEvent(event);
276+
const result = processEvent(event);
191277

192-
if (zh_cn) console.log(JSON.stringify({ post: { zh_cn } }));
193-
else
278+
if (!result)
194279
throw new Error(
195280
`Unsupported ${event.event_name} event & ${event.action} action`,
196281
);
282+
283+
const card = {
284+
schema: '2.0',
285+
config: { wide_screen_mode: true },
286+
header: {
287+
title: { tag: 'plain_text', content: result.title },
288+
template: 'blue',
289+
},
290+
body: { elements: result.elements },
291+
};
292+
console.log(JSON.stringify(card));

0 commit comments

Comments
 (0)