diff options
| author | Guillermo Serrahima <dev@vylion.com> | 2026-02-19 14:27:24 +0100 |
|---|---|---|
| committer | Guillermo Serrahima <dev@vylion.com> | 2026-02-19 14:27:24 +0100 |
| commit | 8f39d3c036588782f36d5ff90ce2839fd75fa496 (patch) | |
| tree | 38bfd8304057828b4e30d704b093e79f6b931bb3 | |
| parent | b8614b16e958cbacfff05a8e2f79f8e4410654b8 (diff) | |
| download | llostre-8f39d3c036588782f36d5ff90ce2839fd75fa496.tar.xz llostre-8f39d3c036588782f36d5ff90ce2839fd75fa496.zip | |
added bsky posts
| -rw-r--r-- | backend/fetchers/app.bsky.go | 47 | ||||
| -rw-r--r-- | backend/notes/app.bsky.feed.post.go | 74 | ||||
| -rw-r--r-- | backend/notes/note.go | 13 |
3 files changed, 134 insertions, 0 deletions
diff --git a/backend/fetchers/app.bsky.go b/backend/fetchers/app.bsky.go new file mode 100644 index 0000000..df89249 --- /dev/null +++ b/backend/fetchers/app.bsky.go @@ -0,0 +1,47 @@ +package fetchers + +import ( + "encoding/json" + "fmt" + "io" + "llostre/backend/notes" + "llostre/backend/records" + "net/http" +) + +type ListRecordsResponse struct { + Records []notes.AppBskyFeedPostRecord `json:"records"` +} + +func FetchBlueskyPosts(did string, pdsURL string) ([]notes.AppBskyFeedPostNote, error) { + url := fmt.Sprintf("%s/xrpc/com.atproto.repo.listRecords?repo=%s&collection=app.bsky.feed.post&limit=50", pdsURL, did) + + resp, err := http.Get(url) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + var response records.ListRecordsResponse + err = json.Unmarshal(body, &response) + if err != nil { + return nil, err + } + + var posts []notes.AppBskyFeedPostNote + for _, record := range response.Records { + bp, err := notes.AppBskyFeedPostFromRecord(record) + if err != nil { + fmt.Printf("skipping malformed record %s: %v\n", record.URI, err) + continue + } + posts = append(posts, *bp) + } + + return posts, nil +} diff --git a/backend/notes/app.bsky.feed.post.go b/backend/notes/app.bsky.feed.post.go new file mode 100644 index 0000000..21256be --- /dev/null +++ b/backend/notes/app.bsky.feed.post.go @@ -0,0 +1,74 @@ +package notes + +import ( + "fmt" + "strings" + "time" +) + +type AppBskyFeedPostNote struct { + URI string + AuthorDID string + AuthorHandle string + Text string + CreatedAt time.Time + ReplyTo *string +} + +type AppBskyFeedPostRecord struct { + URI string `json:"uri"` + Value struct { + Text string `json:"text"` + CreatedAt string `json:"createdAt"` + Reply *struct { + Parent struct { + URI string `json:"uri"` + } `json:"parent"` + } `json:"reply,omitempty"` + } `json:"value"` +} + +func (bp *AppBskyFeedPostNote) GetID() string { + return bp.URI +} + +func (bp *AppBskyFeedPostNote) GetAuthorDID() string { + return bp.AuthorDID +} + +func (bp *AppBskyFeedPostNote) GetAuthorHandle() string { + return bp.AuthorHandle +} + +func (bp *AppBskyFeedPostNote) GetTimestamp() time.Time { + return bp.CreatedAt +} + +func (bp *AppBskyFeedPostNote) GetReplyTo() *string { + return bp.ReplyTo +} + +func AppBskyFeedPostFromRecord(record AppBskyFeedPostRecord) (*AppBskyFeedPostNote, error) { + createdAt, err := time.Parse(time.RFC3339, record.Value.CreatedAt) + if err != nil { + return nil, fmt.Errorf("failed to parse timestamp: %w", err) + } + if record.Value.Text == "" { + return nil, fmt.Errorf("missing required field: text") + } + if record.URI == "" { + return nil, fmt.Errorf("missing required field: uri") + } + + parts := strings.Split(record.URI, "/") // at://DID/collection/rkey + did := parts[2] + + return &AppBskyFeedPostNote{ + URI: record.URI, + AuthorDID: did, + AuthorHandle: "author_handle", // wip + CreatedAt: createdAt, + Text: record.Value.Text, + ReplyTo: &record.Value.Reply.Parent.URI, + }, nil +} diff --git a/backend/notes/note.go b/backend/notes/note.go new file mode 100644 index 0000000..1d92948 --- /dev/null +++ b/backend/notes/note.go @@ -0,0 +1,13 @@ +package notes + +import ( + "time" +) + +type Note interface { + GetID() string + GetAuthorDID() string + GetAuthorHandle() string + GetTimestamp() time.Time + GetReplyTo() *string +} |
