underbbs/adapter/adapter.go

128 lines
2.7 KiB
Go
Raw Normal View History

2024-05-10 04:14:40 +00:00
package adapter
import (
2024-05-19 20:42:28 +00:00
"context"
"encoding/json"
"errors"
"fmt"
2024-05-10 04:14:40 +00:00
. "forge.lightcrystal.systems/lightcrystal/underbbs/models"
2024-05-13 00:26:44 +00:00
nostr "github.com/nbd-wtf/go-nostr"
"strings"
2024-05-10 04:14:40 +00:00
)
type Adapter interface {
2024-05-19 20:42:28 +00:00
Init(Settings, chan SocketData) error
Subscribe(string) []error
2024-05-10 04:14:40 +00:00
SendMessage(Message) error
Follow(Author) error
Unfollow(Author) error
GetFollowers() error
UpdateMetadata(interface{}) error
2024-05-26 18:50:19 +00:00
DefaultSubscriptionFilter() string
2024-05-10 04:14:40 +00:00
}
2024-05-13 00:26:44 +00:00
type NostrAdapter struct {
2024-06-02 16:17:12 +00:00
data chan SocketData
2024-05-19 20:42:28 +00:00
nickname string
privkey string
relays []*nostr.Relay
}
2024-06-02 16:17:12 +00:00
func (self *NostrAdapter) Init(settings Settings, data chan SocketData) error {
2024-05-19 20:42:28 +00:00
self.nickname = settings.Nickname
self.privkey = *settings.PrivKey
2024-06-02 16:17:12 +00:00
self.data = data
2024-05-19 20:42:28 +00:00
ctx := context.Background()
2024-06-02 16:17:12 +00:00
for _, r := range settings.Relays {
2024-05-19 20:42:28 +00:00
pr, _ := nostr.RelayConnect(ctx, strings.Trim(r, " "))
if pr == nil {
return errors.New("Relay connection could not be completed")
}
self.relays = append(self.relays, pr)
}
return nil
}
func (self *NostrAdapter) Subscribe(filter string) []error {
var filters nostr.Filters
err := json.Unmarshal([]byte(filter), &filters)
if err != nil {
return []error{err}
}
2024-06-02 16:17:12 +00:00
errs := make([]error, 0)
2024-05-19 20:42:28 +00:00
2024-06-02 16:17:12 +00:00
fmt.Print("unmarshalled filter from json; iterating through relays to subscribe..")
2024-05-19 20:42:28 +00:00
2024-06-02 16:17:12 +00:00
for _, r := range self.relays {
fmt.Print(".")
2024-05-19 20:42:28 +00:00
sub, err := r.Subscribe(context.Background(), filters)
if err != nil {
errs = append(errs, err)
} else {
go func() {
for ev := range sub.Events {
2024-06-02 16:17:12 +00:00
fmt.Print("!")
2024-05-19 20:42:28 +00:00
// try sequentially to encode into an underbbs object
// and send it to the appropriate channel
m, err := nostrEventToMsg(ev)
if err == nil {
2024-06-02 16:17:12 +00:00
self.data <- m
2024-05-19 20:42:28 +00:00
}
}
}()
}
2024-06-02 16:17:12 +00:00
fmt.Println()
2024-05-19 20:42:28 +00:00
}
if len(errs) > 0 {
2024-06-02 16:17:12 +00:00
fmt.Println("subscription operation completed with errors")
2024-05-19 20:42:28 +00:00
return errs
}
2024-06-02 16:17:12 +00:00
fmt.Println("subscription operation completed without errors")
2024-05-19 20:42:28 +00:00
return nil
}
func (self *NostrAdapter) SendMessage(msg Message) error {
return nil
}
func (self *NostrAdapter) Follow(author Author) error {
return nil
}
func (self *NostrAdapter) Unfollow(author Author) error {
return nil
}
func (self *NostrAdapter) GetFollowers() error {
return nil
2024-05-13 00:26:44 +00:00
}
func (self *NostrAdapter) UpdateMetadata(data interface{}) error {
2024-05-19 20:42:28 +00:00
return nil
}
2024-05-26 18:50:19 +00:00
func (self *NostrAdapter) DefaultSubscriptionFilter() string {
2024-06-02 16:17:12 +00:00
return "[{\"kinds\":[1]}]"
2024-05-26 18:50:19 +00:00
}
2024-05-19 20:42:28 +00:00
func nostrEventToMsg(evt *nostr.Event) (Message, error) {
m := Message{
Protocol: "nostr",
}
if evt == nil {
return m, errors.New("no event")
}
switch evt.Kind {
case nostr.KindTextNote:
m.Uri = evt.ID
m.Author = Author{
Id: evt.PubKey,
}
m.Created = evt.CreatedAt.Time()
m.Content = evt.Content
return m, nil
default:
return m, errors.New(fmt.Sprintf("unsupported event kind: %d", evt.Kind))
}
}