package pdsclient import ( "context" "encoding/json" "fmt" "io" "net/http" "github.com/bluesky-social/indigo/atproto/atclient" "github.com/bluesky-social/indigo/atproto/atdata" "github.com/bluesky-social/indigo/atproto/syntax" ) type PDSClient struct { *atclient.APIClient AccountDID syntax.DID } type createRecordBody struct { Repo syntax.DID `json:"repo"` Collection syntax.NSID `json:"collection"` RKey *syntax.RecordKey `json:"rkey,omitempty"` Record any `json:"record"` } type createRecordResp struct { CID syntax.CID `json:"cid"` URI syntax.ATURI `json:"uri"` ValidationStatus *string `json:"validationStatus,omitempty"` } // rkey is optional (pass empty string for server to create value) func (pc *PDSClient) CreateRecord(ctx context.Context, collection syntax.NSID, rkey syntax.RecordKey, record any) (syntax.ATURI, syntax.CID, error) { body := createRecordBody{ Repo: pc.AccountDID, Collection: collection, Record: record, } if rkey != "" { body.RKey = &rkey } var out createRecordResp endpoint := syntax.NSID("com.atproto.repo.createRecord") if err := pc.APIClient.Post(ctx, endpoint, body, out); err != nil { return "", "", err } return out.URI, out.CID, nil } // TODO: PutRecrod // TODO: DeleteRecord // TODO: GetRecord // TODO: ApplyWrites (?) type uploadBlobResp struct { Blob atdata.Blob `json:"blob"` } func (pc *PDSClient) UploadBlob(ctx context.Context, mimeType string, input io.Reader) (*atdata.Blob, error) { endpoint := syntax.NSID("com.atproto.repo.uploadBlob") req := atclient.NewAPIRequest(http.MethodPost, endpoint, input) req.Headers.Set("Accept", "application/json") req.Headers.Set("Content-Type", mimeType) resp, err := pc.APIClient.Do(ctx, req) if err != nil { return nil, err } defer resp.Body.Close() if !(resp.StatusCode >= 200 && resp.StatusCode < 300) { var eb atclient.ErrorBody if err := json.NewDecoder(resp.Body).Decode(&eb); err != nil { return nil, &atclient.APIError{StatusCode: resp.StatusCode} } return nil, eb.APIError(resp.StatusCode) } var out uploadBlobResp if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { return nil, fmt.Errorf("failed decoding JSON response body: %w", err) } return &out.Blob, nil }