Federated via graft
1.0 kB
35 lines
1package sync
2
3import (
4 "fmt"
5
6 "graft/internal/atproto"
7)
8
9// BlueskyPoster posts short notes to one Bluesky account on behalf of a
10// repo pair. Nil-safe: a nil *BlueskyPoster's Post is a silent no-op, so
11// every call site can post unconditionally instead of nil-checking —
12// matching the "absent config = feature off, never an error" rule for
13// this integration (see config.RepoPair.Bluesky).
14type BlueskyPoster struct {
15 Handle string
16 AppPassword string
17 PDSHost string
18}
19
20// Post logs in fresh and publishes text. A new session per post is
21// wasteful but simple and avoids session-expiry bookkeeping — acceptable
22// given how infrequently a single pair mirrors new content.
23func (b *BlueskyPoster) Post(text string) error {
24 if b == nil {
25 return nil
26 }
27 c := atproto.New(b.PDSHost)
28 if err := c.Login(b.Handle, b.AppPassword); err != nil {
29 return fmt.Errorf("bluesky login: %w", err)
30 }
31 if err := c.Post(text); err != nil {
32 return fmt.Errorf("bluesky post: %w", err)
33 }
34 return nil
35}