Skip to content

fix: Group invites are sent in beeper chat requests when join automatically is turned off#166

Open
highesttt wants to merge 2 commits into
mainfrom
group-invite-in-beeper-requests
Open

fix: Group invites are sent in beeper chat requests when join automatically is turned off#166
highesttt wants to merge 2 commits into
mainfrom
group-invite-in-beeper-requests

Conversation

@highesttt
Copy link
Copy Markdown
Collaborator

No description provided.

@indent
Copy link
Copy Markdown

indent Bot commented May 31, 2026

PR Summary

Surfaces pending LINE group invitations in Beeper's "Requests" inbox instead of as Matrix invites or auto-joined rooms, and wires up the corresponding LINE accept/reject RPCs so Beeper's Accept button (and implicit accept-on-first-message) drive the LINE side. Also fixes a parallel E2EE bug where registerE2EEGroupKey was rejected by LINE because the caller's own key entry was missing.

  • chatToChatInfo now marks GROUP-type (type 0) chats with the bridge user as invitee via info.MessageRequest = true instead of self-MembershipInvite (which Beeper would hide), and only writes the flag when truthy so a racing resync can't clobber bridgev2's post-accept clear; ROOMs (type 1) are deliberately excluded because they auto-join.
  • syncChats passes CreatePortal: true for invited chats so outstanding invites appear as Requests at startup, and handleInvite is refactored to determine self-invite status from MemberMids (not from the SSE op number), avoiding false positives for chats where the bridge user is the inviter or an existing member.
  • handleSystemMessage adds a defense-in-depth path for C_GI/C_MI/A_MI system messages where the invitee is self, spawning a handleInviteForSelf goroutine — but only when no portal already exists for the chat, to avoid duplicate work when the SSE handler wins the race.
  • Implements bridgev2.MessageRequestAcceptingNetworkAPI.HandleMatrixAcceptMessageRequestacceptChatInvitation, makes HandleMatrixLeaveRoom call rejectChatInvitation when portal.MessageRequest is still set, and advertises MessageRequest.AcceptWithButton = FullySupported while intentionally leaving AcceptWithMessage unset so bridgev2's autoAcceptMessageRequest accepts implicitly on first send.
  • Adds line.ChatInvitationRequest plus Client.AcceptChatInvitation / RejectChatInvitation using the single-struct argument form (mutate([{reqSeq, chatMid}])) that the LINE Chrome extension uses.
  • Fixes registerGroupKey by appending the caller's own MID, raw key ID, and self-wrapped group key to the registerE2EEGroupKey arrays; adds e2ee.Manager.MyPublicKey() to expose the caller's raw key ID and base64 public key.

Issues

All clear! No issues remaining. 🎉

3 issues already resolved
  • chatToChatInfo only marks selfInvitePending when chat.Type == 0, so any non-GROUP chat where the bridge user appears in InviteeMids but not MemberMids now silently renders self as MembershipJoin with no MessageRequest flag — a quiet behavior change versus the pre-PR MembershipInvite self path. ROOMs (type 1) auto-join in practice, but if LINE ever surfaces a transient invitee-only state for a type-1 chat the room will look fully joined with no Request banner. Consider documenting the type gate or expanding it to other group types if any exist. (fixed by commit 1c097e3)
  • handleInvite comment claims OpInviteIntoChat (123) is "reflected to the inviter", but the code still uses selfInvited := opType == OpInviteIntoChat as a positive signal that the bridge user is the invitee — these contradict. If the new comment is right, any GROUP invite the user initiates from another LINE client would be funneled into handleInviteForSelfFromChat and flipped into a Beeper Request; if the old comment was right, this is just misleading documentation. Please confirm 123 vs 124 semantics and align the comment (or the fallback) with reality. (fixed by commit 1c097e3)
  • handleSystemMessage's new self-invite branch and the SSE OpInviteIntoChat / OpNotifiedInviteIntoChat handler both spawn goroutines that call handleInviteForSelf for the same chat, so each invite makes two GetChats round-trips and queues two ChatResync events. bridgev2 dedupes by portal key so functionality is fine, but consider gating the system-message goroutine on "no SSE op arrived within Ns" or coalescing in a sync.Map to avoid the duplicate work. (fixed by commit 1c097e3)

CI Checks

All CI checks passed on commit 1c097e3.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 31, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 86682ede-640a-4c5b-a326-86f561ed781d

📥 Commits

Reviewing files that changed from the base of the PR and between 1bd623b and 1c097e3.

📒 Files selected for processing (1)
  • pkg/connector/sync.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/connector/sync.go
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build-docker
  • GitHub Check: build-docker

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Accept and reject pending LINE group invitations from the bridge.
    • Added API to accept message-request invitations.
  • Bug Fixes

    • E2EE group key registration now includes the bridge user's key to prevent server rejections.
    • Sync fixes to surface invited-but-not-joined chats as message requests reliably.
  • Updates

    • Exposed the bridge user's public key retrieval.
    • Enabled explicit "Accept with button" message-request capability.

Walkthrough

This PR adds message request support for LINE pending group invitations. The bridge detects when a user is invited to a group chat but not yet a member, creates it as a message request portal, and provides handlers to accept or reject the invitation. E2EE group key registration now includes the bridge user's own key to satisfy server requirements.

Changes

Message Request Support for LINE Group Invitations

Layer / File(s) Summary
LINE API invitation methods
pkg/line/methods.go
New ChatInvitationRequest type and Client.AcceptChatInvitation/RejectChatInvitation methods to call TalkService RPC endpoints.
E2EE public key exposure
pkg/e2ee/manager.go
Manager.MyPublicKey() method returns the user's latest raw key ID and base64 public key with validation and error handling.
Group E2EE key registration with caller key
pkg/connector/creategroup.go
registerGroupKey wraps the group key for the bridge user's own E2EE public key and appends the caller key entry to request arrays.
Message request detection and portal creation in sync
pkg/connector/sync.go
chatToChatInfo introduces selfInvitePending flow for invitee-only group chats; refactored handleInvite detects self-invites by checking InviteeMids; new handleInviteForSelfFromChat ensures invitee state and queues ChatResync with CreatePortal: true; system invite messages route bridge-user invitees through async portal creation before member changes.
Message request user-facing handlers
pkg/connector/send_message.go
HandleMatrixLeaveRoom rejects pending invitations instead of normal leave; new HandleMatrixAcceptMessageRequest accepts invitations via AcceptChatInvitation; compile-time assertion verifies LineClient implements MessageRequestAcceptingNetworkAPI.
Message request capabilities reporting
pkg/connector/userinfo.go
GetCapabilities reports MessageRequest feature with AcceptWithButton fully supported.

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive No description was provided by the author, making it impossible to assess whether it relates to the changeset. Add a pull request description explaining the changes, their purpose, and how they fix the issue with group invites in message requests.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: enabling group invites to surface as Beeper message requests when auto-join is disabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch group-invite-in-beeper-requests

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

Copy link
Copy Markdown

@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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/connector/sync.go`:
- Around line 1285-1294: The code incorrectly defaults selfInvited to true when
opType == OpInviteIntoChat causing inviters to be treated as self-invites;
change the logic in handleInvite so selfInvited starts false (selfInvited :=
false) and only set to true when the chat's GroupExtra.InviteeMids contains
lc.Mid (i.e., keep the existing check on chat.Extra.GroupExtra.InviteeMids)
before calling lc.handleInviteForSelfFromChat — ensure opType ==
OpInviteIntoChat is not used as the default indicator of a self-invite.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 861ae545-b025-4abf-93ee-74d2506ec28e

📥 Commits

Reviewing files that changed from the base of the PR and between 3142f0f and 1bd623b.

📒 Files selected for processing (6)
  • pkg/connector/creategroup.go
  • pkg/connector/send_message.go
  • pkg/connector/sync.go
  • pkg/connector/userinfo.go
  • pkg/e2ee/manager.go
  • pkg/line/methods.go
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build-docker
  • GitHub Check: build-docker
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Use go fmt for code formatting across all Go files
Use goimports with -local "github.com/highesttt/matrix-line-messenger" flag to group project-local imports correctly
Use zerolog for logging throughout the codebase
Do not use Msgf in logging; use Msg with structured fields instead
Use Stringer interface where applicable in Go code

Files:

  • pkg/connector/creategroup.go
  • pkg/connector/userinfo.go
  • pkg/line/methods.go
  • pkg/e2ee/manager.go
  • pkg/connector/send_message.go
  • pkg/connector/sync.go
**/!(ltsm)/**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/!(ltsm)/**/*.go: Run staticcheck on all Go files excluding pkg/ltsm package (transpiled WASM code)
Run go vet on all Go files excluding pkg/ltsm package (transpiled WASM code)

Files:

  • pkg/connector/creategroup.go
  • pkg/connector/userinfo.go
  • pkg/line/methods.go
  • pkg/e2ee/manager.go
  • pkg/connector/send_message.go
  • pkg/connector/sync.go
🔇 Additional comments (6)
pkg/line/methods.go (1)

761-780: LGTM!

pkg/e2ee/manager.go (1)

70-79: LGTM!

pkg/connector/creategroup.go (1)

243-257: LGTM!

pkg/connector/sync.go (1)

214-223: LGTM!

Also applies to: 244-257, 339-355, 1327-1328, 1330-1355, 1384-1396

pkg/connector/send_message.go (1)

830-837: LGTM!

Also applies to: 849-858

pkg/connector/userinfo.go (1)

54-59: LGTM!

Comment thread pkg/connector/sync.go Outdated
Comment thread pkg/connector/sync.go Outdated
Comment thread pkg/connector/sync.go
Comment thread pkg/connector/sync.go
Fizzadar
Fizzadar previously approved these changes Jun 1, 2026
Copy link
Copy Markdown
Member

@Fizzadar Fizzadar left a comment

Choose a reason for hiding this comment

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

Looks reasonable, please check the indent comments though @highesttt I'm not familiar with the code so may well have missed those notes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants