2121import org .sopt .makers .global .exception .message .ErrorMessage ;
2222import org .sopt .makers .global .exception .unchecked .HttpRequestException ;
2323import org .sopt .makers .global .util .HttpClientUtil ;
24- import org .sopt .makers .vo .slack .message .SlackMessage ;
2524import org .sopt .makers .vo .slack .block .ActionsBlock ;
2625import org .sopt .makers .vo .slack .block .Block ;
2726import org .sopt .makers .vo .slack .block .HeaderBlock ;
2827import org .sopt .makers .vo .slack .block .SectionBlock ;
2928import org .sopt .makers .vo .slack .element .Button ;
29+ import org .sopt .makers .vo .slack .message .SlackMessage ;
30+ import org .sopt .makers .vo .slack .text .MarkdownText ;
3031import org .sopt .makers .vo .slack .text .Text ;
3132
3233import com .fasterxml .jackson .databind .ObjectMapper ;
@@ -54,8 +55,8 @@ private SlackMessage createSlackMessage(String team, String type, String stage,
5455 try {
5556 return buildSlackMessage (team , type , stage , sentryEventDetail );
5657 } catch (DateTimeException e ) {
57- log .error ("Slack 메시지 생성 실패: team={}, type={}, stage={}, id={}, error={}" ,
58- team , type , stage , sentryEventDetail .issueId (), e .getMessage (), e );
58+ log .error ("Slack 메시지 생성 실패: team={}, type={}, stage={}, id={}, error={}" , team , type , stage ,
59+ sentryEventDetail .issueId (), e .getMessage (), e );
5960 throw SlackMessageBuildException .from (ErrorMessage .SLACK_MESSAGE_BUILD_FAILED );
6061 }
6162 }
@@ -74,17 +75,17 @@ private void sendSlackMessage(SlackMessage slackMessage, String webhookUrl, Stri
7475 }
7576 }
7677
77- private void handleSlackResponse (HttpResponse <String > response , String team , String type ,
78- String stage , SentryEventDetail sentryEventDetail ) throws SlackSendException {
78+ private void handleSlackResponse (HttpResponse <String > response , String team , String type , String stage ,
79+ SentryEventDetail sentryEventDetail ) throws SlackSendException {
7980 if (response .statusCode () != 200 || !"ok" .equalsIgnoreCase (response .body ())) {
80- String errorMsg = String .format ("Slack API 응답 오류, status: %d, body: %s" ,
81- response .statusCode (), response . body ());
81+ String errorMsg = String .format ("Slack API 응답 오류, status: %d, body: %s" , response . statusCode (),
82+ response .body ());
8283 log .error ("{}" , errorMsg );
8384 throw SlackSendException .from (ErrorMessage .SLACK_SEND_FAILED );
8485 }
8586
86- log .info ("[Slack 전송 완료] team={}, type={}, stage={}, id={}, statusCode={}" ,
87- team , type , stage , sentryEventDetail .issueId (), response .statusCode ());
87+ log .info ("[Slack 전송 완료] team={}, type={}, stage={}, id={}, statusCode={}" , team , type , stage ,
88+ sentryEventDetail .issueId (), response .statusCode ());
8889 }
8990
9091 /**
@@ -96,9 +97,10 @@ private SlackMessage buildSlackMessage(String team, String type, String stage,
9697 String color = Color .getColorByLevel (sentryEventDetail .level ());
9798
9899 List <Block > blocks = new ArrayList <>();
99- blocks .add (buildHeaderBlock (sentryEventDetail .level ()));
100- blocks .add (buildDetailsBlock (team , type , stage , formattedDate ));
101- blocks .add (buildMessageBlock (sentryEventDetail .message ()));
100+ blocks .add (buildHeaderBlock (sentryEventDetail .message ()));
101+ blocks .add (buildDetailsBlock (team , type , stage , formattedDate , sentryEventDetail .issueId (),
102+ sentryEventDetail .level ()));
103+ blocks .add (buildMessageBlock (sentryEventDetail .title ()));
102104 blocks .add (buildActionsBlock (sentryEventDetail .webUrl ()));
103105
104106 return SlackMessage .newInstance (blocks , color );
@@ -107,30 +109,36 @@ private SlackMessage buildSlackMessage(String team, String type, String stage,
107109 /**
108110 * 헤더 블록 구성
109111 */
110- private Block buildHeaderBlock (String level ) {
111- return HeaderBlock .newInstance (String . format ( "[%s] 오류 발생" , level . toUpperCase ()) );
112+ private Block buildHeaderBlock (String message ) {
113+ return HeaderBlock .newInstance (message );
112114 }
113115
114116 /**
115117 * 상세 정보 블록 구성
116118 */
117- private SectionBlock buildDetailsBlock (String team , String type , String stage , String date ) {
118- List <Text > fields = List .of (
119- Text .newFieldInstance (String .format ("*환경:*%s%s" , NEW_LINE , stage )),
120- Text .newFieldInstance (String .format ("*팀:*%s%s" , NEW_LINE , team )),
121- Text .newFieldInstance (String .format ("*유형:*%s%s" , NEW_LINE , type )),
122- Text .newFieldInstance (String .format ("*발생 시간:*%s%s" , NEW_LINE , date ))
123- );
119+ private Block buildDetailsBlock (String team , String type , String stage , String date , String issueId , String level ) {
120+ List <Text > fields = List .of (MarkdownText .newInstance (String .format ("*Environment:*%s%s" , NEW_LINE , stage )),
121+ MarkdownText .newInstance (String .format ("*Team:*%s%s" , NEW_LINE , team )),
122+ MarkdownText .newInstance (String .format ("*Server Type:*%s%s" , NEW_LINE , type )),
123+ MarkdownText .newInstance (String .format ("*Issue Id:*%s%s" , NEW_LINE , issueId )),
124+ MarkdownText .newInstance (String .format ("*Happen:*%s%s" , NEW_LINE , date )),
125+ MarkdownText .newInstance (String .format ("*Level:*%s%s" , NEW_LINE , level )));
126+
124127 return SectionBlock .newInstanceWithFields (fields );
125128 }
126129
127130 /**
128131 * 메시지 블록 구성
129132 */
130- private Block buildMessageBlock (String message ) {
131- return SectionBlock .newInstanceWithText (
132- Text .newFieldInstance (String .format ("*오류 메시지:*%s%s" , NEW_LINE , message ))
133- );
133+ private Block buildMessageBlock (String title ) {
134+ Text text = MarkdownText .newInstance ("""
135+ *Error Details:*
136+ ```
137+ %s
138+ ```
139+ """ .formatted (title .trim ()));
140+
141+ return SectionBlock .newInstanceWithText (text );
134142 }
135143
136144 /**
@@ -145,8 +153,7 @@ private Block buildActionsBlock(String webUrl) {
145153 */
146154 private String formatDateTime (String isoDatetime ) {
147155 OffsetDateTime utcTime = OffsetDateTime .parse (isoDatetime , DateTimeFormatter .ISO_DATE_TIME );
148- LocalDateTime koreaTime = utcTime .atZoneSameInstant (ZoneId .of (TIMEZONE_SEOUL ))
149- .toLocalDateTime ();
156+ LocalDateTime koreaTime = utcTime .atZoneSameInstant (ZoneId .of (TIMEZONE_SEOUL )).toLocalDateTime ();
150157 return koreaTime .format (DateTimeFormatter .ofPattern (DATE_FORMAT_PATTERN ));
151158 }
152159}
0 commit comments