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.

Go 100.0%
43 1 4

Clone this repository

https://tangled.org/anhgelus.world/goat-site https://tangled.org/did:plc:vtqucb4iga7b5wzza3zbz4so/goat-site
git@tangled.org:anhgelus.world/goat-site git@tangled.org:did:plc:vtqucb4iga7b5wzza3zbz4so/goat-site

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

GoAT Site#

GoAT Site implements Standard.site in Go.

Use anhgelus.world/xrpc, a lightweight XRPC client.

Main repository is hosted on Tangled, an ATProto forge.

Usage#

NOTE

Get the module with:

go get -u tangled.org/anhgelus.world/goat-site

Each Standard.site lexicon is implemented:

  • Publication is for site.standard.publication;
  • Document is for site.standard.document;
  • Subscription is for site.standard.graph.subscription.

These types implement xrpc.Record, an interface describing records.

You can get, list, create, update or delete them with functions:

  • xrpc.GetRecord[*site.Publication] to get a publication;
  • xrpc.ListRecords[*site.Document] to list documents;
  • xrpc.CreateRecord to create a new document;
  • xrpc.PutRecord to update a subscription;
  • xrpc.DeleteRecord[*site.Publication] to delete a publication.

You can verify a publication with Publication.Verify and a document with Document.Verify:

var pub *site.Publication
var did *atproto.DID
var client xrpc.Client
var rkey atproto.RecordKey
valid, err := pub.Verify(context.TODO(), client, did, rkey)
if err != nil {
    panic(err)
}
if !valid {
    println("invalid publication :(")
}

var doc *site.Document
pubUrl, err := doc.PublicationURL(context.TODO(), client)
if err != nil {
    panic(err)
}
valid, err = doc.Verify(context.TODO(), client, pubUrl, did, rkey)
if err != nil {
    panic(err)
}
if !valid {
    panic("invalid document :(")
}

Creating custom records#

Document.Content is an open union: you can create your own lexicon to use it.

If the NSID of your lexicon is tld.example.content and its definition in Go is:

type Content struct {
    // Pars represents the paragraphs in [Content].
    Pars []string `json:"pars"`
}

To use it, you have to implement site.Record:

var CollectionContent = atproto.NewNSIDBuilder(`tld.example`).Name("content").Build()

func (c *Content) Collection() *atproto.NSID {
    return CollectionContent
}

But if you use xrpc.GetRecord[*site.Document] to retrieve one, it will return a simple site.Document without your custom content! The Document.Content field is a xrpc.Union, a type representing an open union. You can get the collection of the content with Union.Collection() and the raw bytes with Union.Raw. You can also directly parse your Content with Union.As:

var doc *site.Document
c := new(Content)
// returns an error if it cannot parse or if the type is invalid
if !doc.Content.As(c) {
    panic("not a Content :(")
}

Marshal/Unmarshal#

See anhgelus.world/xrpc documentation.

Extending lexicons#

Lexicons defined by Standard.site can be extended.

To extend a lexicon, you can create a new type and embed the base lexicon:

type CustomPublication struct {
    site.Publication
    // your custom fields
}

You can call any functions with this new lexicon: the embedded base lexicon already implements the xrpc.Record interface!