Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.2.1"
".": "0.3.0"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 19
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-099d55ac0e749a64dacc1706d7d8276d1acbe52103f0419393c39e8911966cfe.yml
openapi_spec_hash: 70a1b1d513b62c6d6caabbbf360220b4
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-3f6555bfea11258c6e8882455360ae08202067a270313716ee15571b83ada577.yml
openapi_spec_hash: 020324a708981384284f8fad8ac8c66c
config_hash: 48ff2d23c2ebc82bd3c15787f0041684
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 0.3.0 (2026-02-13)

Full Changelog: [v0.2.1...v0.3.0](https://github.com/beeper/desktop-api-go/compare/v0.2.1...v0.3.0)

### Features

* **api:** add reactions ([cb4b3e1](https://github.com/beeper/desktop-api-go/commit/cb4b3e1606a309e3c21d929998b99e30483f97b3))

## 0.2.1 (2026-02-11)

Full Changelog: [v0.2.0...v0.2.1](https://github.com/beeper/desktop-api-go/compare/v0.2.0...v0.2.1)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Or to pin the version:
<!-- x-release-please-start-version -->

```sh
go get -u 'github.com/beeper/desktop-api-go@v0.2.1'
go get -u 'github.com/beeper/desktop-api-go@v0.3.0'
```

<!-- x-release-please-end -->
Expand Down
2 changes: 2 additions & 0 deletions account.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ type Account struct {
// Chat account added to Beeper. Use this to route account-scoped actions.
AccountID string `json:"accountID,required"`
// Display-only human-readable network name (e.g., 'WhatsApp', 'Messenger').
//
// Deprecated: deprecated
Network string `json:"network,required"`
// User the account belongs to.
User shared.User `json:"user,required"`
Expand Down
4 changes: 2 additions & 2 deletions accountcontact.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ func NewAccountContactService(opts ...option.RequestOption) (r AccountContactSer
return
}

// Search contacts on a specific account using the network's search API. Only use
// for creating new chats.
// Search contacts on a specific account using merged account contacts, network
// search, and exact identifier lookup.
func (r *AccountContactService) Search(ctx context.Context, accountID string, query AccountContactSearchParams, opts ...option.RequestOption) (res *AccountContactSearchResponse, err error) {
opts = slices.Concat(r.Options, opts)
if accountID == "" {
Expand Down
12 changes: 3 additions & 9 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,27 +44,21 @@ Response Types:
- <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#Chat">Chat</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#ChatNewResponse">ChatNewResponse</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#ChatListResponse">ChatListResponse</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#ChatArchiveResponse">ChatArchiveResponse</a>

Methods:

- <code title="post /v1/chats">client.Chats.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#ChatService.New">New</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#ChatNewParams">ChatNewParams</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#ChatNewResponse">ChatNewResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /v1/chats/{chatID}">client.Chats.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#ChatService.Get">Get</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, chatID <a href="https://pkg.go.dev/builtin#string">string</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#ChatGetParams">ChatGetParams</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#Chat">Chat</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /v1/chats">client.Chats.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#ChatService.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#ChatListParams">ChatListParams</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#CursorNoLimit">CursorNoLimit</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#ChatListResponse">ChatListResponse</a>], <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="post /v1/chats/{chatID}/archive">client.Chats.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#ChatService.Archive">Archive</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, chatID <a href="https://pkg.go.dev/builtin#string">string</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#ChatArchiveParams">ChatArchiveParams</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#ChatArchiveResponse">ChatArchiveResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="post /v1/chats/{chatID}/archive">client.Chats.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#ChatService.Archive">Archive</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, chatID <a href="https://pkg.go.dev/builtin#string">string</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#ChatArchiveParams">ChatArchiveParams</a>) <a href="https://pkg.go.dev/builtin#error">error</a></code>
- <code title="get /v1/chats/search">client.Chats.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#ChatService.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#ChatSearchParams">ChatSearchParams</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#CursorSearch">CursorSearch</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#Chat">Chat</a>], <a href="https://pkg.go.dev/builtin#error">error</a>)</code>

## Reminders

Response Types:

- <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#ChatReminderNewResponse">ChatReminderNewResponse</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#ChatReminderDeleteResponse">ChatReminderDeleteResponse</a>

Methods:

- <code title="post /v1/chats/{chatID}/reminders">client.Chats.Reminders.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#ChatReminderService.New">New</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, chatID <a href="https://pkg.go.dev/builtin#string">string</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#ChatReminderNewParams">ChatReminderNewParams</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#ChatReminderNewResponse">ChatReminderNewResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="delete /v1/chats/{chatID}/reminders">client.Chats.Reminders.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#ChatReminderService.Delete">Delete</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, chatID <a href="https://pkg.go.dev/builtin#string">string</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#ChatReminderDeleteResponse">ChatReminderDeleteResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="post /v1/chats/{chatID}/reminders">client.Chats.Reminders.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#ChatReminderService.New">New</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, chatID <a href="https://pkg.go.dev/builtin#string">string</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#ChatReminderNewParams">ChatReminderNewParams</a>) <a href="https://pkg.go.dev/builtin#error">error</a></code>
- <code title="delete /v1/chats/{chatID}/reminders">client.Chats.Reminders.<a href="https://pkg.go.dev/github.com/beeper/desktop-api-go#ChatReminderService.Delete">Delete</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, chatID <a href="https://pkg.go.dev/builtin#string">string</a>) <a href="https://pkg.go.dev/builtin#error">error</a></code>

# Messages

Expand Down
88 changes: 58 additions & 30 deletions chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ func NewChatService(opts ...option.RequestOption) (r ChatService) {
return
}

// Create a single or group chat on a specific account using participant IDs and
// optional title.
// Create a single/group chat (mode='create') or start a direct chat from merged
// user data (mode='start').
func (r *ChatService) New(ctx context.Context, body ChatNewParams, opts ...option.RequestOption) (res *ChatNewResponse, err error) {
opts = slices.Concat(r.Options, opts)
path := "v1/chats"
Expand Down Expand Up @@ -93,14 +93,15 @@ func (r *ChatService) ListAutoPaging(ctx context.Context, query ChatListParams,

// Archive or unarchive a chat. Set archived=true to move to archive,
// archived=false to move back to inbox
func (r *ChatService) Archive(ctx context.Context, chatID string, body ChatArchiveParams, opts ...option.RequestOption) (res *ChatArchiveResponse, err error) {
func (r *ChatService) Archive(ctx context.Context, chatID string, body ChatArchiveParams, opts ...option.RequestOption) (err error) {
opts = slices.Concat(r.Options, opts)
opts = append([]option.RequestOption{option.WithHeader("Accept", "*/*")}, opts...)
if chatID == "" {
err = errors.New("missing required chatID parameter")
return
}
path := fmt.Sprintf("v1/chats/%s/archive", chatID)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, nil, opts...)
return
}

Expand Down Expand Up @@ -134,6 +135,10 @@ type Chat struct {
ID string `json:"id,required"`
// Account ID this chat belongs to.
AccountID string `json:"accountID,required"`
// Display-only human-readable network name (e.g., 'WhatsApp', 'Messenger').
//
// Deprecated: deprecated
Network string `json:"network,required"`
// Chat participants information.
Participants ChatParticipants `json:"participants,required"`
// Display title of the chat as computed by the client/server.
Expand All @@ -160,6 +165,7 @@ type Chat struct {
JSON struct {
ID respjson.Field
AccountID respjson.Field
Network respjson.Field
Participants respjson.Field
Title respjson.Field
Type respjson.Field
Expand Down Expand Up @@ -216,9 +222,15 @@ const (
type ChatNewResponse struct {
// Newly created chat ID.
ChatID string `json:"chatID,required"`
// Only returned in start mode. 'existing' means an existing chat was reused;
// 'created' means a new chat was created.
//
// Any of "existing", "created".
Status ChatNewResponseStatus `json:"status"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
ChatID respjson.Field
Status respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
Expand All @@ -230,6 +242,15 @@ func (r *ChatNewResponse) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

// Only returned in start mode. 'existing' means an existing chat was reused;
// 'created' means a new chat was created.
type ChatNewResponseStatus string

const (
ChatNewResponseStatusExisting ChatNewResponseStatus = "existing"
ChatNewResponseStatusCreated ChatNewResponseStatus = "created"
)

type ChatListResponse struct {
// Last message preview for this chat, if available.
Preview shared.Message `json:"preview"`
Expand All @@ -248,26 +269,29 @@ func (r *ChatListResponse) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

type ChatArchiveResponse struct {
// Indicates the operation completed successfully
type ChatNewParams struct {

//
// Any of true.
Success bool `json:"success,required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Success respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
// Request body variants
//

// This field is a request body variant, only one variant field can be set.
OfObject *ChatNewParamsBodyObject `json:",inline"`
// This field is a request body variant, only one variant field can be set.
OfChatNewsBodyObject *ChatNewParamsBodyObject `json:",inline"`

paramObj
}

// Returns the unmodified JSON received from the API
func (r ChatArchiveResponse) RawJSON() string { return r.JSON.raw }
func (r *ChatArchiveResponse) UnmarshalJSON(data []byte) error {
func (u ChatNewParams) MarshalJSON() ([]byte, error) {
return param.MarshalUnion(u, u.OfObject, u.OfChatNewsBodyObject)
}
func (r *ChatNewParams) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

type ChatNewParams struct {
// The properties AccountID, ParticipantIDs, Type are required.
type ChatNewParamsBodyObject struct {
// Account to create the chat on.
AccountID string `json:"accountID,required"`
// User IDs to include in the new chat.
Expand All @@ -276,30 +300,34 @@ type ChatNewParams struct {
// supports multiple participants and optional title.
//
// Any of "single", "group".
Type ChatNewParamsType `json:"type,omitzero,required"`
Type string `json:"type,omitzero,required"`
// Optional first message content if the platform requires it to create the chat.
MessageText param.Opt[string] `json:"messageText,omitzero"`
// Optional title for group chats; ignored for single chats on most platforms.
Title param.Opt[string] `json:"title,omitzero"`
// Create mode. Defaults to 'create' when omitted.
//
// Any of "create".
Mode string `json:"mode,omitzero"`
paramObj
}

func (r ChatNewParams) MarshalJSON() (data []byte, err error) {
type shadow ChatNewParams
func (r ChatNewParamsBodyObject) MarshalJSON() (data []byte, err error) {
type shadow ChatNewParamsBodyObject
return param.MarshalObject(r, (*shadow)(&r))
}
func (r *ChatNewParams) UnmarshalJSON(data []byte) error {
func (r *ChatNewParamsBodyObject) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

// Chat type to create: 'single' requires exactly one participantID; 'group'
// supports multiple participants and optional title.
type ChatNewParamsType string

const (
ChatNewParamsTypeSingle ChatNewParamsType = "single"
ChatNewParamsTypeGroup ChatNewParamsType = "group"
)
func init() {
apijson.RegisterFieldValidator[ChatNewParamsBodyObject](
"type", "single", "group",
)
apijson.RegisterFieldValidator[ChatNewParamsBodyObject](
"mode", "create",
)
}

type ChatGetParams struct {
// Maximum number of participants to return. Use -1 for all; otherwise 0–500.
Expand Down
15 changes: 9 additions & 6 deletions chat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@ func TestChatNewWithOptionalParams(t *testing.T) {
option.WithAccessToken("My Access Token"),
)
_, err := client.Chats.New(context.TODO(), beeperdesktopapi.ChatNewParams{
AccountID: "accountID",
ParticipantIDs: []string{"string"},
Type: beeperdesktopapi.ChatNewParamsTypeSingle,
MessageText: beeperdesktopapi.String("messageText"),
Title: beeperdesktopapi.String("title"),
OfObject: &beeperdesktopapi.ChatNewParamsBodyObject{
AccountID: "accountID",
ParticipantIDs: []string{"string"},
Type: "single",
MessageText: beeperdesktopapi.String("messageText"),
Mode: "create",
Title: beeperdesktopapi.String("title"),
},
})
if err != nil {
var apierr *beeperdesktopapi.Error
Expand Down Expand Up @@ -108,7 +111,7 @@ func TestChatArchiveWithOptionalParams(t *testing.T) {
option.WithBaseURL(baseURL),
option.WithAccessToken("My Access Token"),
)
_, err := client.Chats.Archive(
err := client.Chats.Archive(
context.TODO(),
"!NCdzlIaMjZUmvmvyHU:beeper.com",
beeperdesktopapi.ChatArchiveParams{
Expand Down
Loading