underbbs/adapter/mastodon.go

128 lines
2.9 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) 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(query 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 {
var parent *madon.Status
if status.InReplyToID != nil {
parent, _ = self.masto.GetStatus(*status.InReplyToID)
}
msg := Message{
Protocol: "mastodon",
Content: status.Content,
Uri: status.URI,
Author: Author{
Id: fmt.Sprintf("%d", status.Account.ID),
Name: status.Account.Username,
// TODO: we can add the fields to the profiledata as well
ProfileData: status.Account.Note,
ProfileUri: status.Account.URL,
ProfilePic: status.Account.Avatar,
},
Created: status.CreatedAt,
}
if parent != nil {
msg.ReplyTo = &parent.URI
}
// TODO: mentions and replies
msg.Aux = make(map[string]string)
msg.Aux["visibility"] = status.Visibility
return &msg
}