44 pull_request :
55 types : [opened, reopened]
66 issue_comment :
7- types : [created]
7+ types : [created, edited ]
88 pull_request_review_comment :
9- types : [created]
9+ types : [created, edited ]
1010
1111jobs :
1212 notify-slack :
2222 SLACK_BOT_TOKEN : ${{ secrets.SLACK_BOT_TOKEN }}
2323 SLACK_CHANNEL_ID : ${{ secrets.SLACK_CHANNEL_ID }}
2424 EVENT_NAME : ${{ github.event_name }}
25+ EVENT_ACTION : ${{ github.event.action }}
26+ COMMENT_ID : ${{ github.event.comment.id }}
2527 COMMENT_BODY : ${{ github.event.comment.body }}
2628 COMMENT_URL : ${{ github.event.comment.html_url }}
2729 COMMENTER : ${{ github.event.comment.user.login }}
@@ -118,11 +120,19 @@ jobs:
118120
119121 # Clean comment body:
120122 # 1. Remove HTML comments (<!-- ... -->)
121- # 2. Remove GitHub admonitions (> [!TIP], > [!NOTE], etc. and their continuation lines)
122- # 3. Trim leading/trailing whitespace
123+ # 2. Remove <details>...</details> blocks (CodeRabbit analysis chains)
124+ # 3. Remove GitHub admonitions (> [!TIP], > [!NOTE], etc. and their continuation lines)
125+ # 4. Remove --- separators and everything after them
126+ # 5. Remove remaining HTML tags (<sub>, <summary>, etc.)
127+ # 6. Remove lines that are only whitespace or markdown artifacts
128+ # 7. Trim leading/trailing whitespace
123129 CLEANED_BODY=$(echo "$COMMENT_BODY" | perl -0777 -pe '
124130 s/<!--.*?-->//gs;
131+ s/<details>.*?<\/details>//gs;
125132 s/^>\s*\[!(TIP|NOTE|WARNING|CAUTION|IMPORTANT)\]\s*\n(^>.*\n)*//gm;
133+ s/\n---\s*\n.*//s;
134+ s/<[^>]+>//g;
135+ s/^\s*\n//gm;
126136 s/^\s+|\s+$//g;
127137 ')
128138
@@ -133,83 +143,152 @@ jobs:
133143 TRUNCATED_BODY="$CLEANED_BODY"
134144 fi
135145
136- if [ -n "$THREAD_TS" ]; then
137- # Thread reply — just show the comment text, no header
146+ # Build the blocks for the comment
147+ COMMENT_BLOCKS=$(jq -n --arg comment_body "$TRUNCATED_BODY" '[
148+ {
149+ "type": "rich_text",
150+ "elements": [
151+ {
152+ "type": "rich_text_quote",
153+ "elements": [
154+ {
155+ "type": "text",
156+ "text": $comment_body
157+ }
158+ ]
159+ }
160+ ]
161+ }
162+ ]')
163+
164+ # Build metadata to tag this Slack message with the GitHub comment ID
165+ METADATA=$(jq -n --arg comment_id "$COMMENT_ID" '{
166+ "event_type": "github_comment",
167+ "event_payload": { "comment_id": $comment_id }
168+ }')
169+
170+ if [ "$EVENT_ACTION" = "edited" ] && [ -n "$THREAD_TS" ]; then
171+ # Edit — find the existing Slack message for this GitHub comment and update it
172+ REPLIES=$(curl -s "https://slack.com/api/conversations.replies?channel=$SLACK_CHANNEL_ID&ts=$THREAD_TS&include_all_metadata=true&limit=200" \
173+ -H "Authorization: Bearer $SLACK_BOT_TOKEN")
174+
175+ SLACK_MSG_TS=$(echo "$REPLIES" | jq -r --arg cid "$COMMENT_ID" '
176+ .messages[]
177+ | select(.metadata.event_payload.comment_id == $cid)
178+ | .ts' | head -1)
179+
180+ if [ -n "$SLACK_MSG_TS" ] && [ "$SLACK_MSG_TS" != "null" ]; then
181+ # Found the message — update it
182+ UPDATE_PAYLOAD=$(jq -n \
183+ --arg channel "$SLACK_CHANNEL_ID" \
184+ --arg ts "$SLACK_MSG_TS" \
185+ --arg comment_body "$TRUNCATED_BODY" \
186+ --argjson blocks "$COMMENT_BLOCKS" \
187+ --argjson metadata "$METADATA" \
188+ '{
189+ "channel": $channel,
190+ "ts": $ts,
191+ "text": $comment_body,
192+ "blocks": $blocks,
193+ "metadata": $metadata
194+ }')
195+
196+ curl -s -X POST "https://slack.com/api/chat.update" \
197+ -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
198+ -H "Content-Type: application/json" \
199+ -d "$UPDATE_PAYLOAD"
200+ else
201+ # Could not find the original message — post as new reply
202+ PAYLOAD=$(jq -n \
203+ --arg channel "$SLACK_CHANNEL_ID" \
204+ --arg commenter "$COMMENTER" \
205+ --arg comment_body "$TRUNCATED_BODY" \
206+ --arg avatar "$COMMENTER_AVATAR" \
207+ --arg thread_ts "$THREAD_TS" \
208+ --argjson blocks "$COMMENT_BLOCKS" \
209+ --argjson metadata "$METADATA" \
210+ '{
211+ "channel": $channel,
212+ "username": $commenter,
213+ "icon_url": $avatar,
214+ "thread_ts": $thread_ts,
215+ "text": $comment_body,
216+ "unfurl_links": false,
217+ "blocks": $blocks,
218+ "metadata": $metadata
219+ }')
220+
221+ curl -s -X POST "https://slack.com/api/chat.postMessage" \
222+ -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
223+ -H "Content-Type: application/json" \
224+ -d "$PAYLOAD"
225+ fi
226+ elif [ -n "$THREAD_TS" ]; then
227+ # New comment with existing thread — reply in thread
138228 PAYLOAD=$(jq -n \
139229 --arg channel "$SLACK_CHANNEL_ID" \
140230 --arg commenter "$COMMENTER" \
141231 --arg comment_body "$TRUNCATED_BODY" \
142232 --arg avatar "$COMMENTER_AVATAR" \
143233 --arg thread_ts "$THREAD_TS" \
234+ --argjson blocks "$COMMENT_BLOCKS" \
235+ --argjson metadata "$METADATA" \
144236 '{
145237 "channel": $channel,
146238 "username": $commenter,
147239 "icon_url": $avatar,
148240 "thread_ts": $thread_ts,
149241 "text": $comment_body,
150242 "unfurl_links": false,
151- "blocks": [
152- {
153- "type": "rich_text",
154- "elements": [
155- {
156- "type": "rich_text_quote",
157- "elements": [
158- {
159- "type": "text",
160- "text": $comment_body
161- }
162- ]
163- }
164- ]
165- }
166- ]
243+ "blocks": $blocks,
244+ "metadata": $metadata
167245 }')
246+
247+ curl -s -X POST "https://slack.com/api/chat.postMessage" \
248+ -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
249+ -H "Content-Type: application/json" \
250+ -d "$PAYLOAD"
168251 else
169252 # No thread found — post top-level with full context
253+ HEADER_BLOCK=$(jq -n \
254+ --arg repo_short "$REPO_SHORT" \
255+ --arg pr_url "$PR_URL" \
256+ --arg pr_number "$PR_NUMBER" \
257+ --arg pr_title "$PR_TITLE" \
258+ --arg commenter "$COMMENTER" \
259+ '{
260+ "type": "section",
261+ "text": {
262+ "type": "mrkdwn",
263+ "text": ($commenter + " commented on [" + $repo_short + "#" + $pr_number + "] <" + $pr_url + "|" + $pr_title + ">")
264+ }
265+ }')
266+
267+ ALL_BLOCKS=$(echo "$COMMENT_BLOCKS" | jq --argjson header "$HEADER_BLOCK" '[$header] + .')
268+
170269 PAYLOAD=$(jq -n \
171270 --arg channel "$SLACK_CHANNEL_ID" \
172271 --arg repo_short "$REPO_SHORT" \
173272 --arg pr_url "$PR_URL" \
174273 --arg pr_number "$PR_NUMBER" \
175274 --arg pr_title "$PR_TITLE" \
176275 --arg commenter "$COMMENTER" \
177- --arg comment_body "$TRUNCATED_BODY" \
178276 --arg avatar "$COMMENTER_AVATAR" \
277+ --argjson blocks "$ALL_BLOCKS" \
278+ --argjson metadata "$METADATA" \
179279 '{
180280 "channel": $channel,
181281 "username": $commenter,
182282 "icon_url": $avatar,
183283 "text": ($commenter + " commented on [" + $repo_short + "#" + $pr_number + "] <" + $pr_url + "|" + $pr_title + ">"),
184284 "unfurl_links": false,
185- "blocks": [
186- {
187- "type": "section",
188- "text": {
189- "type": "mrkdwn",
190- "text": ($commenter + " commented on [" + $repo_short + "#" + $pr_number + "] <" + $pr_url + "|" + $pr_title + ">")
191- }
192- },
193- {
194- "type": "rich_text",
195- "elements": [
196- {
197- "type": "rich_text_quote",
198- "elements": [
199- {
200- "type": "text",
201- "text": $comment_body
202- }
203- ]
204- }
205- ]
206- }
207- ]
285+ "blocks": $blocks,
286+ "metadata": $metadata
208287 }')
209- fi
210288
211- curl -s -X POST "https://slack.com/api/chat.postMessage" \
212- -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
213- -H "Content-Type: application/json" \
214- -d "$PAYLOAD"
289+ curl -s -X POST "https://slack.com/api/chat.postMessage" \
290+ -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
291+ -H "Content-Type: application/json" \
292+ -d "$PAYLOAD"
293+ fi
215294 fi
0 commit comments