GoAT Site is library that implements Standard.site in Go.
atprotocol standard-site atproto library
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs(info): basic usage and complexe types

+85 -2
+83 -1
README.md
··· 1 1 # GoAT Site 2 2 3 - GoAT Site implements [standard.site](https://standard.site/) in Go. 3 + GoAT Site implements [Standard.site](https://standard.site/) in Go. 4 4 5 5 Use official [`bluesky-social/indigo`](https://github.com/bluesky-social/indigo/). 6 + 7 + Main repository is hosted on [Tangled](https://tangled.org/anhgelus.world/goat-site/), an ATProto forge. 6 8 7 9 ## Usage 8 10 ··· 11 13 go get -u tangled.org/anhgelus.world/goat-site 12 14 ``` 13 15 16 + Each Standard.site lexicon is implemented: 17 + - `Publication` is for `site.standard.publication`; 18 + - `Document` is for `site.standard.document`; 19 + - `Subscription` is for `site.standard.graph.subscription`. 14 20 21 + These types implement `Record`, an interface describing records. 22 + 23 + You can get, list, create, update or delete them with functions. 24 + Each function starts with the action followed by the lexicon's name, e.g., 25 + - `GetPublication` to get a publication; 26 + - `ListDocuments` to list documents; 27 + - `CreateDocument` to create a new document. 28 + 29 + Currently, functions related to `Subscription` are not implemented. 30 + 31 + You can [verify](https://standard.site/docs/verification/) a publication with `Publication.Verify`. 32 + 33 + ## Creating custom records 34 + 35 + `Document.Content` is an open union: you can create your own lexicon to use it. 36 + 37 + If the NSID of your lexicon is `tld.example.content` and its definition in Go is: 38 + ```go 39 + type Content struct { 40 + // Pars represents the paragraphs in [Content]. 41 + Pars []string `json:"pars"` 42 + } 43 + ``` 44 + 45 + To use it, you have to implement `site.Record`: 46 + ```go 47 + const CollectionContent = `tld.example.content` 48 + 49 + func (c *Content) Type() string { 50 + return CollectionContent 51 + } 52 + ``` 53 + 54 + But, if you use `site.GetDocument` to retrieve one, it will return a simple `site.Document` without your custom content! 55 + The `Document.Content` field is a `site.RecordJSON`, a wrapper. 56 + You can get the type of the content with `RecordJSON.Type` and the raw bytes with `RecordJSON.Raw`. 57 + You can also directly parse your `Content` with `RecordJSON.As`: 58 + ```go 59 + var doc *site.Document 60 + var c *Content 61 + // returns an error if it cannot parse or if the type is invalid 62 + err := doc.Content.As(&c) 63 + if err != nil { 64 + panic(err) 65 + } 66 + ``` 67 + 68 + ### Marshal/Unmarshal 69 + 70 + When your record is sent, it is firstly marshaled to a map. 71 + We provide `site.MarshalToMap` which works like the JSON API: 72 + ```go 73 + var c *Content 74 + // mp is the map[string]any created 75 + mp, err := site.MarshalToMap(c) 76 + if err != nil { 77 + panic(err) 78 + } 79 + /* 80 + mp = map[string]any{"content": []string{}} 81 + */ 82 + ``` 83 + 84 + It uses the `json` tag to determine how to marshal the content. 85 + It supports `omitempty`, `string` and embedded type. 86 + 87 + If you are using complexe types, you may have to implement `json.Unmarshaler` to unmarshal from JSON and 88 + `site.MarshalerMap` to marshal to a map. 89 + ```go 90 + func (c *Content) MarshalMap() (map[string]any, error) { 91 + mp := make(map[string]any, 1) 92 + mp["foo"] = "bar" 93 + return mp, nil 94 + } 95 + // the future call to site.MarshalToMap on *Content will return map[string]any{"foo":"bar"}. 96 + ```
+1 -1
document.go
··· 36 36 // CoverImage to used for thumbnail or cover. 37 37 // Less than 1MB in size. 38 38 CoverImage *Blob `json:"coverImage,omitempty"` 39 - // Content is a custom [Lexicon] used to define the [Document]'s content. 39 + // Content is a custom [Record] used to define the [Document]'s content. 40 40 Content *RecordJSON `json:"content,omitempty"` 41 41 // TextContent is a plaintext representation of the [Document.Content]. 42 42 // Should not contain markdown or other formatting.
+1
lexicons.go
··· 22 22 CollectionBase = "site.standard" 23 23 CollectionBlob = "blob" 24 24 25 + // TimeFormat is the standard time format specified by the ATProto. 25 26 TimeFormat = "2006-01-02T15:04:05.000Z07:00" 26 27 ) 27 28