@@ -5,8 +5,10 @@ type GitHubSchema = components['schemas'];
55
66type 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+
2442const 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
4682type 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
189275const 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