package adapter import ( "fmt" . "forge.lightcrystal.systems/lightcrystal/underbbs/models" "github.com/yitsushi/go-misskey" mkm "github.com/yitsushi/go-misskey/models" notes "github.com/yitsushi/go-misskey/services/notes" tl "github.com/yitsushi/go-misskey/services/notes/timeline" _ "strings" "time" ) type MisskeyAdapter struct { data chan SocketData nickname string server string apiKey string mk *misskey.Client // unlike the mastodon client, we have to manage combining resources // from different API calls instead of streaming them in a single channel cache map[string]time.Time stop chan bool notes chan mkm.Note users chan mkm.User follows chan mkm.FollowStatus } func (self *MisskeyAdapter) Init(settings Settings, data chan SocketData) error { self.nickname = settings.Nickname self.server = *settings.Server self.apiKey = *settings.ApiKey self.data = data client, err := misskey.NewClientWithOptions( misskey.WithAPIToken(self.apiKey), misskey.WithBaseURL("https", self.server, ""), ) if err != nil { return err } self.mk = client return nil } func (self *MisskeyAdapter) Subscribe(filter string) []error { // misskey streaming API is undocumented.... // we could try to reverse engineer it by directly connecting to the websocket??? // alternatively, we can poll timelines, mentions, etc with a cancellation channel, // keep a cache of IDs in memory, and send new objects on the data channel // TODO: decode the filter so we can send data to the mk services // same as in masto, we will want to close and reopen the stop channel if self.stop != nil { close(self.stop) } self.stop = make(chan bool) // in the background, continuously read data from these API endpoints // if they are newer than the cache, convert them to UnderBBS objects // and send them on the data channel go func() { notesService := self.mk.Notes() timelineService := notesService.Timeline() for { _, moar := <-self.stop if !moar { break } // TODO: we have to actually decode and pass our filter criteria tlnotes, tlerr := timelineService.Get(tl.GetRequest{}) mentions, merr := notesService.Mentions(notes.MentionsRequest{}) if tlerr != nil { fmt.Println(tlerr.Error()) } if merr != nil { fmt.Println(merr.Error()) } // check the cache for everything we just collected // if anything is newer or as of yet not in the cache, add it // and convert it to a SocketData implementation before sending on data channel for _, n := range tlnotes { fmt.Println(n.ID) // check existence and cache // convert // send } for _, n := range mentions { fmt.Println(n.ID) // check existence and cache // convert // send } } }() return nil } func (self *MisskeyAdapter) Fetch(query string) error { return nil } func (self *MisskeyAdapter) Do(action string) error { return nil }