go scratch code for atproto
at main 89 lines 2.3 kB view raw
1package pdsclient 2 3import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "io" 8 "net/http" 9 10 "github.com/bluesky-social/indigo/atproto/atclient" 11 "github.com/bluesky-social/indigo/atproto/atdata" 12 "github.com/bluesky-social/indigo/atproto/syntax" 13) 14 15type PDSClient struct { 16 *atclient.APIClient 17 18 AccountDID syntax.DID 19} 20 21type createRecordBody struct { 22 Repo syntax.DID `json:"repo"` 23 Collection syntax.NSID `json:"collection"` 24 RKey *syntax.RecordKey `json:"rkey,omitempty"` 25 Record any `json:"record"` 26} 27 28type createRecordResp struct { 29 CID syntax.CID `json:"cid"` 30 URI syntax.ATURI `json:"uri"` 31 ValidationStatus *string `json:"validationStatus,omitempty"` 32} 33 34// rkey is optional (pass empty string for server to create value) 35func (pc *PDSClient) CreateRecord(ctx context.Context, collection syntax.NSID, rkey syntax.RecordKey, record any) (syntax.ATURI, syntax.CID, error) { 36 37 body := createRecordBody{ 38 Repo: pc.AccountDID, 39 Collection: collection, 40 Record: record, 41 } 42 if rkey != "" { 43 body.RKey = &rkey 44 } 45 46 var out createRecordResp 47 endpoint := syntax.NSID("com.atproto.repo.createRecord") 48 if err := pc.APIClient.Post(ctx, endpoint, body, out); err != nil { 49 return "", "", err 50 } 51 return out.URI, out.CID, nil 52} 53 54// TODO: PutRecrod 55// TODO: DeleteRecord 56// TODO: GetRecord 57// TODO: ApplyWrites (?) 58 59type uploadBlobResp struct { 60 Blob atdata.Blob `json:"blob"` 61} 62 63func (pc *PDSClient) UploadBlob(ctx context.Context, mimeType string, input io.Reader) (*atdata.Blob, error) { 64 65 endpoint := syntax.NSID("com.atproto.repo.uploadBlob") 66 req := atclient.NewAPIRequest(http.MethodPost, endpoint, input) 67 req.Headers.Set("Accept", "application/json") 68 req.Headers.Set("Content-Type", mimeType) 69 70 resp, err := pc.APIClient.Do(ctx, req) 71 if err != nil { 72 return nil, err 73 } 74 defer resp.Body.Close() 75 76 if !(resp.StatusCode >= 200 && resp.StatusCode < 300) { 77 var eb atclient.ErrorBody 78 if err := json.NewDecoder(resp.Body).Decode(&eb); err != nil { 79 return nil, &atclient.APIError{StatusCode: resp.StatusCode} 80 } 81 return nil, eb.APIError(resp.StatusCode) 82 } 83 84 var out uploadBlobResp 85 if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { 86 return nil, fmt.Errorf("failed decoding JSON response body: %w", err) 87 } 88 return &out.Blob, nil 89}