aboutsummaryrefslogtreecommitdiff
path: root/backend/fetchers/app.bsky.actor.go
diff options
context:
space:
mode:
Diffstat (limited to 'backend/fetchers/app.bsky.actor.go')
-rw-r--r--backend/fetchers/app.bsky.actor.go73
1 files changed, 42 insertions, 31 deletions
diff --git a/backend/fetchers/app.bsky.actor.go b/backend/fetchers/app.bsky.actor.go
index 3c0154a..45ced77 100644
--- a/backend/fetchers/app.bsky.actor.go
+++ b/backend/fetchers/app.bsky.actor.go
@@ -5,6 +5,7 @@ import (
"fmt"
"io"
"llostre/backend/general"
+ "log/slog"
"net"
"net/http"
"strings"
@@ -128,57 +129,67 @@ func FetchHandleAndPDS(did string) (string, string, error) {
return handle, pds, nil
}
-func FetchProfile(did, pdsURL string, cache *Cache) (*general.Profile, error) {
- recordURL := fmt.Sprintf("%s/xrpc/com.atproto.repo.getRecord?repo=%s&collection=app.bsky.actor.profile&rkey=self", pdsURL, did)
+func FetchProfile(logger *slog.Logger, did, pdsURL, slingshotURL string, cache *Cache) (*general.Profile, error) {
+ // construct profile record URI
+ uri := fmt.Sprintf("at://%s/app.bsky.actor.profile/self", did)
+
+ // try slingshot first
+ if slingshotURL != "" {
+ rawRecord, err := general.FetchRawRecordByURI(logger, uri, slingshotURL)
+ if err != nil {
+ logger.Warn("slingshot profile fetch failed", "did", did, "error", err)
+ } else {
+ return parseProfile(did, rawRecord, cache)
+ }
+ }
- resp, err := http.Get(recordURL)
+ // fallback to PDS
+ rawRecord, err := general.FetchRawRecordByURI(logger, uri, pdsURL)
if err != nil {
return nil, err
}
- defer resp.Body.Close()
- if resp.StatusCode != 200 {
- return nil, fmt.Errorf("profile fetch failed: %d", resp.StatusCode)
- }
+ return parseProfile(did, rawRecord, cache)
+}
- handle, err := FetchHandle(did)
- if err != nil {
- handle = "handle.invalid"
+func FetchProfiles(logger *slog.Logger, dids []string, pdsURL, slingshotURL string, cache *Cache) map[string]general.Profile {
+ profiles := make(map[string]general.Profile)
+ for _, did := range dids {
+ profile, err := FetchProfile(logger, did, pdsURL, slingshotURL, cache)
+ if err == nil {
+ profiles[did] = *profile
+ }
}
+ return profiles
+}
- var response general.ProfileRecordResponse
- if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
+func parseProfile(did string, rawRecord *general.RawRecord, cache *Cache) (*general.Profile, error) {
+ var profileData general.ProfileRecord
+ if err := json.Unmarshal(rawRecord.Value, &profileData); err != nil {
return nil, err
}
var avatarURL, bannerURL string
- if response.Value.Avatar != nil {
- avatarURL = fmt.Sprintf("https://cdn.bsky.app/img/avatar/plain/%s/%s@jpeg", did, response.Value.Avatar.Ref.Link)
+ if profileData.Avatar != nil {
+ avatarURL = fmt.Sprintf("https://cdn.bsky.app/img/avatar/plain/%s/%s@jpeg", did, profileData.Avatar.Ref.Link)
+ }
+ if profileData.Banner != nil {
+ bannerURL = fmt.Sprintf("https://cdn.bsky.app/img/banner/plain/%s/%s@jpeg", did, profileData.Banner.Ref.Link)
}
- if response.Value.Banner != nil {
- bannerURL = fmt.Sprintf("https://cdn.bsky.app/img/banner/plain/%s/%s@jpeg", did, response.Value.Banner.Ref.Link)
+
+ handle, err := FetchHandle(did)
+ if err != nil {
+ handle = "handle.invalid"
}
profile := &general.Profile{
Handle: handle,
- DisplayName: response.Value.DisplayName,
+ DisplayName: profileData.DisplayName,
AvatarURL: avatarURL,
BannerURL: bannerURL,
- Pronouns: response.Value.Pronouns,
+ Pronouns: profileData.Pronouns,
}
- cache.SetProfile(handle, profile)
+ cache.SetProfile(did, profile)
return profile, nil
}
-
-func FetchProfiles(dids []string, pdsURL string, cache *Cache) map[string]general.Profile {
- profiles := make(map[string]general.Profile)
- for _, did := range dids {
- profile, err := FetchProfile(did, pdsURL, cache)
- if err == nil {
- cache.SetProfile(did, profile)
- profiles[did] = *profile
- }
- }
- return profiles
-}