goat

package module
v0.0.0-...-11b446b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 7, 2024 License: MIT Imports: 16 Imported by: 0

README

goat

Package goat is a simple Go implementation for posting to ATProto platform (e.g. BlueSky).

Credit goes to https://atproto.com/blog/create-post as the inspiration for this library.

Features

Create post

  • Text post: Done
  • Inline URI / link (strict mode): Done
  • Image: Done
  • Link card: Done
  • Mention: Done
  • Quote: Done
  • Reply: Done

Delete post: Done

Update post: BSky API does not yet allow for app.bsky.feed.post update as of Jan 2024; TODO when / if it is allowed

Please note goat does not check for policy adherence, i.e. it does not check for post text length nor image size upload. This is left to the calling app to manage. A Truncate helper function can be called to truncate a long post down to within the maximum length, before sending the post, if a LinkURL to the origin is provided (i.e. permalink).

API

For more details on the API, please consult the go doc.

Go Reference

Here's a brief overview.

ATProto post is flexible and goat accommodates the content using the Prepost data structure.

type Prepost struct {
    Text            string
    Languages       []string
    ImageBlobs      []BlobData // for image attachment
    LinkURL         string     // for link card
    LinkTitle       string     // for link card
    LinkDescription string     // for link card
    LinkThumbnail   BlobData   // for link card
    Quote           PostInfo   // for reposting a quote
    Reply           Reply      // for posting a reply to an existing post
    RKey            string     // for updating an existing post, if not ""
}

type Reply struct {
    Root   PostInfo `json:"root"`
    Parent PostInfo `json:"parent"`
}

type PostInfo struct {
    URI string `json:"uri"`
    CID string `json:"cid"`
}

type BlobData struct {
    Data []byte
    Alt  string // image alt text; cannot be empty
    MIME string // image MIME type; cannot be empty
}

Populate the relevant fields and goat will parse them and process them into the needed format when it sends to the ATProto server.

To create a new post

import "codeberg.org/s877/goat"
...
var pp goat.Prepost
pp.Text = text
pp.Languages = langs
...
_, err := pp.Create(server, handle, password)

If server == "", it will default to "https://bsky.social". ATProto can specify multiple languages in a post, so it takes the form of []string. If including image(s), the []BlobData needs to be prepared beforehand.

To delete a post, use

err := goat.DeletePost(server, handle, password, rkey)

rkey is the last segment in URI after the last "/".

Convenience API

For simpler use cases, the older APIs are still available.

To create a post

_, err := NewPost(server, handle, password, text string, langs []string, blobs []BlobData)

To post a link card, use

_, err := NewLinkCard(server, handle, password, text, title, description, url string, thumbnail BlobData)

To post a quote, use

_, err := NewQuote(server, handle, password, text string, langs []string, quotedPost PostInfo)
Examples

The file cmd/goat/main.go illustrates usage of the goat package.

CLI

cd cmd/goat; go build will produce a binary called goat which also serves as a very simple BlueSky / ATProto CLI client. Run goat to see the command line usage hint.

Miscellaneous
Why call it 'goat'?

Because 'go-ATProto-Post' is a bit lengthy. A better spelling might be goAT, but goat seems simpler. (No goat was harmed during development.)

Maintenance

goat is open sourced in the hope it can help others reuse my experiments with the ATProto platform. No guarantee on future development nor API stability. It is provided as-is.

Thank you for your understanding.

Documentation

Overview

Package goat is a simple Go implementation for posting to ATProto platform (e.g. BlueSky).

Index

Constants

View Source
const BSkyMaxPostLength = 300

Variables

This section is empty.

Functions

func DeletePost

func DeletePost(server, handle, password, rkey string) error

func ResolveHandle

func ResolveHandle(server, handle string) string

ResolveHandle tries to resolve the handle of a user mention (@handle) and returns the DID of the user. If err or not found, it returns "".

func Truncate

func Truncate(limit int, text, url string) string

Truncate truncates text to within post character limit and then appends the permalink url to the truncated text; limit is expected to be longer than url by some margin. url should be well formed; Truncate does not validate the url. Returns only the url, if it cannot truncate. Use Truncate before parsing the text for facet or embed.

Example output: "Truncated text ... https://codeberg.org/s877/goat"

Types

type Blob

type Blob struct {
	Type string `json:"$type"`
	Ref  Ref    `json:"ref"`
	MIME string `json:"mimeType"`
	Size int    `json:"size"`
}

type BlobData

type BlobData struct {
	Data []byte
	Alt  string // image alt text; cannot be empty
	MIME string // image MIME type; cannot be empty
}

type External

type External struct {
	Type     string      `json:"$type"`
	External interface{} `json:"external"` // expecting Card or CardWithThumb
}

type Facet

type Facet struct {
	Index    Index     `json:"index"`
	Features []Feature `json:"features"`
}
func GetFacetLinks(text string) (facets []Facet)

GetFacetLinks parses the post text for links / URLs. It uses strict mode, i.e. considers a URL as a Facet only if it starts with 'https://' or 'http://'.

func GetFacetMentions

func GetFacetMentions(server, text string) (facets []Facet)

GetFacetMentions parses the post text for ATProto / BlueSky @mentions

type Feature

type Feature struct {
	Type string `json:"$type"`
	DID  string `json:"did,omitempty"`
	URI  string `json:"uri,omitempty"`
	Tag  string `json:"tag,omitempty"`
}

type Image

type Image struct {
	Alt   string `json:"alt,omitempty"`
	Image Blob   `json:"image,omitempty"`
}

type Index

type Index struct {
	ByteStart int `json:"byteStart"`
	ByteEnd   int `json:"byteEnd"`
}

type PostInfo

type PostInfo struct {
	URI string `json:"uri"`
	CID string `json:"cid"`
}

func NewLinkCard

func NewLinkCard(server, handle, password, text, title, description, url string, thumbnail BlobData) (PostInfo, error)

NewLinkCard uploads an external "website card / social card: rendered preview of a website link"; handle, password, and url are mandatory.

func NewPost

func NewPost(server, handle, password, text string, langs []string, blobs []BlobData) (PostInfo, error)

NewPost creates a new ATProto / BlueSky post. It authenticates, uploads images, if any, and then uploads the post.

func NewQuote

func NewQuote(server, handle, password, text string, langs []string, quoted PostInfo) (PostInfo, error)

NewQuote is similar to NewPost() for a quote of an existing ATProto record minus the image upload

type Prepost

type Prepost struct {
	Text            string
	Languages       []string
	ImageBlobs      []BlobData // for image attachment
	LinkURL         string     // for link card
	LinkTitle       string     // for link card
	LinkDescription string     // for link card
	LinkThumbnail   BlobData   // for link card
	Quote           PostInfo   // for reposting a quote
	Reply           Reply      // for posting a reply to an existing post

}

Prepost stores the values to be converted into a post for creating new post (RKey must be empty "") or updating an existing post (RKey must be valid)

func (*Prepost) Create

func (pp *Prepost) Create(server, handle, password string) (PostInfo, error)

Create creates a new post

type Ref

type Ref struct {
	Link string `json:"$link"`
}

type Reply

type Reply struct {
	Root   PostInfo `json:"root"`
	Parent PostInfo `json:"parent"`
}

type Session

type Session struct {
	Server string
	Auth   xrpc.AuthInfo
}

func CreateSession

func CreateSession(server, handle, password string) (Session, error)

CreateSession authenticates the user against the server. Server can be left as "" to authenticate against the default, i.e. https://bsky.social, or specified to an alternate server. This is a low level function for those who want to reuse it for their own alternative implementation.

func (*Session) CreateLinkCardEmbed

func (s *Session) CreateLinkCardEmbed(pp *Prepost) (embed External, err error)

func (*Session) CreateRecord

func (s *Session) CreateRecord(data []byte) (json string, err error)

func (*Session) UploadBlob

func (s *Session) UploadBlob(mimeType, altText string, data []byte) (Image, error)

UploadBlob uploads a blob (image) to the server to get the link id which is a required data to include if posting with image. This is a low level function for those who want to reuse it for their own alternative implementation.

Directories

Path Synopsis
cmd
goat
Goat is a really simple CLI to create or delete a post for ATProto / BlueSky platform.
Goat is a really simple CLI to create or delete a post for ATProto / BlueSky platform.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL