package qq import ( "context" "encoding/json" "fmt" "net/http" "time" "git.yeij.top/AskaEth/Cyrene/platform-bridge/internal/bridge" ) // ListChannels implements bridge.ChannelLister — fetches groups + friends from NapCat. func (a *Adapter) ListChannels() []bridge.ChannelInfo { var all []bridge.ChannelInfo all = append(all, a.FetchGroups()...) all = append(all, a.FetchFriends()...) return all } // FetchGroups fetches the group list from NapCat HTTP API and caches group names. // Returns a list of channel info for all groups the bot is in. func (a *Adapter) FetchGroups() []bridge.ChannelInfo { if a.mode != "client" || a.remoteURL == "" { return nil } httpBase := a.httpBase() if httpBase == "" { return nil } url := fmt.Sprintf("%s/get_group_list", httpBase) if a.accessToken != "" { url += "?access_token=" + a.accessToken } ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() req, err := http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { fmt.Printf("[qq:%s] get_group_list request failed: %v\n", a.configName, err) return nil } resp, err := http.DefaultClient.Do(req) if err != nil { fmt.Printf("[qq:%s] get_group_list failed: %v\n", a.configName, err) return nil } defer resp.Body.Close() var result struct { Data []struct { GroupID int64 `json:"group_id"` GroupName string `json:"group_name"` } `json:"data"` } if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { fmt.Printf("[qq:%s] get_group_list parse failed: %v\n", a.configName, err) return nil } var channels []bridge.ChannelInfo for _, g := range result.Data { if g.GroupName != "" { a.SetGroupName(g.GroupID, g.GroupName) } channels = append(channels, bridge.ChannelInfo{ Platform: "obv11", ChannelType: "group", ChannelID: fmt.Sprintf("%d", g.GroupID), ChannelName: g.GroupName, }) } fmt.Printf("[qq:%s] 获取到 %d 个群聊\n", a.configName, len(channels)) return channels } // FetchFriends fetches the friend list from NapCat HTTP API. // Returns a list of channel info for private chats. func (a *Adapter) FetchFriends() []bridge.ChannelInfo { if a.mode != "client" || a.remoteURL == "" { return nil } httpBase := a.httpBase() if httpBase == "" { return nil } url := fmt.Sprintf("%s/get_friend_list", httpBase) if a.accessToken != "" { url += "?access_token=" + a.accessToken } ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() req, err := http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { fmt.Printf("[qq:%s] get_friend_list request failed: %v\n", a.configName, err) return nil } resp, err := http.DefaultClient.Do(req) if err != nil { fmt.Printf("[qq:%s] get_friend_list failed: %v\n", a.configName, err) return nil } defer resp.Body.Close() var result struct { Data []struct { UserID int64 `json:"user_id"` Nickname string `json:"nickname"` Remark string `json:"remark"` } `json:"data"` } if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { fmt.Printf("[qq:%s] get_friend_list parse failed: %v\n", a.configName, err) return nil } var channels []bridge.ChannelInfo for _, f := range result.Data { name := f.Remark if name == "" { name = f.Nickname } channels = append(channels, bridge.ChannelInfo{ Platform: "obv11", ChannelType: "private", ChannelID: fmt.Sprintf("%d", f.UserID), ChannelName: name, }) } fmt.Printf("[qq:%s] 获取到 %d 个好友\n", a.configName, len(channels)) return channels }