all repos — underbbs @ 678e5e62584a2edc9f909c0b02247fa7ba95f71c

decentralized social media client

adapter/misskey.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
package adapter

import (
	"fmt"
	. "forge.lightcrystal.systems/lightcrystal/underbbs/models"
	"github.com/yitsushi/go-misskey"
	mkm "github.com/yitsushi/go-misskey/models"
	notes "github.com/yitsushi/go-misskey/services/notes"
	tl "github.com/yitsushi/go-misskey/services/notes/timeline"
	_ "strings"
	"time"
)

type MisskeyAdapter struct {
	data     chan SocketData
	nickname string
	server   string
	apiKey   string

	mk *misskey.Client

	// unlike the mastodon client, we have to manage combining resources
	// from different API calls instead of streaming them in a single channel

	cache map[string]time.Time

	stop chan bool

	notes   chan mkm.Note
	users   chan mkm.User
	follows chan mkm.FollowStatus
}

func (self *MisskeyAdapter) Init(settings Settings, data chan SocketData) error {
	self.nickname = settings.Nickname
	self.server = *settings.Server
	self.apiKey = *settings.ApiKey
	self.data = data

	client, err := misskey.NewClientWithOptions(
		misskey.WithAPIToken(self.apiKey),
		misskey.WithBaseURL("https", self.server, ""),
	)

	if err != nil {
		return err
	}
	self.mk = client
	return nil
}

func (self *MisskeyAdapter) Subscribe(filter string) []error {
	// misskey streaming API is undocumented....
	// we could try to reverse engineer it by directly connecting to the websocket???
	// alternatively, we can poll timelines, mentions, etc with a cancellation channel,
	// keep a cache of IDs in memory, and send new objects on the data channel

	// TODO: decode the filter so we can send data to the mk services

	// same as in masto, we will want to close and reopen the stop channel
	if self.stop != nil {
		close(self.stop)
	}
	self.stop = make(chan bool)

	// in the background, continuously read data from these API endpoints
	// if they are newer than the cache, convert them to UnderBBS objects
	// and send them on the data channel

	go func() {
		notesService := self.mk.Notes()
		timelineService := notesService.Timeline()

		for {
			_, moar := <-self.stop
			if !moar {
				break
			}

			// TODO: we have to actually decode and pass our filter criteria
			tlnotes, tlerr := timelineService.Get(tl.GetRequest{})
			mentions, merr := notesService.Mentions(notes.MentionsRequest{})

			if tlerr != nil {
				fmt.Println(tlerr.Error())
			}
			if merr != nil {
				fmt.Println(merr.Error())
			}

			// check the cache for everything we just collected
			// if anything is newer or as of yet not in the cache, add it
			// and convert it to a SocketData implementation before sending on data channel
			for _, n := range tlnotes {
				fmt.Println(n.ID)
				// check existence and cache
				// convert
				// send
			}
			for _, n := range mentions {
				fmt.Println(n.ID)
				// check existence and cache
				// convert
				// send
			}
		}

	}()

	return nil
}

func (self *MisskeyAdapter) Fetch(query string) error {
	return nil
}

func (self *MisskeyAdapter) Do(action string) error {
	return nil
}