@@ -19,7 +19,7 @@ import {
1919 isClosedPR ,
2020} from "../utils/validation.js" ;
2121import { ALLOWED_REPO } from "../utils/constants.js" ;
22- import { performAIReview } from "../utils/prReview.js" ;
22+ import { performAIReview , addReactionToComment } from "../utils/prReview.js" ;
2323
2424/**
2525 * GitHub webhook 이벤트 처리
@@ -249,6 +249,26 @@ async function handlePullRequestEvent(payload, env) {
249249 } ) ;
250250}
251251
252+ /**
253+ * 댓글에서 @dalestudy 멘션과 사용자 요청 추출
254+ *
255+ * @param {string } commentBody - 댓글 내용
256+ * @returns {Object|null } { isMentioned, userRequest } 또는 null
257+ */
258+ function extractMentionAndRequest ( commentBody ) {
259+ const lowerBody = commentBody . toLowerCase ( ) ;
260+ const isMentioned = lowerBody . includes ( "@dalestudy" ) ;
261+
262+ if ( ! isMentioned ) {
263+ return null ;
264+ }
265+
266+ const mentionMatch = commentBody . match ( / @ d a l e s t u d y \s * ( .* ) / i) ;
267+ const userRequest = mentionMatch && mentionMatch [ 1 ] . trim ( ) ? mentionMatch [ 1 ] . trim ( ) : null ;
268+
269+ return { isMentioned : true , userRequest } ;
270+ }
271+
252272/**
253273 * Issue Comment 이벤트 처리 (AI 코드 리뷰 요청)
254274 */
@@ -276,21 +296,14 @@ async function handleIssueCommentEvent(payload, env) {
276296
277297 const prNumber = issue . number ;
278298
279- // 멘션 감지: @dalestudy만 체크
280- const commentBody = comment . body ;
281- const lowerBody = commentBody . toLowerCase ( ) ;
282- const isMentioned = lowerBody . includes ( "@dalestudy" ) ;
283-
284- if ( ! isMentioned ) {
299+ // 멘션 감지 및 사용자 요청 추출
300+ const mention = extractMentionAndRequest ( comment . body ) ;
301+ if ( ! mention ) {
285302 console . log ( "Ignoring: bot not mentioned" ) ;
286303 return corsResponse ( { message : "Ignored: not mentioned" } ) ;
287304 }
288305
289- // 멘션 뒤의 텍스트 추출
290- const mentionMatch = commentBody . match ( / @ d a l e s t u d y \s * ( .* ) / i) ;
291- const userRequest = mentionMatch && mentionMatch [ 1 ] . trim ( ) ? mentionMatch [ 1 ] . trim ( ) : null ;
292-
293- console . log ( `AI review requested for PR #${ prNumber } ${ userRequest ? ` - Request: ${ userRequest } ` : "" } ` ) ;
306+ console . log ( `AI review requested for PR #${ prNumber } ${ mention . userRequest ? ` - Request: ${ mention . userRequest } ` : "" } ` ) ;
294307
295308 // OPENAI_API_KEY 확인
296309 if ( ! env . OPENAI_API_KEY ) {
@@ -303,13 +316,13 @@ async function handleIssueCommentEvent(payload, env) {
303316 const appToken = await generateGitHubAppToken ( env ) ;
304317
305318 // 👀 reaction 추가 (리뷰 시작 알림)
306- await fetch (
307- `https://api.github.com/repos/ ${ repoOwner } / ${ repoName } /issues/comments/ ${ comment . id } /reactions` ,
308- {
309- method : "POST" ,
310- headers : getGitHubHeaders ( appToken ) ,
311- body : JSON . stringify ( { content : "eyes" } ) ,
312- }
319+ await addReactionToComment (
320+ repoOwner ,
321+ repoName ,
322+ comment . id ,
323+ "issue" ,
324+ "eyes" ,
325+ appToken
313326 ) ;
314327
315328 await performAIReview (
@@ -319,7 +332,8 @@ async function handleIssueCommentEvent(payload, env) {
319332 issue . title ,
320333 issue . body ,
321334 appToken ,
322- env . OPENAI_API_KEY
335+ env . OPENAI_API_KEY ,
336+ mention . userRequest
323337 ) ;
324338
325339 console . log ( `AI review completed for PR #${ prNumber } ` ) ;
@@ -354,16 +368,14 @@ async function handlePullRequestReviewCommentEvent(payload, env) {
354368 const repoName = payload . repository . name ;
355369 const prNumber = pullRequest . number ;
356370
357- // 멘션 감지: @dalestudy만 체크
358- const commentBody = comment . body . toLowerCase ( ) ;
359- const isMentioned = commentBody . includes ( "@dalestudy" ) ;
360-
361- if ( ! isMentioned ) {
371+ // 멘션 감지 및 사용자 요청 추출
372+ const mention = extractMentionAndRequest ( comment . body ) ;
373+ if ( ! mention ) {
362374 console . log ( "Ignoring: bot not mentioned" ) ;
363375 return corsResponse ( { message : "Ignored: not mentioned" } ) ;
364376 }
365377
366- console . log ( `AI review requested for PR #${ prNumber } (review comment)` ) ;
378+ console . log ( `AI review requested for PR #${ prNumber } (review comment)${ mention . userRequest ? ` - Request: ${ mention . userRequest } ` : "" } ` ) ;
367379
368380 // OPENAI_API_KEY 확인
369381 if ( ! env . OPENAI_API_KEY ) {
@@ -376,43 +388,26 @@ async function handlePullRequestReviewCommentEvent(payload, env) {
376388 const appToken = await generateGitHubAppToken ( env ) ;
377389
378390 // 👀 reaction 추가
379- await fetch (
380- `https://api.github.com/repos/ ${ repoOwner } / ${ repoName } /pulls/comments/ ${ comment . id } /reactions` ,
381- {
382- method : "POST" ,
383- headers : getGitHubHeaders ( appToken ) ,
384- body : JSON . stringify ( { content : "eyes" } ) ,
385- }
391+ await addReactionToComment (
392+ repoOwner ,
393+ repoName ,
394+ comment . id ,
395+ "pull" ,
396+ "eyes" ,
397+ appToken
386398 ) ;
387399
388- // AI 리뷰 생성
389- const { generateCodeReview } = await import ( "../utils/openai.js" ) ;
390- const { getPRDiff } = await import ( "../utils/prReview.js" ) ;
391-
392- const prDiff = await getPRDiff ( repoOwner , repoName , prNumber , appToken ) ;
393-
394- // diff가 너무 크면 스킵
395- const diffLines = prDiff . split ( "\n" ) . length ;
396- if ( diffLines > 1000 ) {
397- console . log ( `Skipping AI review: diff too large (${ diffLines } lines)` ) ;
398- return corsResponse ( { message : "Diff too large" } ) ;
399- }
400-
401- const reviewContent = await generateCodeReview (
402- prDiff ,
400+ // performAIReview 사용 (스레드 답변 모드)
401+ await performAIReview (
402+ repoOwner ,
403+ repoName ,
404+ prNumber ,
403405 pullRequest . title ,
404406 pullRequest . body ,
405- env . OPENAI_API_KEY
406- ) ;
407-
408- // 스레드 답변으로 작성
409- await fetch (
410- `https://api.github.com/repos/${ repoOwner } /${ repoName } /pulls/${ prNumber } /comments/${ comment . id } /replies` ,
411- {
412- method : "POST" ,
413- headers : getGitHubHeaders ( appToken ) ,
414- body : JSON . stringify ( { body : reviewContent } ) ,
415- }
407+ appToken ,
408+ env . OPENAI_API_KEY ,
409+ mention . userRequest ,
410+ comment . id // 스레드 답변으로 작성
416411 ) ;
417412
418413 console . log ( `AI review completed for PR #${ prNumber } (thread reply)` ) ;
0 commit comments