Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 29 additions & 9 deletions pkg/connector/userinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,16 +151,36 @@ func (lc *LineClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal)
mid := string(portal.ID)
lowerMid := strings.ToLower(mid)
if strings.HasPrefix(lowerMid, "c") || strings.HasPrefix(lowerMid, "r") {
_, res, err := callLineResult(lc, ctx, func(client *line.Client) (*line.GetChatsResponse, error) {
return client.GetChats([]string{mid}, true, true)
})
if err != nil {
return nil, err
}
if len(res.Chats) == 0 {
return nil, fmt.Errorf("chat not found")
var chat *line.Chat
if strings.HasPrefix(lowerMid, "r") {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Bug · All "r" portals skip getChats, losing name/avatar/invitees/creator on resync

Every portal ID starting with "r" now goes to getRoomsV2, and the synthesized Chat has only ChatMid, Type 1 and MemberMids. syncChatsNow still gets type-1 ROOM chats from getChats, so for any "r" chat getChats returns, a GetChatInfo resync produces a different ChatInfo than startup sync: empty ChatName replaces a custom name, empty PicturePath clears the avatar, nil InviteeMids removes invitees (Members.IsFull=true), and empty CreatorMid drops the creator's power level from 100 to 0. The two paths then overwrite each other.

Keep getChats as the first lookup for "r" mids and use getRoomsV2 only when getChats returns no chats (or errors).

Found by Indent Review Agent

// Legacy multi-person rooms aren't returned by getChats.
_, rooms, err := callLineResult(lc, ctx, func(client *line.Client) ([]line.Room, error) {
return client.GetRoomsV2([]string{mid})
})
if err != nil {
return nil, err
}
if len(rooms) == 0 {
return nil, fmt.Errorf("room not found")
}
chat = &line.Chat{
ChatMid: mid,
Type: 1,
Extra: line.ChatExtra{GroupExtra: &line.GroupExtra{MemberMids: rooms[0].MemberMids}},
}
} else {
_, res, err := callLineResult(lc, ctx, func(client *line.Client) (*line.GetChatsResponse, error) {
return client.GetChats([]string{mid}, true, true)
})
if err != nil {
return nil, err
}
if len(res.Chats) == 0 {
return nil, fmt.Errorf("chat not found")
}
chat = &res.Chats[0]
}
info := lc.chatToChatInfo(ctx, &res.Chats[0], true)
info := lc.chatToChatInfo(ctx, chat, true)
if portal.MXID == "" && lc.shouldSkipDeletedChat(mid, "") {
lc.stripRemoteMembersFromInitialChatInfo(info)
}
Expand Down
19 changes: 19 additions & 0 deletions pkg/line/methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,25 @@ func (c *Client) GetChats(mids []string, withMembers, withInvitees bool) (*GetCh
return &wrapper.Data, nil
}

func (c *Client) GetRoomsV2(mids []string) ([]Room, error) {
resp, err := c.callRPC("TalkService", "getRoomsV2", mids)
if err != nil {
return nil, err
}
var wrapper struct {
Code int `json:"code"`
Message string `json:"message"`
Data []Room `json:"data"`
}
if err := json.Unmarshal(resp, &wrapper); err != nil {
return nil, err
}
if wrapper.Code != 0 {
return nil, fmt.Errorf("getRoomsV2 failed: %s", wrapper.Message)
}
return wrapper.Data, nil
}

func (c *Client) GetLastOpRevision() (int64, error) {
return c.GetLastOpRevisionContext(context.Background())
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/line/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,10 @@ type Chat struct {
Type int `json:"type"` // 0=GROUP, 1=ROOM
}

type Room struct {
MemberMids FlexibleMidMap `json:"memberMids"`
}

type ChatExtra struct {
GroupExtra *GroupExtra `json:"groupExtra,omitempty"`
PeerExtra *PeerExtra `json:"peerExtra,omitempty"`
Expand Down
Loading