its for when you want to get like notifications for your reposts

refactor: instead of sending like jetstream dids to filter, just dont and do it our side

ptr.pet 2f18acb4 b16df182

verified
Changed files
+38 -8
+38 -8
main.go
···
// Global state
var (
subscribers = hashmap.New[string, *SubscriberData]()
+
listeningTo = hashmap.New[string, *hashmap.Map[string, *SubscriberData]]()
likeStream *client.Client
subscriberStream *client.Client
···
}
logger.Info("fetched reposts")
-
subscriber := &SubscriberData{
+
sd := &SubscriberData{
DID: did,
Conn: conn,
// use user follows as default listen to
···
Reposts: reposts,
}
-
subscribers.Set(did, subscriber)
+
subscribers.Set(sd.DID, sd)
+
for listenDid := range sd.ListenTo {
+
listenTo(sd, listenDid)
+
}
+
updateSubscriberStreamOpts()
updateLikeStreamOpts()
// delete subscriber after we are done
defer func() {
-
subscribers.Del(did)
+
for listenDid := range sd.ListenTo {
+
stopListeningTo(sd.DID, listenDid)
+
}
+
subscribers.Del(sd.DID)
+
updateSubscriberStreamOpts()
updateLikeStreamOpts()
}()
···
}
}
+
func listenTo(sd *SubscriberData, did string) {
+
targetDids, _ := listeningTo.GetOrInsert(did, hashmap.New[string, *SubscriberData]())
+
targetDids.Insert(sd.DID, sd)
+
}
+
+
func stopListeningTo(subscriberDid, did string) {
+
if targetDids, exists := listeningTo.Get(did); exists {
+
targetDids.Del(subscriberDid)
+
}
+
}
+
func getLikeStreamOpts() models.SubscriberOptionsUpdatePayload {
return models.SubscriberOptionsUpdatePayload{
WantedCollections: []string{"app.bsky.feed.like"},
-
WantedDIDs: getFollowsDids(),
+
// WantedDIDs: getFollowsDids(),
}
}
···
return nil
}
+
// skip handling event if its not from a source we are listening to
+
targets, exists := listeningTo.Get(event.Did)
+
if !exists {
+
return nil
+
}
+
var like bsky.FeedLike
if err := json.Unmarshal(event.Commit.Record, &like); err != nil {
-
logger.Error("Failed to unmarshal like", "error", err)
+
logger.Error("failed to unmarshal like", "error", err)
return nil
}
-
subscribers.Range(func(s string, sd *SubscriberData) bool {
+
targets.Range(func(s string, sd *SubscriberData) bool {
for repostURI, _ := range sd.Reposts {
// (un)liked a post the subscriber reposted
if like.Subject.Uri == repostURI {
···
}
if err := sd.Conn.WriteJSON(notification); err != nil {
-
logger.Error("Failed to send notification", "subscriber", sd.DID, "error", err)
+
logger.Error("failed to send notification", "subscriber", sd.DID, "error", err)
}
}
}
···
case "app.bsky.graph.follow":
modifySubscribersWithEvent(
event,
-
func(s *SubscriberData, r bsky.GraphFollow) { delete(s.ListenTo, r.Subject) },
+
func(s *SubscriberData, r bsky.GraphFollow) {
+
delete(s.ListenTo, r.Subject)
+
stopListeningTo(s.DID, r.Subject)
+
},
func(s *SubscriberData, r bsky.GraphFollow) {
s.ListenTo[r.Subject] = struct{}{}
+
listenTo(s, r.Subject)
},
)
}