underbbs/adapter/mastodon.go

127 lines
2.8 KiB
Go

package adapter
import (
"fmt"
. "forge.lightcrystal.systems/lightcrystal/underbbs/models"
madon "github.com/McKael/madon"
)
type MastoAdapter struct {
data chan SocketData
nickname string
server string
apiKey string
masto *madon.Client
events chan madon.StreamEvent
stop chan bool
done chan bool
}
var scopes = []string{"read", "write", "follow"}
func (self *MastoAdapter) Name() string {
return self.nickname
}
func (self *MastoAdapter) Init(settings Settings, data chan SocketData) error {
self.nickname = settings.Nickname
self.server = *settings.Server
self.apiKey = *settings.ApiKey
self.data = data
masto, err := madon.NewApp("underbbs", "https://lightcrystal.systems", scopes, madon.NoRedirect, self.server)
if err != nil {
return err
}
self.masto = masto
err = self.masto.SetUserToken(self.apiKey, "", "", []string{})
return err
}
func (self *MastoAdapter) Subscribe(filter string) []error {
// TODO: decode separate timelines and hashtags
// for now, the filter is just the timeline
if self.events != nil {
close(self.events)
}
self.events = make(chan madon.StreamEvent)
if self.stop != nil {
close(self.stop)
}
self.stop = make(chan bool)
self.done = make(chan bool)
err := self.masto.StreamListener(filter, "", self.events, self.stop, self.done)
if err != nil {
return []error{err}
}
go func() {
for e := range self.events {
fmt.Println("event: %s !!!", e.Event)
switch e.Event {
case "error":
case "update":
var msg *Message
switch v := e.Data.(type) {
case int64:
s, _ := self.masto.GetStatus(v)
if s != nil {
msg = self.mastoUpdateToMessage(*s)
}
case madon.Status:
msg = self.mastoUpdateToMessage(v)
}
if msg != nil {
self.data <- msg
}
case "notification":
case "delete":
}
}
}()
// in the background, read and translate events from the stream
// and check for doneCh closing
// the stopCh will be closed by a subsequent call to subscribe
return nil
}
func (self *MastoAdapter) Fetch(etype string, ids []string) error {
return nil
}
func (self *MastoAdapter) Do(action string) error {
return nil
}
func (self *MastoAdapter) DefaultSubscriptionFilter() string {
return "user"
}
func (self *MastoAdapter) mastoUpdateToMessage(status madon.Status) *Message {
msg := Message{
Datagram: Datagram{
Protocol: "mastodon",
Adapter: self.nickname,
Id: fmt.Sprintf("%d", status.ID),
Uri: status.URI,
Type: "message",
Created: status.CreatedAt.UnixMilli(),
},
Content: status.Content,
Author: status.Account.Acct,
Visibility: status.Visibility,
}
if status.InReplyToID != nil {
idStr := fmt.Sprintf("%d", *status.InReplyToID)
msg.ReplyTo = &idStr
}
// TODO: mentions and replies
return &msg
}