136 lines
3 KiB
Go
136 lines
3 KiB
Go
package adapter
|
|
|
|
import (
|
|
"fmt"
|
|
. "forge.lightcrystal.systems/lightcrystal/underbbs/models"
|
|
madon "github.com/McKael/madon"
|
|
"log"
|
|
"os"
|
|
)
|
|
|
|
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) send(data SocketData) {
|
|
if self.data != nil {
|
|
*self.data <- data
|
|
} else {
|
|
fmt.Println(os.Stdout, string(data.ToDatagram()))
|
|
}
|
|
}
|
|
|
|
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 {
|
|
log.Printf("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.send(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, data map[string]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
|
|
}
|