···2233import (
44 "context"
55- "encoding/json"
65 "fmt"
76 "log/slog"
87 "strings"
98 "time"
1091110 "github.com/bluesky-social/indigo/api/atproto"
1111+ "github.com/bluesky-social/indigo/api/bsky"
1212 "github.com/bluesky-social/indigo/lex/util"
1313 "github.com/bluesky-social/indigo/xrpc"
1414 bk "github.com/tailscale/go-bluesky"
···20202121// PostRecord constructs a post record with a facet. To get there, it will find the
2222// position of the URL inside the text and attaches it to the post.
2323-func PostRecord(title, url, author, stargazers, hashtags string) map[string]interface{} {
2323+func PostRecord(title, url, author, stargazers, hashtags string) *bsky.FeedPost {
2424 text := title
25252626- startAuthor := -1
2626+ var startAuthor int64 = -1
27272828 if len(author) > 0 {
2929 text += " by " + author
3030- startAuthor = strings.Index(text, " by @") + 4
3030+ startAuthor = int64(strings.Index(text, " by @")) + 4
3131 }
32323333 if len(stargazers) > 0 {
3434 text += fmt.Sprintf(" (%s)", stargazers)
3535 }
36363737- text += "\n\n" + url
3838-3937 if len(hashtags) > 0 {
4038 text += "\n\n" + hashtags
4139 }
42404343- startRepoURL := strings.Index(text, url)
4141+ var startRepoURL int64 = 0
4242+4343+ facets := []*bsky.RichtextFacet{}
4444+ facets = append(facets, addFacet(
4545+ startRepoURL,
4646+ startRepoURL+int64(len(title)),
4747+ addLinkFeature(url)))
4848+4949+ if startAuthor > 0 {
5050+ facets = append(facets, addFacet(
5151+ startAuthor,
5252+ startAuthor+int64(len(author)),
5353+ addLinkFeature("https://github.com/"+author[1:]),
5454+ ))
5555+ }
44564545- facets := []map[string]interface{}{
4646- {
4747- "index": map[string]int{
4848- "byteStart": startRepoURL,
4949- "byteEnd": startRepoURL + len(url),
5050- },
5151- "features": []map[string]string{
5252- addFeature("app.bsky.richtext.facet#link", "uri", url),
5353- },
5757+ if len(hashtags) > 0 {
5858+ allTags := strings.Split(hashtags, " ")
5959+6060+ startHashTag := int64(strings.Index(text, hashtags))
6161+6262+ for _, t := range allTags {
6363+ slog.Debug(t)
6464+ facets = append(facets, addFacet(
6565+ startHashTag,
6666+ startHashTag+int64(len(t)),
6767+ addTagFeature(t[1:]),
6868+ ))
6969+7070+ // set cursor for next hashtag
7171+ startHashTag += int64(len(t)) + 1
7272+ }
7373+ }
7474+7575+ // fmt.Printf("%v", facets)
7676+7777+ return &bsky.FeedPost{
7878+ Text: text,
7979+ CreatedAt: time.Now().Format(time.RFC3339),
8080+ Langs: []string{"en-UK"},
8181+ Facets: facets,
8282+ }
8383+}
8484+8585+// build structure for the facet (enables linking)
8686+func addFacet(start, end int64, feature any) *bsky.RichtextFacet {
8787+ facet := &bsky.RichtextFacet{
8888+ Index: &bsky.RichtextFacet_ByteSlice{
8989+ ByteStart: start,
9090+ ByteEnd: end,
5491 },
9292+ Features: []*bsky.RichtextFacet_Features_Elem{},
5593 }
56945757- if startAuthor > 0 {
5858- facets = append(facets, map[string]interface{}{
5959- "index": map[string]int{
6060- "byteStart": startAuthor,
6161- "byteEnd": startAuthor + len(author),
6262- },
6363- "features": []map[string]string{
6464- addFeature("app.bsky.richtext.facet#link", "uri", "https://github.com/"+author[1:]),
6565- },
9595+ switch f := feature.(type) {
9696+ case *bsky.RichtextFacet_Link:
9797+ facet.Features = append(facet.Features, &bsky.RichtextFacet_Features_Elem{
9898+ RichtextFacet_Link: f,
6699 })
100100+ case *bsky.RichtextFacet_Tag:
101101+ facet.Features = append(facet.Features, &bsky.RichtextFacet_Features_Elem{
102102+ RichtextFacet_Tag: f,
103103+ })
104104+ case *bsky.RichtextFacet_Mention:
105105+ panic("mention not supported")
106106+ default:
107107+ panic("unknown type")
67108 }
681096969- // if len(hashtags) > 0 {
7070- // facets = append(facets, map[string]interface{}{
7171- // "index": map[string]int{
7272- // "byteStart": 0,
7373- // "byteEnd": 0,
7474- // },
7575- // "features": []map[string]string{
7676- // addFeature("app.bsky.richtext.facet#tag", "tag", "tag-here-fixme"),
7777- // },
7878- // })
7979- // }
110110+ return facet
111111+}
801128181- return map[string]interface{}{
8282- "$type": "app.bsky.feed.post",
8383- "text": text,
8484- "createdAt": time.Now().Format(time.RFC3339),
8585- "langs": []string{"en-UK"},
8686- "facets": facets,
113113+// build structure for the feature (link target)
114114+func addLinkFeature(uri string) *bsky.RichtextFacet_Link {
115115+ return &bsky.RichtextFacet_Link{
116116+ Uri: uri,
87117 }
8888-89118}
901199191-func addFeature(fType, fAttr, value string) map[string]string {
9292- return map[string]string{
9393- "$type": fType,
9494- fAttr: value,
120120+func addTagFeature(tag string) *bsky.RichtextFacet_Tag {
121121+ return &bsky.RichtextFacet_Tag{
122122+ Tag: tag,
95123 }
96124}
9712598126// Post creates a post on BlueSky
9999-func (c *Client) Post(ctx context.Context, post map[string]interface{}) error {
127127+func (c *Client) Post(ctx context.Context, post *bsky.FeedPost) error {
100128 return c.Client.CustomCall(func(api *xrpc.Client) error {
101129 sessionResult, err := atproto.ServerGetSession(ctx, api)
102130 if err != nil {
103131 return err
104132 }
105133106106- jRecord, err := json.Marshal(post)
107107- if err != nil {
108108- return fmt.Errorf("failed to marshal record: %v", err)
109109- }
110110-111111- slog.Debug(string(jRecord))
112112-113113- record := &util.LexiconTypeDecoder{}
114114- if err := record.UnmarshalJSON(jRecord); err != nil {
115115- return fmt.Errorf("failed to pack record: %v", err)
116116- }
117117-118134 _, err = atproto.RepoCreateRecord(ctx, api, &atproto.RepoCreateRecord_Input{
119135 Collection: "app.bsky.feed.post",
120136 Repo: sessionResult.Did,
121121- Record: record,
137137+ Record: &util.LexiconTypeDecoder{
138138+ Val: post,
139139+ },
122140 })
123141124142 return err
+1
internal/content/cache.go
···99 "github.com/go-redis/redis/v8"
1010)
11111212+// CacheClientProcess is an in process cache that adheres to larry's interface
1213type CacheClientProcess struct {
1314 store sync.Map
1415}
+1-1
internal/content/content.go
···5151 }
52525353 if strings.Contains(e, "#") {
5454- hashTags = e
5454+ hashTags = strings.TrimSpace(e)
5555 continue
5656 }
5757