diff --git a/apps/simplex-support-bot/bot.test.ts b/apps/simplex-support-bot/bot.test.ts index a1afd7a660..37521e49dc 100644 --- a/apps/simplex-support-bot/bot.test.ts +++ b/apps/simplex-support-bot/bot.test.ts @@ -1068,24 +1068,26 @@ describe("Team Member Lifecycle", () => { expect(chat.roleChanges.some(r => r.groupId === CUSTOMER_GROUP_ID && r.memberIds.includes(5000 + TEAM_MEMBER_1_ID) && r.role === GroupMemberRole.Owner)).toBe(true) }) - test("/team invites team member → apiSetMembersRole(Owner) called at invite time", async () => { + test("/team invites team member → added directly as Owner, single invitation", async () => { await bot.onNewChatItems(customerMessage("/team")) - expectMemberAdded(CUSTOMER_GROUP_ID, TEAM_MEMBER_1_ID) - expect(chat.roleChanges.some(r => - r.groupId === CUSTOMER_GROUP_ID - && r.memberIds.includes(5000 + TEAM_MEMBER_1_ID) - && r.role === GroupMemberRole.Owner + expect(chat.added.some(a => + a.groupId === CUSTOMER_GROUP_ID + && a.contactId === TEAM_MEMBER_1_ID + && a.role === GroupMemberRole.Owner )).toBe(true) + // No role change — that would send a second invitation. + expect(chat.roleChanges.length).toBe(0) }) - test("/join invites team member → apiSetMembersRole(Owner) called at invite time", async () => { + test("/join invites team member → added directly as Owner, single invitation", async () => { await bot.onNewChatItems(teamGroupMessage(`/join ${CUSTOMER_GROUP_ID}`)) - expectMemberAdded(CUSTOMER_GROUP_ID, TEAM_MEMBER_1_ID) - expect(chat.roleChanges.some(r => - r.groupId === CUSTOMER_GROUP_ID - && r.memberIds.includes(5000 + TEAM_MEMBER_1_ID) - && r.role === GroupMemberRole.Owner + expect(chat.added.some(a => + a.groupId === CUSTOMER_GROUP_ID + && a.contactId === TEAM_MEMBER_1_ID + && a.role === GroupMemberRole.Owner )).toBe(true) + // No role change — that would send a second invitation. + expect(chat.roleChanges.length).toBe(0) }) test("/team when team member already in group (any non-terminal status) → apiSetMembersRole NOT re-called", async () => { diff --git a/apps/simplex-support-bot/src/bot.ts b/apps/simplex-support-bot/src/bot.ts index 9b534381de..28b2080793 100644 --- a/apps/simplex-support-bot/src/bot.ts +++ b/apps/simplex-support-bot/src/bot.ts @@ -853,17 +853,12 @@ export class SupportBot { const members = await this.withMainProfile(() => this.chat.apiListMembers(groupId)) const existing = members.find(m => m.memberContactId === teamContactId && isInGroup(m)) if (existing) return existing - const member = await this.withMainProfile(() => - this.chat.apiAddMember(groupId, teamContactId, T.GroupMemberRole.Member) + // Invite directly as Owner in one call. Adding as Member then promoting + // sent a second invitation, since the API re-sends it when a pending + // (GSMemInvited) member's role changes. onMemberConnected re-asserts Owner. + return this.withMainProfile(() => + this.chat.apiAddMember(groupId, teamContactId, T.GroupMemberRole.Owner) ) - try { - await this.withMainProfile(() => - this.chat.apiSetMembersRole(groupId, [member.groupMemberId], T.GroupMemberRole.Owner) - ) - } catch { - // Not yet connected — will be promoted in onMemberConnected - } - return member } async sendToGroup(groupId: number, text: string): Promise {