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 |
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) self.masto.StreamListener(filter, "", self.events, self.stop, self.done) go func() { for e := range self.events { 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) SendMessage(msg Message) error { return nil } func (self *MastoAdapter) Follow(author Author) error { return nil } func (self *MastoAdapter) Unfollow(author Author) error { return nil } func (self *MastoAdapter) GetFollowers() error { return nil } func (self *MastoAdapter) UpdateMetadata(data interface{}) error { return nil } func (self *MastoAdapter) DefaultSubscriptionFilter() string { return "home" } 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 } |