collection of golang services under the Red Dwarf umbrella server.reddwarf.app
bluesky reddwarf microcosm appview
15
fork

Configure Feed

Select the types of activity you want to include in your feed.

getFeedGenerators

+135
+95
main.go
··· 1 1 package main 2 2 3 3 import ( 4 + "bytes" 4 5 "context" 5 6 "encoding/json" 6 7 "flag" ··· 8 9 "io" 9 10 "log" 10 11 "net/http" 12 + "os" 13 + "sync" 11 14 "time" 12 15 13 16 did "github.com/whyrusleeping/go-did" ··· 22 25 // "github.com/bluesky-social/indigo/atproto/atclient" 23 26 // comatproto "github.com/bluesky-social/indigo/api/atproto" 24 27 appbsky "github.com/bluesky-social/indigo/api/bsky" 28 + "github.com/bluesky-social/indigo/atproto/syntax" 29 + 25 30 // "github.com/bluesky-social/indigo/atproto/atclient" 26 31 // "github.com/bluesky-social/indigo/atproto/identity" 27 32 // "github.com/bluesky-social/indigo/atproto/syntax" ··· 280 285 Views: labelers, 281 286 }) 282 287 }) 288 + 289 + router.GET("/xrpc/app.bsky.feed.getFeedGenerators", 290 + func(c *gin.Context) { 291 + feeds := c.QueryArray("feeds") 292 + ctx := c.Request.Context() 293 + 294 + type result struct { 295 + view *appbsky.FeedDefs_GeneratorView 296 + } 297 + 298 + results := make([]result, len(feeds)) 299 + 300 + var wg sync.WaitGroup 301 + wg.Add(len(feeds)) 302 + 303 + for i, raw := range feeds { 304 + go func(i int, raw string) { 305 + defer wg.Done() 306 + 307 + aturi, err := syntax.ParseATURI(raw) 308 + if err != nil { 309 + return 310 + } 311 + 312 + did := aturi.Authority().String() 313 + collection := aturi.Collection().String() 314 + rkey := aturi.RecordKey().String() 315 + 316 + repoDID, err := utils.NewDID(did) 317 + if err != nil { 318 + return 319 + } 320 + 321 + // fetch profile and record in parallel too (optional) 322 + // but to keep it simple, do serial inside this goroutine 323 + profile, _, _ := appbskyactordefs.ProfileView(ctx, repoDID, sl, BSKYIMAGECDN_URL) 324 + 325 + rec, err := agnostic.RepoGetRecord(ctx, sl, "", collection, did, rkey) 326 + if err != nil || rec.Value == nil { 327 + return 328 + } 329 + 330 + var genRec appbsky.FeedGenerator 331 + if err := json.Unmarshal(*rec.Value, &genRec); err != nil { 332 + return 333 + } 334 + 335 + var avatar *string 336 + if genRec.Avatar != nil { 337 + u := utils.MakeImageCDN(repoDID, BSKYIMAGECDN_URL, "avatar", genRec.Avatar.Ref.String()) 338 + avatar = &u 339 + } 340 + 341 + results[i].view = &appbsky.FeedDefs_GeneratorView{ 342 + LexiconTypeID: "app.bsky.feed.defs#generatorView", 343 + AcceptsInteractions: genRec.AcceptsInteractions, 344 + Avatar: avatar, 345 + Cid: *rec.Cid, 346 + ContentMode: genRec.ContentMode, 347 + Creator: profile, 348 + Description: genRec.Description, 349 + DescriptionFacets: genRec.DescriptionFacets, 350 + Did: did, 351 + DisplayName: genRec.DisplayName, 352 + IndexedAt: genRec.CreatedAt, 353 + Uri: rec.Uri, 354 + } 355 + }(i, raw) 356 + } 357 + 358 + wg.Wait() 359 + 360 + // build final slice 361 + out := make([]*appbsky.FeedDefs_GeneratorView, 0, len(results)) 362 + for _, r := range results { 363 + if r.view != nil { 364 + out = append(out, r.view) 365 + } 366 + } 367 + 368 + c.JSON(http.StatusOK, &appbsky.FeedGetFeedGenerators_Output{ 369 + Feeds: out, 370 + }) 371 + }) 372 + 373 + yourJSONBytes, _ := os.ReadFile("./public/getConfig.json") 374 + router.GET("/xrpc/app.bsky.unspecced.getConfig", func(c *gin.Context) { 375 + c.DataFromReader(200, -1, "application/json", 376 + bytes.NewReader(yourJSONBytes), nil) 377 + }) 283 378 284 379 router.GET("/", func(c *gin.Context) { 285 380 log.Println("hello worldio !")
+40
public/getConfig.json
··· 1 + { 2 + "checkEmailConfirmed": true, 3 + "topicsEnabled": true, 4 + "liveNow": [ 5 + { 6 + "did": "did:plc:7sfnardo5xxznxc6esxc5ooe", 7 + "domains": [ 8 + "www.nba.com", 9 + "nba.com", 10 + "nba.smart.link", 11 + "espn.com", 12 + "www.espn.com" 13 + ] 14 + }, 15 + { "did": "did:plc:gx6fyi3jcfxd7ammq2t7mzp2", "domains": ["twitch.tv"] }, 16 + { "did": "did:plc:mc2hhszsfk6iwapfdwrwoj7i", "domains": ["twitch.tv"] }, 17 + { "did": "did:plc:sb54dpdfefflykmf5bcfvr7t", "domains": ["youtube.com"] }, 18 + { "did": "did:plc:dqav4a4ue5cyzgckv3l6fshr", "domains": ["twitch.tv"] }, 19 + { "did": "did:plc:q6f4hsgifb3qs2e3wwdycjtf", "domains": ["twitch.tv"] }, 20 + { "did": "did:plc:7tpvfx7mdbceyzj6kgboirle", "domains": ["twitch.tv"] }, 21 + { 22 + "did": "did:plc:4adlzwqtkv4dirxjwq4c3tlm", 23 + "domains": ["stream.place", "skylight.social"] 24 + }, 25 + { 26 + "did": "did:plc:2zmxikig2sj7gqaezl5gntae", 27 + "domains": ["stream.place", "skylight.social"] 28 + }, 29 + { 30 + "did": "did:plc:jsbkvuuviqj4xooqwcbaftav", 31 + "domains": ["stream.place", "skylight.social"] 32 + }, 33 + { 34 + "did": "did:plc:76iqtegcbbr4pbcxomka5pat", 35 + "domains": ["stream.place", "skylight.social"] 36 + }, 37 + { "did": "did:plc:r2mpjf3gz2ygfaodkzzzfddg", "domains": ["youtube.com"] }, 38 + { "did": "did:plc:wvwvlbeizca367klhhyudf2n", "domains": ["youtube.com"] } 39 + ] 40 + }