tinyrelayfile
tinyrelay/internal/daemon/direct_messages.go/

internal/daemon/direct_messages.go raw
1package daemon
2
3import (
4 "context"
5 "encoding/json"
6 "errors"
7 "fmt"
8 "time"
9
10 "github.com/FelineStateMachine/tinyrelay/internal/event"
11 "github.com/FelineStateMachine/tinyrelay/internal/relay"
12 "github.com/FelineStateMachine/tinyrelay/internal/storage"
13)
14
15type directMessagesRequest struct {
16 Cursor string `json:"cursor"`
17 Limit int `json:"limit"`
18}
19
20func directMessagesBrowseMethod(method string) bool { return method == "browsedirectmessages" }
21
22func (t *Tenant) executeDirectMessages(ctx context.Context, actor string, params []json.RawMessage) (any, error) {
23 if actor == "" || !hex64(actor) {
24 return nil, errors.New("auth-required: signed actor")
25 }
26 request := directMessagesRequest{Limit: 50}
27 if len(params) > 0 {
28 if err := json.Unmarshal(params[0], &request); err != nil {
29 return nil, fmt.Errorf("invalid: direct message parameters: %w", err)
30 }
31 }
32 if request.Limit <= 0 || request.Limit > 100 {
33 request.Limit = 50
34 }
35 cursor, err := parseCollaborationCursor(request.Cursor)
36 if err != nil {
37 return nil, errors.New("invalid: direct message cursor")
38 }
39 return t.browseDirectMessages(ctx, actor, cursor, request.Limit)
40}
41
42func (t *Tenant) browseDirectMessages(ctx context.Context, actor string, cursor *storage.EventCursor, limit int) (any, error) {
43 filter := event.Filter{Kinds: []int{event.KIND_WRAP}, Tags: map[string][]string{"p": {actor}}}
44 session := relay.Session{PubKeys: []string{actor}, RelayURL: t.RelayURL()}
45 if _, err := t.gate.Read(ctx, []event.Filter{filter}, session); err != nil {
46 return nil, err
47 }
48 rows := make([]event.Event, 0, limit)
49 next := ""
50 for scans := 0; scans < 100; scans++ {
51 page, err := t.store.Query(ctx, filter, storage.QueryOptions{Now: time.Now().Unix(), Access: storage.Access{PubKeys: []string{actor}}, Limit: 100, Before: cursor})
52 if err != nil {
53 return nil, err
54 }
55 for index, row := range page.Events {
56 cursor = &storage.EventCursor{CreatedAt: row.CreatedAt, ID: row.ID}
57 if !t.gate.CanSee(ctx, row, session, &filter) {
58 continue
59 }
60 rows = append(rows, row)
61 if len(rows) == limit {
62 if page.More || index+1 < len(page.Events) {
63 next = collaborationCursor(collaborationItem{CreatedAt: row.CreatedAt, ID: row.ID})
64 }
65 return map[string]any{"events": rows, "next_cursor": next}, nil
66 }
67 }
68 if !page.More || len(page.Events) == 0 {
69 return map[string]any{"events": rows, "next_cursor": ""}, nil
70 }
71 }
72 if cursor != nil {
73 next = collaborationCursor(collaborationItem{CreatedAt: cursor.CreatedAt, ID: cursor.ID})
74 }
75 return map[string]any{"events": rows, "next_cursor": next}, nil
76}

About

ownerc01503e8035f
visibilitypublic
headd730679639bf

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

  • https://012.run/npub1cq2s86qrtadf36eqq3epm38wmhdynrrcwxf84eldk3f94dkv7ttsrulrz5/tinyrelay.git

Refs