underbbs/adapter/misskey.go

120 lines
2.9 KiB
Go
Raw Normal View History

2024-06-22 16:39:02 +00:00
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
}