@@ -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,113 +23,201 @@ interface GitHubAction
2123}
2224
2325// Helper functions
24- const getActionText = ( action ?: string ) =>
25- action === 'closed' ? '关闭' : action ?. includes ( 'open' ) ? '打开' : '编辑' ;
26-
27- const createLink = ( href : string , text = href ) => ( { tag : 'a' , href, text } ) ;
28-
29- const createText = ( text : string ) => ( { tag : 'text' , text } ) ;
30-
31- // create user link
32- const createUserLink = ( user : GitHubUser ) =>
33- user ? createLink ( user . html_url , user . login ) : createText ( '无' ) ;
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+ } ;
3441
35- const createContentItem = ( label : string , value ?: string | { tag : string ; text : string } ) =>
36- [
37- createText ( label ) ,
38- typeof value === 'string' ? createText ( value || '无' ) : value || createText ( '无' ) ,
39- ] as [ object , object ] ;
42+ const getActionText = ( action ?: string ) => ( action ? ACTION_TEXT_MAP [ action ] || action : '编辑' ) ;
43+
44+ const createLink = ( href : string , text = href ) => `[${ text } ](${ href } )` ;
45+
46+ const createUserLink = ( user : any ) => ( user ? createLink ( user . html_url , user . login ) : '无' ) ;
47+
48+ // Convert GitHub markdown to Lark card supported format
49+ const sanitizeMarkdown = ( text : string ) : string =>
50+ text
51+ // Remove code blocks
52+ . replace ( / ` ` ` [ \s \S ] * ?` ` ` / g, '[代码块]' )
53+ // Remove inline code
54+ . replace ( / ` [ ^ ` ] + ` / g, match => match . slice ( 1 , - 1 ) )
55+ // Convert images to link text
56+ . replace ( / ! \[ ( [ ^ \] ] * ) \] \( ( [ ^ ) ] + ) \) / g, '🖼️ [$1]($2)' )
57+ // Convert ### headers to bold
58+ . replace ( / ^ # # # \s + ( .+ ) $ / gm, '**$1**' )
59+ // Convert ## headers to bold
60+ . replace ( / ^ # # \s + ( .+ ) $ / gm, '**$1**' )
61+ // Convert # headers to bold
62+ . replace ( / ^ # \s + ( .+ ) $ / gm, '**$1**' )
63+ // Remove HTML comments
64+ . replace ( / < ! - - [ \s \S ] * ?- - > / g, '' )
65+ // Remove HTML tags (keep content)
66+ . replace ( / < [ ^ > ] + > / g, '' )
67+ // Remove excess empty lines
68+ . replace ( / \n { 3 , } / g, '\n\n' )
69+ // Truncate long content
70+ . slice ( 0 , 800 ) + ( text . length > 800 ? '\n...' : '' ) ;
71+
72+ const createContentItem = ( label : string , value ?: string ) =>
73+ `**${ label } ** ${ value ? sanitizeMarkdown ( value ) : '无' } ` ;
74+
75+ interface LarkMessageElement {
76+ tag : string ;
77+ content : string | [ object , object ] [ ] ;
78+ }
4079
4180type EventHandler = (
4281 event : GitHubAction ,
4382 actionText : string ,
4483) => {
4584 title : string ;
46- content : [ object , object ] [ ] ;
85+ elements : LarkMessageElement [ ] ;
4786} ;
4887
4988// Event handlers
5089const eventHandlers : Record < string , EventHandler > = {
51- push : ( { event : { head_commit } , ref, ref_name, server_url, repository, actor } ) => ( {
52- title : 'GitHub 代码提交' ,
53- content : [
54- [ createText ( '提交链接:' ) , createLink ( head_commit ! . url ) ] ,
55- [ createText ( '代码分支:' ) , createLink ( `${ server_url } /${ repository } /tree/${ ref_name } ` , ref ) ] ,
56- [ createText ( '提交作者:' ) , createLink ( `${ server_url } /${ actor } ` , actor ) ] ,
57- [ createText ( '提交信息:' ) , createText ( head_commit ! . message ) ] ,
58- ] ,
59- } ) ,
90+ push : ( { event : { head_commit } , ref, ref_name, server_url, repository, actor } ) => {
91+ const commitUrl = head_commit ?. url || `${ server_url } /${ repository } /tree/${ ref_name } ` ;
92+ const commitMessage = head_commit ?. message || 'Create/Delete/Update Branch (No head commit)' ;
93+
94+ return {
95+ title : 'GitHub 代码提交' ,
96+ elements : [
97+ {
98+ tag : 'markdown' ,
99+ content : [
100+ createContentItem ( '提交链接:' , createLink ( commitUrl ) ) ,
101+ createContentItem (
102+ '代码分支:' ,
103+ createLink ( `${ server_url } /${ repository } /tree/${ ref_name } ` , ref_name ) ,
104+ ) ,
105+ createContentItem ( '提交作者:' , createLink ( `${ server_url } /${ actor } ` , actor ) ) ,
106+ createContentItem ( '提交信息:' , commitMessage ) ,
107+ ] . join ( '\n' ) ,
108+ } ,
109+ ] ,
110+ } ;
111+ } ,
60112
61113 issues : ( { event : { issue } } , actionText ) => ( {
62114 title : `GitHub issue ${ actionText } :${ issue ?. title } ` ,
63- content : [
64- [ createText ( '链接:' ) , createLink ( issue ! . html_url ) ] ,
65- [ createText ( '作者:' ) , createLink ( issue ! . user ! . html_url ! , issue ! . user ! . login ) ] ,
66- [
67- createText ( '指派:' ) ,
68- issue ?. assignee
69- ? createLink ( issue . assignee . html_url ! , issue . assignee . login )
70- : createText ( '无' ) ,
71- ] ,
72- [ createText ( '标签:' ) , createText ( issue ?. labels ?. map ( ( { name } ) => name ) . join ( ', ' ) || '无' ) ] ,
73- [ createText ( '里程碑:' ) , createText ( issue ?. milestone ?. title || '无' ) ] ,
74- [ createText ( '描述:' ) , createText ( issue ?. body || '无' ) ] ,
115+ elements : [
116+ {
117+ tag : 'markdown' ,
118+ content : [
119+ createContentItem ( '链接:' , createLink ( issue ! . html_url ) ) ,
120+ createContentItem ( '作者:' , createUserLink ( issue ! . user ! ) ) ,
121+ createContentItem ( '指派:' , issue ? .assignee ? createUserLink ( issue . assignee ) : '无' ) ,
122+ createContentItem ( '标签:' , issue ?. labels ?. map ( ( { name } ) => name ) . join ( ', ' ) || '无' ) ,
123+ createContentItem ( '里程碑:' , issue ?. milestone ?. title || '无' ) ,
124+ createContentItem ( '描述:' , issue ?. body || '无' ) ,
125+ ] . join ( '\n' ) ,
126+ } ,
75127 ] ,
76128 } ) ,
77129
78130 pull_request : ( { event : { pull_request } } , actionText ) => ( {
79131 title : `GitHub PR ${ actionText } :${ pull_request ?. title } ` ,
80- content : [
81- [ createText ( '链接:' ) , createLink ( pull_request ! . html_url ) ] ,
82- [ createText ( '作者:' ) , createLink ( pull_request ! . user . html_url , pull_request ! . user . login ) ] ,
83- [
84- createText ( '指派:' ) ,
85- pull_request ?. assignee
86- ? createLink ( pull_request . assignee . html_url , pull_request . assignee . login )
87- : createText ( '无' ) ,
88- ] ,
89- [
90- createText ( '标签:' ) ,
91- createText ( pull_request ?. labels ?. map ( ( { name } ) => name ) . join ( ', ' ) || '无' ) ,
92- ] ,
93- [ createText ( '里程碑:' ) , createText ( pull_request ?. milestone ?. title || '无' ) ] ,
94- [ createText ( '描述:' ) , createText ( pull_request ?. body || '无' ) ] ,
132+ elements : [
133+ {
134+ tag : 'markdown' ,
135+ content : [
136+ createContentItem ( '链接:' , createLink ( pull_request ! . html_url ) ) ,
137+ createContentItem ( '作者:' , createUserLink ( pull_request ! . user ) ) ,
138+ createContentItem (
139+ '指派:' ,
140+ pull_request ?. assignee ? createUserLink ( pull_request . assignee ) : '无' ,
141+ ) ,
142+ createContentItem (
143+ '标签:' ,
144+ pull_request ?. labels ?. map ( ( { name } ) => name ) . join ( ', ' ) || '无' ,
145+ ) ,
146+ createContentItem ( '里程碑:' , pull_request ?. milestone ?. title || '无' ) ,
147+ createContentItem ( '描述:' , pull_request ?. body || '无' ) ,
148+ ] . join ( '\n' ) ,
149+ } ,
95150 ] ,
96151 } ) ,
97152
98153 discussion : ( { event : { discussion } } , actionText ) => ( {
99154 title : `GitHub 讨论 ${ actionText } :${ discussion ?. title || '无' } ` ,
100- content : [
101- createContentItem ( '链接:' , discussion ?. html_url ) ,
102- createContentItem ( '作者:' , createUserLink ( discussion ! . user as GitHubUser ) ) ,
103- createContentItem ( '描述:' , discussion ?. body || '无' ) ,
155+ elements : [
156+ {
157+ tag : 'markdown' ,
158+ content : [
159+ createContentItem ( '链接:' , createLink ( discussion ! . html_url ) ) ,
160+ createContentItem ( '作者:' , createUserLink ( discussion ! . user as GitHubUser ) ) ,
161+ createContentItem ( '描述:' , discussion ?. body || '无' ) ,
162+ ] . join ( '\n' ) ,
163+ } ,
104164 ] ,
105165 } ) ,
106166
107167 issue_comment : ( { event : { comment, issue } } ) => ( {
108168 title : `GitHub issue 评论:${ issue ?. title || '未知 issue' } ` ,
109- content : [
110- createContentItem ( '链接:' , comment ?. html_url ) ,
111- createContentItem ( '作者:' , createUserLink ( comment ! . user ! ) ) ,
112- createContentItem ( '描述:' , comment ?. body || '无' ) ,
169+ elements : [
170+ {
171+ tag : 'markdown' ,
172+ content : [
173+ createContentItem ( '链接:' , createLink ( comment ! . html_url ) ) ,
174+ createContentItem ( '作者:' , createUserLink ( comment ! . user ! ) ) ,
175+ createContentItem ( '描述:' , comment ?. body || '无' ) ,
176+ ] . join ( '\n' ) ,
177+ } ,
113178 ] ,
114179 } ) ,
115180
116181 discussion_comment : ( { event : { comment, discussion } } ) => ( {
117182 title : `GitHub 讨论评论:${ discussion ?. title || '无' } ` ,
118- content : [
119- createContentItem ( '链接:' , comment ?. html_url ) ,
120- createContentItem ( '作者:' , createUserLink ( comment ! . user ! ) ) ,
121- createContentItem ( '描述:' , comment ?. body || '无' ) ,
183+ elements : [
184+ {
185+ tag : 'markdown' ,
186+ content : [
187+ createContentItem ( '链接:' , createLink ( comment ! . html_url ) ) ,
188+ createContentItem ( '作者:' , createUserLink ( comment ! . user ! ) ) ,
189+ createContentItem ( '描述:' , comment ?. body || '无' ) ,
190+ ] . join ( '\n' ) ,
191+ } ,
122192 ] ,
123193 } ) ,
124194
125195 release : ( { event : { release } } ) => ( {
126196 title : `GitHub Release 发布:${ release ! . name || release ! . tag_name } ` ,
127- content : [
128- createContentItem ( '链接:' , release ! . html_url ) ,
129- createContentItem ( '作者:' , createUserLink ( release ! . author ) ) ,
130- createContentItem ( '描述:' , release ! . body ! ) ,
197+ elements : [
198+ {
199+ tag : 'markdown' ,
200+ content : [
201+ createContentItem ( '链接:' , createLink ( release ! . html_url ) ) ,
202+ createContentItem ( '作者:' , createUserLink ( release ! . author ) ) ,
203+ createContentItem ( '描述:' , release ?. body || '无' ) ,
204+ ] . join ( '\n' ) ,
205+ } ,
206+ ] ,
207+ } ) ,
208+
209+ pull_request_review_comment : ( { event : { comment, pull_request } } ) => ( {
210+ title : `GitHub PR 代码评论:${ pull_request ?. title || '未知 PR' } ` ,
211+ elements : [
212+ {
213+ tag : 'markdown' ,
214+ content : [
215+ createContentItem ( '链接:' , createLink ( comment ! . html_url ) ) ,
216+ createContentItem ( '作者:' , createUserLink ( comment ! . user ! ) ) ,
217+ createContentItem ( 'PR:' , createLink ( pull_request ! . html_url , `#${ pull_request ! . number } ` ) ) ,
218+ createContentItem ( '评论:' , comment ?. body || '无' ) ,
219+ ] . join ( '\n' ) ,
220+ } ,
131221 ] ,
132222 } ) ,
133223} ;
@@ -147,9 +237,19 @@ const processEvent = (event: GitHubAction) => {
147237 }
148238} ;
149239
150- // Main execution:Processing GitHub Events and Outputting Results
240+ // Main execution
151241const event = JSON . parse ( ( await stdin ( ) ) || '{}' ) as GitHubAction ;
152- const zh_cn = processEvent ( event ) ;
153-
154- if ( zh_cn ) console . log ( JSON . stringify ( { post : { zh_cn } } ) ) ;
155- else throw new Error ( `Unsupported ${ event . event_name } event & ${ event . action } action` ) ;
242+ const result = processEvent ( event ) ;
243+
244+ if ( ! result ) throw new Error ( `Unsupported ${ event . event_name } event & ${ event . action } action` ) ;
245+
246+ const card = {
247+ schema : '2.0' ,
248+ config : { wide_screen_mode : true } ,
249+ header : {
250+ title : { tag : 'plain_text' , content : result . title } ,
251+ template : 'blue' ,
252+ } ,
253+ body : { elements : result . elements } ,
254+ } ;
255+ console . log ( JSON . stringify ( card ) ) ;
0 commit comments