diff options
Diffstat (limited to 'backend/fetchers/profiles.go')
| -rw-r--r-- | backend/fetchers/profiles.go | 67 |
1 files changed, 60 insertions, 7 deletions
diff --git a/backend/fetchers/profiles.go b/backend/fetchers/profiles.go index 9a1334a..e98dc00 100644 --- a/backend/fetchers/profiles.go +++ b/backend/fetchers/profiles.go @@ -9,29 +9,44 @@ import ( "strings" ) -func FetchHandle(did string) (string, error) { +type DIDDocument struct { + AlsoKnownAs []string `json:"alsoKnownAs"` + Service []struct { + ID string `json:"id"` + Type string `json:"type"` + ServiceEndpoint string `json:"serviceEndpoint"` + } `json:"service"` +} + +func FetchDidDoc(did string) (*DIDDocument, error) { didDocURL := fmt.Sprintf("https://plc.directory/%s", did) resp, err := http.Get(didDocURL) if err != nil { - return "", err + return nil, err } defer resp.Body.Close() if resp.StatusCode != 200 { - return "", fmt.Errorf("DID resolution failed: %d", resp.StatusCode) + return nil, fmt.Errorf("DID resolution failed: %d", resp.StatusCode) } body, err := io.ReadAll(resp.Body) if err != nil { - return "", err + return nil, err } - var didDoc struct { - AlsoKnownAs []string `json:"alsoKnownAs"` + var didDoc DIDDocument + err = json.Unmarshal(body, &didDoc) + if err != nil { + return nil, err } - err = json.Unmarshal(body, &didDoc) + return &didDoc, nil +} + +func FetchHandle(did string) (string, error) { + var didDoc, err = FetchDidDoc(did) if err != nil { return "", err } @@ -44,6 +59,44 @@ func FetchHandle(did string) (string, error) { return handle, nil } +func FetchPDS(did string) (string, error) { + var didDoc, err = FetchDidDoc(did) + if err != nil { + return "", err + } + + for _, svc := range didDoc.Service { + if svc.Type == "AtprotoPersonalDataServer" { + return svc.ServiceEndpoint, nil + } + } + + return "", fmt.Errorf("no PDS found for DID %s", did) +} + +func FetchHandleAndPDS(did string) (string, string, error) { + var didDoc, err = FetchDidDoc(did) + if err != nil { + return "", "", err + } + + if len(didDoc.AlsoKnownAs) == 0 { + return "", "", fmt.Errorf("no handle found") + } + + var pds string + for _, svc := range didDoc.Service { + if svc.Type == "AtprotoPersonalDataServer" { + pds = svc.ServiceEndpoint + break + } + } + + handle := strings.TrimPrefix(didDoc.AlsoKnownAs[0], "at://") + + return handle, pds, nil +} + func FetchProfile(did string, pdsURL string) (*general.Profile, error) { recordURL := fmt.Sprintf("%s/xrpc/com.atproto.repo.getRecord?repo=%s&collection=app.bsky.actor.profile&rkey=self", pdsURL, did) |
