core, ui: auto-accept group invitations per user profile

Add a per-profile toggle for auto-accepting group invitations, and regroup it
with the existing contact-requests setting under a single Auto-accept section
in Privacy & Security, relabelled "Contact requests in groups".

The join is fully async. processGroupInvitation already had an async accept
path, used when the invitation matches a group link the user opened:
prepareAgentJoin + createMemberConnectionAsync + joinAgentConnectionAsync,
with the outcome reported later against the CFJoinConn command id. Auto-accept
takes that same path instead of going through APIJoinGroup, so it works while
the app is closed and never blocks message processing.

An auto-accepted invitation still records a CIRcvGroupInvitation item in the
chat with the inviting contact, so there is a record of who added the user to
which group.

Two details worth noting for review:

hostContact is reported to clients only for group links. Clients respond to it
by replacing the transient host connection view with the group and removing
that chat - correct for a group link, where the contact is a placeholder, but
wrong for a plain invitation, where it is a real contact.

A resent invitation returns the existing group, because createGroupInvitation
is idempotent on inv_queue_info. The join therefore only runs while the
membership is still GSMemInvited, so a resend cannot open a second connection.
This commit is contained in:
Narasimha-sc
2026-08-15 14:22:07 +00:00
parent 6fcfbd54c5
commit 0bec70821f
32 changed files with 480 additions and 58 deletions
@@ -637,6 +637,19 @@ def APISetUserAutoAcceptMemberContacts_cmd_string(self: APISetUserAutoAcceptMemb
APISetUserAutoAcceptMemberContacts_Response = CR.CmdOk | CR.ChatCmdError
# Set auto-accept group invitations.
# Network usage: no.
class APISetUserAutoAcceptGroupInvitations(TypedDict):
userId: int # int64
onOff: bool
def APISetUserAutoAcceptGroupInvitations_cmd_string(self: APISetUserAutoAcceptGroupInvitations) -> str:
return '/_set accept group invitations ' + str(self['userId']) + ' ' + ('on' if self['onOff'] else 'off')
APISetUserAutoAcceptGroupInvitations_Response = CR.CmdOk | CR.ChatCmdError
# User profile commands
# Most bots don't need to use these commands, as bot profile can be configured manually via CLI or desktop client. These commands can be used by bots that need to manage multiple user profiles (e.g., the profiles of support agents).
@@ -3526,6 +3526,7 @@ class User(TypedDict):
sendRcptsContacts: bool
sendRcptsSmallGroups: bool
autoAcceptMemberContacts: bool
autoAcceptGroupInvitations: bool
userMemberProfileUpdatedAt: NotRequired[str] # ISO-8601 timestamp
userChatRelay: bool
clientService: bool