adapter/mastodon.go (raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
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) 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 } |