go scratch code for atproto
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}