Skip to content

Commit db71efa

Browse files
feat(api): manual updates
1 parent 589a68b commit db71efa

File tree

7 files changed

+143
-150
lines changed

7 files changed

+143
-150
lines changed

.stats.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 15
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-953cbc1ea1fe675bf2d32b18030a3ac509c521946921cb338c0d1c2cfef89424.yml
3-
openapi_spec_hash: b4d08ca2dc21bc00245c9c9408be89ef
4-
config_hash: 4fb2010b528ce4358300ddd10e750265
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-803a4423d75f7a43582319924f0770153fd5ec313b9466c290513b9a891c2653.yml
3+
openapi_spec_hash: f32dfbf172bb043fd8c961cba5f73765
4+
config_hash: 738402ade5ac9528c8ef1677aa1d70f7

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,42 @@ This library provides some conveniences for working with paginated list endpoint
282282

283283
You can use `.ListAutoPaging()` methods to iterate through items across all pages:
284284

285+
```go
286+
iter := client.Messages.SearchAutoPaging(context.TODO(), beeperdesktopapi.MessageSearchParams{
287+
AccountIDs: []string{"local-telegram_ba_QFrb5lrLPhO3OT5MFBeTWv0x4BI"},
288+
Limit: beeperdesktopapi.Int(10),
289+
Query: beeperdesktopapi.String("deployment"),
290+
})
291+
// Automatically fetches more pages as needed.
292+
for iter.Next() {
293+
message := iter.Current()
294+
fmt.Printf("%+v\n", message)
295+
}
296+
if err := iter.Err(); err != nil {
297+
panic(err.Error())
298+
}
299+
```
300+
285301
Or you can use simple `.List()` methods to fetch a single page and receive a standard response object
286302
with additional helper methods like `.GetNextPage()`, e.g.:
287303

304+
```go
305+
page, err := client.Messages.Search(context.TODO(), beeperdesktopapi.MessageSearchParams{
306+
AccountIDs: []string{"local-telegram_ba_QFrb5lrLPhO3OT5MFBeTWv0x4BI"},
307+
Limit: beeperdesktopapi.Int(10),
308+
Query: beeperdesktopapi.String("deployment"),
309+
})
310+
for page != nil {
311+
for _, message := range page.Items {
312+
fmt.Printf("%+v\n", message)
313+
}
314+
page, err = page.GetNextPage()
315+
}
316+
if err != nil {
317+
panic(err.Error())
318+
}
319+
```
320+
288321
### Errors
289322

290323
When the API returns a non-success status code, we return an error with type

api.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,10 @@ Methods:
6767

6868
Response Types:
6969

70-
- <a href="https://pkg.go.dev/github.com/beeper/desktop-api-go">beeperdesktopapi</a>.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#MessageSearchResponse">MessageSearchResponse</a>
7170
- <a href="https://pkg.go.dev/github.com/beeper/desktop-api-go">beeperdesktopapi</a>.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#MessageSendResponse">MessageSendResponse</a>
7271

7372
Methods:
7473

7574
- <code title="get /v1/messages">client.Messages.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#MessageService.List">List</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, query <a href="https://pkg.go.dev/github.com/beeper/desktop-api-go">beeperdesktopapi</a>.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#MessageListParams">MessageListParams</a>) (<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go/packages/pagination">pagination</a>.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go/packages/pagination#Cursor">Cursor</a>[<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go/shared">shared</a>.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go/shared#Message">Message</a>], <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
76-
- <code title="get /v1/messages/search">client.Messages.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#MessageService.Search">Search</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, query <a href="https://pkg.go.dev/github.com/beeper/desktop-api-go">beeperdesktopapi</a>.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#MessageSearchParams">MessageSearchParams</a>) (<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go">beeperdesktopapi</a>.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#MessageSearchResponse">MessageSearchResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
75+
- <code title="get /v1/messages/search">client.Messages.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#MessageService.Search">Search</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, query <a href="https://pkg.go.dev/github.com/beeper/desktop-api-go">beeperdesktopapi</a>.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#MessageSearchParams">MessageSearchParams</a>) (<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go/packages/pagination">pagination</a>.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go/packages/pagination#Cursor">Cursor</a>[<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go/shared">shared</a>.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go/shared#Message">Message</a>], <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
7776
- <code title="post /v1/messages">client.Messages.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#MessageService.Send">Send</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, body <a href="https://pkg.go.dev/github.com/beeper/desktop-api-go">beeperdesktopapi</a>.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#MessageSendParams">MessageSendParams</a>) (<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go">beeperdesktopapi</a>.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#MessageSendResponse">MessageSendResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>

message.go

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,26 @@ func (r *MessageService) ListAutoPaging(ctx context.Context, query MessageListPa
6363
}
6464

6565
// Search messages across chats using Beeper's message index
66-
func (r *MessageService) Search(ctx context.Context, query MessageSearchParams, opts ...option.RequestOption) (res *MessageSearchResponse, err error) {
66+
func (r *MessageService) Search(ctx context.Context, query MessageSearchParams, opts ...option.RequestOption) (res *pagination.Cursor[shared.Message], err error) {
67+
var raw *http.Response
6768
opts = append(r.Options[:], opts...)
69+
opts = append([]option.RequestOption{option.WithResponseInto(&raw)}, opts...)
6870
path := "v1/messages/search"
69-
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...)
70-
return
71+
cfg, err := requestconfig.NewRequestConfig(ctx, http.MethodGet, path, query, &res, opts...)
72+
if err != nil {
73+
return nil, err
74+
}
75+
err = cfg.Execute()
76+
if err != nil {
77+
return nil, err
78+
}
79+
res.SetPageConfig(cfg, raw)
80+
return res, nil
81+
}
82+
83+
// Search messages across chats using Beeper's message index
84+
func (r *MessageService) SearchAutoPaging(ctx context.Context, query MessageSearchParams, opts ...option.RequestOption) *pagination.CursorAutoPager[shared.Message] {
85+
return pagination.NewCursorAutoPager(r.Search(ctx, query, opts...))
7186
}
7287

7388
// Send a text message to a specific chat. Supports replying to existing messages.
@@ -79,37 +94,6 @@ func (r *MessageService) Send(ctx context.Context, body MessageSendParams, opts
7994
return
8095
}
8196

82-
type MessageSearchResponse struct {
83-
// Map of chatID -> chat details for chats referenced in items.
84-
Chats map[string]Chat `json:"chats,required"`
85-
// True if additional results can be fetched using the provided cursors.
86-
HasMore bool `json:"hasMore,required"`
87-
// Messages matching the query and filters.
88-
Items []shared.Message `json:"items,required"`
89-
// Cursor for fetching newer results (use with direction='after'). Opaque string;
90-
// do not inspect.
91-
NewestCursor string `json:"newestCursor,required"`
92-
// Cursor for fetching older results (use with direction='before'). Opaque string;
93-
// do not inspect.
94-
OldestCursor string `json:"oldestCursor,required"`
95-
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
96-
JSON struct {
97-
Chats respjson.Field
98-
HasMore respjson.Field
99-
Items respjson.Field
100-
NewestCursor respjson.Field
101-
OldestCursor respjson.Field
102-
ExtraFields map[string]respjson.Field
103-
raw string
104-
} `json:"-"`
105-
}
106-
107-
// Returns the unmodified JSON received from the API
108-
func (r MessageSearchResponse) RawJSON() string { return r.JSON.raw }
109-
func (r *MessageSearchResponse) UnmarshalJSON(data []byte) error {
110-
return apijson.UnmarshalRoot(data, r)
111-
}
112-
11397
type MessageSendResponse struct {
11498
// Unique identifier of the chat.
11599
ChatID string `json:"chatID,required"`

packages/pagination/pagination.go

Lines changed: 0 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ package pagination
55
import (
66
"net/http"
77

8-
"github.com/beeper/desktop-api-go"
98
"github.com/beeper/desktop-api-go/internal/apijson"
109
"github.com/beeper/desktop-api-go/internal/requestconfig"
1110
"github.com/beeper/desktop-api-go/option"
@@ -126,113 +125,3 @@ func (r *CursorAutoPager[T]) Err() error {
126125
func (r *CursorAutoPager[T]) Index() int {
127126
return r.run
128127
}
129-
130-
type CursorWithChats[T any] struct {
131-
Items []T `json:"items"`
132-
Chats map[string]beeperdesktopapi.Chat `json:"chats"`
133-
HasMore bool `json:"hasMore"`
134-
OldestCursor string `json:"oldestCursor,nullable"`
135-
NewestCursor string `json:"newestCursor,nullable"`
136-
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
137-
JSON struct {
138-
Items respjson.Field
139-
Chats respjson.Field
140-
HasMore respjson.Field
141-
OldestCursor respjson.Field
142-
NewestCursor respjson.Field
143-
ExtraFields map[string]respjson.Field
144-
raw string
145-
} `json:"-"`
146-
cfg *requestconfig.RequestConfig
147-
res *http.Response
148-
}
149-
150-
// Returns the unmodified JSON received from the API
151-
func (r CursorWithChats[T]) RawJSON() string { return r.JSON.raw }
152-
func (r *CursorWithChats[T]) UnmarshalJSON(data []byte) error {
153-
return apijson.UnmarshalRoot(data, r)
154-
}
155-
156-
// GetNextPage returns the next page as defined by this pagination style. When
157-
// there is no next page, this function will return a 'nil' for the page value, but
158-
// will not return an error
159-
func (r *CursorWithChats[T]) GetNextPage() (res *CursorWithChats[T], err error) {
160-
if len(r.Items) == 0 {
161-
return nil, nil
162-
}
163-
164-
if r.JSON.HasMore.Valid() && r.HasMore == false {
165-
return nil, nil
166-
}
167-
next := r.OldestCursor
168-
if len(next) == 0 {
169-
return nil, nil
170-
}
171-
cfg := r.cfg.Clone(r.cfg.Context)
172-
err = cfg.Apply(option.WithQuery("cursor", next))
173-
if err != nil {
174-
return nil, err
175-
}
176-
var raw *http.Response
177-
cfg.ResponseInto = &raw
178-
cfg.ResponseBodyInto = &res
179-
err = cfg.Execute()
180-
if err != nil {
181-
return nil, err
182-
}
183-
res.SetPageConfig(cfg, raw)
184-
return res, nil
185-
}
186-
187-
func (r *CursorWithChats[T]) SetPageConfig(cfg *requestconfig.RequestConfig, res *http.Response) {
188-
if r == nil {
189-
r = &CursorWithChats[T]{}
190-
}
191-
r.cfg = cfg
192-
r.res = res
193-
}
194-
195-
type CursorWithChatsAutoPager[T any] struct {
196-
page *CursorWithChats[T]
197-
cur T
198-
idx int
199-
run int
200-
err error
201-
paramObj
202-
}
203-
204-
func NewCursorWithChatsAutoPager[T any](page *CursorWithChats[T], err error) *CursorWithChatsAutoPager[T] {
205-
return &CursorWithChatsAutoPager[T]{
206-
page: page,
207-
err: err,
208-
}
209-
}
210-
211-
func (r *CursorWithChatsAutoPager[T]) Next() bool {
212-
if r.page == nil || len(r.page.Items) == 0 {
213-
return false
214-
}
215-
if r.idx >= len(r.page.Items) {
216-
r.idx = 0
217-
r.page, r.err = r.page.GetNextPage()
218-
if r.err != nil || r.page == nil || len(r.page.Items) == 0 {
219-
return false
220-
}
221-
}
222-
r.cur = r.page.Items[r.idx]
223-
r.run += 1
224-
r.idx += 1
225-
return true
226-
}
227-
228-
func (r *CursorWithChatsAutoPager[T]) Current() T {
229-
return r.cur
230-
}
231-
232-
func (r *CursorWithChatsAutoPager[T]) Err() error {
233-
return r.err
234-
}
235-
236-
func (r *CursorWithChatsAutoPager[T]) Index() int {
237-
return r.run
238-
}

paginationauto_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package beeperdesktopapi_test
4+
5+
import (
6+
"context"
7+
"os"
8+
"testing"
9+
10+
"github.com/beeper/desktop-api-go"
11+
"github.com/beeper/desktop-api-go/internal/testutil"
12+
"github.com/beeper/desktop-api-go/option"
13+
)
14+
15+
func TestAutoPagination(t *testing.T) {
16+
baseURL := "http://localhost:4010"
17+
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
18+
baseURL = envURL
19+
}
20+
if !testutil.CheckTestServer(t, baseURL) {
21+
return
22+
}
23+
client := beeperdesktopapi.NewClient(
24+
option.WithBaseURL(baseURL),
25+
option.WithAccessToken("My Access Token"),
26+
)
27+
iter := client.Messages.SearchAutoPaging(context.TODO(), beeperdesktopapi.MessageSearchParams{
28+
AccountIDs: []string{"local-telegram_ba_QFrb5lrLPhO3OT5MFBeTWv0x4BI"},
29+
Limit: beeperdesktopapi.Int(10),
30+
Query: beeperdesktopapi.String("deployment"),
31+
})
32+
// Prism mock isn't going to give us real pagination
33+
for i := 0; i < 3 && iter.Next(); i++ {
34+
message := iter.Current()
35+
t.Logf("%+v\n", message.ID)
36+
}
37+
if err := iter.Err(); err != nil {
38+
t.Fatalf("err should be nil: %s", err.Error())
39+
}
40+
}

paginationmanual_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package beeperdesktopapi_test
4+
5+
import (
6+
"context"
7+
"os"
8+
"testing"
9+
10+
"github.com/beeper/desktop-api-go"
11+
"github.com/beeper/desktop-api-go/internal/testutil"
12+
"github.com/beeper/desktop-api-go/option"
13+
)
14+
15+
func TestManualPagination(t *testing.T) {
16+
baseURL := "http://localhost:4010"
17+
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
18+
baseURL = envURL
19+
}
20+
if !testutil.CheckTestServer(t, baseURL) {
21+
return
22+
}
23+
client := beeperdesktopapi.NewClient(
24+
option.WithBaseURL(baseURL),
25+
option.WithAccessToken("My Access Token"),
26+
)
27+
page, err := client.Messages.Search(context.TODO(), beeperdesktopapi.MessageSearchParams{
28+
AccountIDs: []string{"local-telegram_ba_QFrb5lrLPhO3OT5MFBeTWv0x4BI"},
29+
Limit: beeperdesktopapi.Int(10),
30+
Query: beeperdesktopapi.String("deployment"),
31+
})
32+
if err != nil {
33+
t.Fatalf("err should be nil: %s", err.Error())
34+
}
35+
for _, message := range page.Items {
36+
t.Logf("%+v\n", message.ID)
37+
}
38+
// Prism mock isn't going to give us real pagination
39+
page, err = page.GetNextPage()
40+
if err != nil {
41+
t.Fatalf("err should be nil: %s", err.Error())
42+
}
43+
if page != nil {
44+
for _, message := range page.Items {
45+
t.Logf("%+v\n", message.ID)
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)