Skip to content

Sync GitHub comment edits to Slack#4

Merged
jbingham17 merged 2 commits intomainfrom
feature/edit-comment-sync
Feb 20, 2026
Merged

Sync GitHub comment edits to Slack#4
jbingham17 merged 2 commits intomainfrom
feature/edit-comment-sync

Conversation

@jbingham17
Copy link
Contributor

@jbingham17 jbingham17 commented Feb 20, 2026

Summary

  • Triggers workflow on edited comment events (in addition to created)
  • Tags each Slack message with the GitHub comment ID via Slack message metadata
  • On edit, finds the matching Slack message in the thread using conversations.replies + metadata lookup, then updates it via chat.update
  • Falls back to posting a new message if the original can't be found

Test plan

  • Comment on this PR, then edit the comment — the Slack thread reply should update in place
  • Verify new comments still post correctly as thread replies

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Slack notifications now support edited comments and will update the corresponding Slack message when possible.
    • Edited comments fall back to posting a new reply if the original message can't be located.
  • Improvements

    • Richer, cleaner message formatting with a concise header and truncated preview for long comments.
    • Better comment cleaning (removes extraneous markup) and stronger thread discovery for more accurate linking.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Feb 20, 2026

Caution

Review failed

The pull request is closed.

Walkthrough

The workflow .github/workflows/pr-comment-slack-notify.yml was expanded to handle both created and edited issue and review comments. Two new public inputs, EVENT_ACTION and COMMENT_ID, distinguish event type and identify the comment. Comment text is preprocessed and truncated; Slack message blocks (COMMENT_BLOCKS, header) and METADATA (including comment_id) are dynamically built. If EVENT_ACTION is edited and a thread exists, the workflow searches thread replies for matching metadata.comment_id and updates the Slack message with chat.update; otherwise it posts a new top-level message or thread reply. All Slack API calls now send blocks and metadata.

Possibly related PRs

  • Sync GitHub comment edits to Slack #4 — Modifies the same workflow to add EVENT_ACTION and COMMENT_ID, build COMMENT_BLOCKS and METADATA, and implement edit-handling that finds and updates Slack messages via conversations.replies plus chat.update.

Comment @coderabbitai help to get the list of available commands and usage tips.

@jbingham17
Copy link
Contributor Author

Sizurp

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/pr-comment-slack-notify.yml:
- Around line 162-170: The current conversations.replies call that sets REPLIES
and extracts SLACK_MSG_TS can miss the edited message in long threads due to the
200-item cap; update the logic that runs when THREAD_TS is set (the edited
branch) to perform cursor-based pagination: repeatedly call
conversations.replies with the response_metadata.next_cursor until either the
message matching COMMENT_ID is found or no cursor remains, merging/fetching each
page into REPLIES or scanning per-page for the matching
.metadata.event_payload.comment_id to set SLACK_MSG_TS; ensure the cursor query
parameter is URL-encoded when appended to the API URL and stop the loop once
SLACK_MSG_TS is determined or next_cursor is empty to avoid infinite loops.

Comment on lines +162 to +170
if [ "$EVENT_ACTION" = "edited" ] && [ -n "$THREAD_TS" ]; then
# Edit — find the existing Slack message for this GitHub comment and update it
REPLIES=$(curl -s "https://slack.com/api/conversations.replies?channel=$SLACK_CHANNEL_ID&ts=$THREAD_TS&include_all_metadata=true&limit=200" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN")

SLACK_MSG_TS=$(echo "$REPLIES" | jq -r --arg cid "$COMMENT_ID" '
.messages[]
| select(.metadata.event_payload.comment_id == $cid)
| .ts' | head -1)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Slack conversations.replies API pagination next_cursor limit

💡 Result:

conversations.replies uses cursor-based pagination:

  • First request: pass channel, ts, and optionally limit (page size). Example: limit=200 (Slack recommends ≤200). The method’s general maximum is documented as 1000, but see the non‑Marketplace note below. [1][2]
  • Next pages: read response_metadata.next_cursor from the response, then call again with cursor=<next_cursor> (and the same limit). Repeat until next_cursor is missing/null/empty string (""). [1][3]
  • Don’t stop just because you got fewer than limit items—Slack may return fewer (even 0) while still providing a next_cursor. Always key off next_cursor. [2][3]
  • Encoding: cursor strings often end with =; when sending as a URL query parameter, encode it (e.g., =%3D). [3]

Important (rate-limit-driven limit change): For apps commercially distributed outside the Slack Marketplace, Slack reduced the default and maximum limit for conversations.replies to 15 and rate-limited the method to 1 request/min for certain apps/installations (see Slack’s changelog and method docs for applicability dates). [1][4]

Minimal pagination loop (pseudo):

  1. cursor = null
  2. call conversations.replies(channel, ts, limit, cursor?)
  3. cursor = response.response_metadata.next_cursor
  4. if cursor is empty → done; else repeat. [1][3]

Sources:
[1] Slack method docs: conversations.replies https://api.slack.com/methods/conversations.replies
[2] Slack Conversations API pagination notes https://api.slack.com/conversations-api
[3] Slack pagination guide https://docs.slack.dev/apis/web-api/pagination/
[4] Slack changelog (rate limit + limit=15 for non‑Marketplace) https://api.slack.com/changelog/2025-05-terms-rate-limit-update-and-faq


Paginate replies to avoid missing edited messages in long threads.
conversations.replies is capped at 200 (or 15 for non-Marketplace apps); if a thread exceeds that, the target message won't be found and edits will post a duplicate reply instead of updating in place. Implement cursor-based pagination using response_metadata.next_cursor.

One detail: URL-encode the cursor when passing it as a query parameter (e.g., =%3D), since cursor strings often contain special characters.

🧭 Suggested pagination pattern
- REPLIES=$(curl -s "https://slack.com/api/conversations.replies?channel=$SLACK_CHANNEL_ID&ts=$THREAD_TS&include_all_metadata=true&limit=200" \
-   -H "Authorization: Bearer $SLACK_BOT_TOKEN")
-
- SLACK_MSG_TS=$(echo "$REPLIES" | jq -r --arg cid "$COMMENT_ID" '
-   .messages[]
-   | select(.metadata.event_payload.comment_id == $cid)
-   | .ts' | head -1)
+ SLACK_MSG_TS=""
+ CURSOR=""
+ while :; do
+   REPLIES=$(curl -s "https://slack.com/api/conversations.replies?channel=$SLACK_CHANNEL_ID&ts=$THREAD_TS&include_all_metadata=true&limit=200&cursor=$CURSOR" \
+     -H "Authorization: Bearer $SLACK_BOT_TOKEN")
+
+   SLACK_MSG_TS=$(echo "$REPLIES" | jq -r --arg cid "$COMMENT_ID" '
+     .messages[]
+     | select(.metadata.event_payload.comment_id == $cid)
+     | .ts' | head -1)
+
+   if [ -n "$SLACK_MSG_TS" ] && [ "$SLACK_MSG_TS" != "null" ]; then
+     break
+   fi
+
+   CURSOR=$(echo "$REPLIES" | jq -r '.response_metadata.next_cursor // empty')
+   [ -z "$CURSOR" ] && break
+ done

Note: Consider URL-encoding the cursor parameter if special characters cause issues.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/pr-comment-slack-notify.yml around lines 162 - 170, The
current conversations.replies call that sets REPLIES and extracts SLACK_MSG_TS
can miss the edited message in long threads due to the 200-item cap; update the
logic that runs when THREAD_TS is set (the edited branch) to perform
cursor-based pagination: repeatedly call conversations.replies with the
response_metadata.next_cursor until either the message matching COMMENT_ID is
found or no cursor remains, merging/fetching each page into REPLIES or scanning
per-page for the matching .metadata.event_payload.comment_id to set
SLACK_MSG_TS; ensure the cursor query parameter is URL-encoded when appended to
the API URL and stop the loop once SLACK_MSG_TS is determined or next_cursor is
empty to avoid infinite loops.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jbingham17 jbingham17 merged commit 48a59bf into main Feb 20, 2026
1 check was pending
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant