Documentation
¶
Overview ¶
Package hey provides a Go SDK for the HEY API.
The SDK handles authentication, HTTP caching, rate limiting, and retry logic. It supports both OAuth 2.0 authentication and static token authentication.
Installation ¶
To install the SDK, use go get:
go get github.com/basecamp/hey-sdk/go/pkg/hey
Authentication ¶
The SDK supports two authentication methods:
Static Token Authentication (simplest):
cfg := hey.DefaultConfig()
token := &hey.StaticTokenProvider{Token: os.Getenv("HEY_TOKEN")}
client := hey.NewClient(cfg, token)
OAuth 2.0 Authentication (for user-facing apps):
cfg := hey.DefaultConfig() authMgr := hey.NewAuthManager(cfg, http.DefaultClient) client := hey.NewClient(cfg, authMgr)
Services ¶
The SDK provides typed services for each HEY resource:
- Client.Identity - Current user identity and navigation
- Client.Boxes - Mailboxes (imbox, feedbox, etc.)
- Client.Topics - Email topics and views (sent, spam, trash, everything)
- Client.Messages - Individual messages
- Client.Entries - Drafts and replies
- Client.Contacts - Contact management
- Client.Calendars - Calendar views and recordings
- Client.CalendarTodos - Calendar todo items
- Client.Habits - Habit tracking
- Client.TimeTracks - Time tracking
- Client.Journal - Journal entries
- Client.Search - Full-text search
Working with Boxes ¶
List all mailboxes:
boxes, err := client.Boxes().List(ctx)
if err != nil {
log.Fatal(err)
}
for _, b := range boxes {
fmt.Println(b.Name)
}
Pagination ¶
The SDK handles pagination automatically via FollowPagination:
resp, err := client.Contacts().List(ctx, nil) // The SDK follows Link headers for pagination
Error Handling ¶
The SDK returns typed errors that can be inspected:
_, err := client.Boxes().Get(ctx, 999)
if err != nil {
var apiErr *hey.Error
if errors.As(err, &apiErr) {
switch apiErr.Code {
case hey.CodeNotFound:
// Handle 404
case hey.CodeAuth:
// Handle authentication error
case hey.CodeRateLimit:
// Handle rate limiting (auto-retried by default)
}
}
}
Thread Safety ¶
The Client is safe for concurrent use after construction. Service accessors (e.g., client.Boxes()) use mutex-protected lazy initialization.
Index ¶
- Constants
- Variables
- func CheckResponse(resp *http.Response) error
- func ExitCodeFor(code string) int
- func NormalizeBaseURL(url string) string
- func RedactHeaders(headers http.Header) http.Header
- func RequireSecureEndpoint(rawURL string) error
- type AuthManager
- func (m *AuthManager) AccessToken(ctx context.Context) (string, error)
- func (m *AuthManager) GetUserID() string
- func (m *AuthManager) IsAuthenticated() bool
- func (m *AuthManager) Logout() error
- func (m *AuthManager) Refresh(ctx context.Context) error
- func (m *AuthManager) SetUserID(userID string) error
- func (m *AuthManager) Store() *CredentialStore
- type AuthStrategy
- type BearerAuth
- type BoxesService
- func (s *BoxesService) Get(ctx context.Context, boxID int64, params *generated.GetBoxParams) (result *generated.BoxShowResponse, err error)
- func (s *BoxesService) GetAsidebox(ctx context.Context, params *generated.GetAsideboxParams) (result *generated.BoxShowResponse, err error)
- func (s *BoxesService) GetBubblebox(ctx context.Context, params *generated.GetBubbleboxParams) (result *generated.BoxShowResponse, err error)
- func (s *BoxesService) GetFeedbox(ctx context.Context, params *generated.GetFeedboxParams) (result *generated.BoxShowResponse, err error)
- func (s *BoxesService) GetImbox(ctx context.Context, params *generated.GetImboxParams) (result *generated.BoxShowResponse, err error)
- func (s *BoxesService) GetLaterbox(ctx context.Context, params *generated.GetLaterboxParams) (result *generated.BoxShowResponse, err error)
- func (s *BoxesService) GetTrailbox(ctx context.Context, params *generated.GetTrailboxParams) (result *generated.BoxShowResponse, err error)
- func (s *BoxesService) List(ctx context.Context) (result *generated.ListBoxesResponseContent, err error)
- type BulkheadConfig
- type Cache
- type CalendarTodosService
- func (s *CalendarTodosService) Complete(ctx context.Context, todoID int64) (result *generated.Recording, err error)
- func (s *CalendarTodosService) Create(ctx context.Context, title string, startsAt string) (result *generated.Recording, err error)
- func (s *CalendarTodosService) Delete(ctx context.Context, todoID int64) (err error)
- func (s *CalendarTodosService) Uncomplete(ctx context.Context, todoID int64) (result *generated.Recording, err error)
- type CalendarsService
- type ChainHooks
- func (c *ChainHooks) OnOperationEnd(ctx context.Context, op OperationInfo, err error, duration time.Duration)
- func (c *ChainHooks) OnOperationGate(ctx context.Context, op OperationInfo) (context.Context, error)
- func (c *ChainHooks) OnOperationStart(ctx context.Context, op OperationInfo) context.Context
- func (c *ChainHooks) OnRequestEnd(ctx context.Context, info RequestInfo, result RequestResult)
- func (c *ChainHooks) OnRequestStart(ctx context.Context, info RequestInfo) context.Context
- func (c *ChainHooks) OnRetry(ctx context.Context, info RequestInfo, attempt int, err error)
- type CircuitBreakerConfig
- type Client
- func (c *Client) Boxes() *BoxesService
- func (c *Client) CalendarTodos() *CalendarTodosService
- func (c *Client) Calendars() *CalendarsService
- func (c *Client) Config() Config
- func (c *Client) Contacts() *ContactsService
- func (c *Client) DefaultSenderID(ctx context.Context) (int64, error)
- func (c *Client) Delete(ctx context.Context, path string) (*Response, error)
- func (c *Client) Entries() *EntriesService
- func (c *Client) FollowPagination(ctx context.Context, httpResp *http.Response, firstPageCount, limit int) ([]json.RawMessage, error)
- func (c *Client) Get(ctx context.Context, path string) (*Response, error)
- func (c *Client) GetAll(ctx context.Context, path string) ([]json.RawMessage, error)
- func (c *Client) GetAllWithLimit(ctx context.Context, path string, limit int) ([]json.RawMessage, error)
- func (c *Client) GetHTML(ctx context.Context, path string) (*Response, error)
- func (c *Client) Habits() *HabitsService
- func (c *Client) Identity() *IdentityService
- func (c *Client) Journal() *JournalService
- func (c *Client) Messages() *MessagesService
- func (c *Client) Patch(ctx context.Context, path string, body any) (*Response, error)
- func (c *Client) PatchMutation(ctx context.Context, path string, body any) (*Response, error)
- func (c *Client) Post(ctx context.Context, path string, body any) (*Response, error)
- func (c *Client) PostMutation(ctx context.Context, path string, body any) (*Response, error)
- func (c *Client) Postings() *PostingsService
- func (c *Client) Put(ctx context.Context, path string, body any) (*Response, error)
- func (c *Client) Search() *SearchService
- func (c *Client) TimeTracks() *TimeTracksService
- func (c *Client) Topics() *TopicsService
- type ClientOption
- func WithAuthStrategy(strategy AuthStrategy) ClientOption
- func WithBaseDelay(d time.Duration) ClientOption
- func WithBulkhead(cfg *BulkheadConfig) ClientOption
- func WithCache(cache *Cache) ClientOption
- func WithCircuitBreaker(cfg *CircuitBreakerConfig) ClientOption
- func WithHTTPClient(c *http.Client) ClientOption
- func WithHooks(hooks Hooks) ClientOption
- func WithLogger(l *slog.Logger) ClientOption
- func WithMaxJitter(d time.Duration) ClientOption
- func WithMaxPages(n int) ClientOption
- func WithMaxRetries(n int) ClientOption
- func WithRateLimit(cfg *RateLimitConfig) ClientOption
- func WithResilience(cfg *ResilienceConfig) ClientOption
- func WithTimeout(d time.Duration) ClientOption
- func WithTransport(t http.RoundTripper) ClientOption
- func WithUserAgent(ua string) ClientOption
- type Config
- type ContactsService
- type CredentialStore
- type Credentials
- type EntriesService
- type Error
- func AsError(err error) *Error
- func ErrAPI(status int, msg string) *Error
- func ErrAmbiguous(resource string, matches []string) *Error
- func ErrAuth(msg string) *Error
- func ErrForbidden(msg string) *Error
- func ErrForbiddenScope() *Error
- func ErrNetwork(cause error) *Error
- func ErrNotFound(resource, identifier string) *Error
- func ErrNotFoundHint(resource, identifier, hint string) *Error
- func ErrRateLimit(retryAfter int) *Error
- func ErrUsage(msg string) *Error
- func ErrUsageHint(msg, hint string) *Error
- type GatingHooks
- type HTTPOptions
- type HabitsService
- type Hooks
- type IdentityService
- type JournalService
- type ListMeta
- type Match
- type MessagesService
- func (s *MessagesService) Create(ctx context.Context, subject, content string, to, cc, bcc []string) (err error)
- func (s *MessagesService) CreateTopicMessage(ctx context.Context, topicID int64, content string) (err error)
- func (s *MessagesService) Get(ctx context.Context, messageID int64) (result *generated.Message, err error)
- type NoopHooks
- func (NoopHooks) OnOperationEnd(context.Context, OperationInfo, error, time.Duration)
- func (NoopHooks) OnOperationStart(ctx context.Context, _ OperationInfo) context.Context
- func (NoopHooks) OnRequestEnd(context.Context, RequestInfo, RequestResult)
- func (NoopHooks) OnRequestStart(ctx context.Context, _ RequestInfo) context.Context
- func (NoopHooks) OnRetry(context.Context, RequestInfo, int, error)
- type OperationInfo
- type PostingsService
- func (s *PostingsService) Ignore(ctx context.Context, postingID int64) error
- func (s *PostingsService) MarkSeen(ctx context.Context, postingIDs []int64) (err error)
- func (s *PostingsService) MarkUnseen(ctx context.Context, postingIDs []int64) (err error)
- func (s *PostingsService) MoveToFeed(ctx context.Context, postingID int64) error
- func (s *PostingsService) MoveToPaperTrail(ctx context.Context, postingID int64) error
- func (s *PostingsService) MoveToReplyLater(ctx context.Context, postingID int64) error
- func (s *PostingsService) MoveToSetAside(ctx context.Context, postingID int64) error
- func (s *PostingsService) MoveToTrash(ctx context.Context, postingID int64) error
- type RateLimitConfig
- type RequestInfo
- type RequestResult
- type ResilienceConfig
- type Response
- type Router
- type SearchService
- type StaticTokenProvider
- type TimeTracksService
- func (s *TimeTracksService) GetOngoing(ctx context.Context) (result *generated.Recording, err error)
- func (s *TimeTracksService) Start(ctx context.Context, body generated.StartTimeTrackJSONRequestBody) (result *generated.Recording, err error)
- func (s *TimeTracksService) Stop(ctx context.Context, timeTrackID int64) (err error)
- func (s *TimeTracksService) Update(ctx context.Context, timeTrackID int64, ...) (result *generated.Recording, err error)
- type TokenProvider
- type TopicsService
- func (s *TopicsService) Get(ctx context.Context, topicID int64) (result *generated.Topic, err error)
- func (s *TopicsService) GetEntries(ctx context.Context, topicID int64, params *generated.GetTopicEntriesParams) (result *generated.GetTopicEntriesResponseContent, err error)
- func (s *TopicsService) GetEverything(ctx context.Context, params *generated.GetEverythingTopicsParams) (result *generated.TopicListResponse, err error)
- func (s *TopicsService) GetSent(ctx context.Context, params *generated.GetSentTopicsParams) (result *generated.TopicListResponse, err error)
- func (s *TopicsService) GetSpam(ctx context.Context, params *generated.GetSpamTopicsParams) (result *generated.TopicListResponse, err error)
- func (s *TopicsService) GetTrash(ctx context.Context, params *generated.GetTrashTopicsParams) (result *generated.TopicListResponse, err error)
Constants ¶
const ( CodeUsage = "usage" CodeNotFound = "not_found" CodeAuth = "auth_required" CodeForbidden = "forbidden" CodeRateLimit = "rate_limit" CodeNetwork = "network" CodeAPI = "api_error" CodeValidation = "validation" CodeAmbiguous = "ambiguous" )
Error codes for API responses.
const ( ExitOK = 0 // Success ExitUsage = 1 // Invalid arguments or flags ExitNotFound = 2 // Resource not found ExitAuth = 3 // Not authenticated ExitForbidden = 4 // Access denied (scope issue) ExitRateLimit = 5 // Rate limited (429) ExitNetwork = 6 // Connection/DNS/timeout error ExitAPI = 7 // Server returned error ExitAmbiguous = 8 // Multiple matches for name ExitValidation = 9 // Validation error (422) )
Exit codes for CLI tools.
const ( DefaultMaxRetries = 3 DefaultBaseDelay = 1 * time.Second DefaultMaxJitter = 100 * time.Millisecond DefaultTimeout = 30 * time.Second DefaultMaxPages = 10000 )
Default values for HTTP client configuration.
const ( // MaxResponseBodyBytes is the maximum size for successful API response bodies (50 MB). MaxResponseBodyBytes int64 = 50 * 1024 * 1024 // MaxErrorBodyBytes is the maximum size for error response bodies (1 MB). MaxErrorBodyBytes int64 = 1 * 1024 * 1024 // MaxErrorMessageBytes is the maximum length for error messages included in errors (500 bytes). MaxErrorMessageBytes = 500 )
Response body size limits.
const APIVersion = "2026-03-04"
APIVersion is the HEY API version this SDK targets.
const DefaultUserAgent = "hey-sdk-go/" + Version + " (api:" + APIVersion + ")"
DefaultUserAgent is the default User-Agent header value.
const Version = "0.1.1"
Version is the current version of the HEY Go SDK.
Variables ¶
var ( // ErrCircuitOpen is returned when the circuit breaker is open. ErrCircuitOpen = errors.New("circuit breaker is open") // ErrBulkheadFull is returned when the bulkhead has no available slots. ErrBulkheadFull = errors.New("bulkhead is full") // ErrRateLimited is returned when the rate limiter rejects a request. ErrRateLimited = errors.New("rate limit exceeded") )
Resilience errors for circuit breaker, bulkhead, and rate limiting.
Functions ¶
func CheckResponse ¶
CheckResponse converts HTTP response errors to SDK errors for non-2xx responses. It is exported for use by conformance testing and consumers using the raw generated client.
func ExitCodeFor ¶
ExitCodeFor returns the exit code for a given error code.
func NormalizeBaseURL ¶
NormalizeBaseURL ensures consistent URL format (no trailing slash).
func RedactHeaders ¶
RedactHeaders returns a copy of the headers with sensitive values replaced by "[REDACTED]".
func RequireSecureEndpoint ¶
RequireSecureEndpoint validates that an endpoint URL is secure.
Types ¶
type AuthManager ¶
type AuthManager struct {
// contains filtered or unexported fields
}
AuthManager handles OAuth token management.
func NewAuthManager ¶
func NewAuthManager(cfg *Config, httpClient *http.Client) *AuthManager
NewAuthManager creates a new auth manager.
func NewAuthManagerWithStore ¶
func NewAuthManagerWithStore(cfg *Config, httpClient *http.Client, store *CredentialStore) *AuthManager
NewAuthManagerWithStore creates an auth manager with a custom credential store.
func (*AuthManager) AccessToken ¶
func (m *AuthManager) AccessToken(ctx context.Context) (string, error)
AccessToken returns a valid access token, refreshing if needed.
func (*AuthManager) GetUserID ¶
func (m *AuthManager) GetUserID() string
GetUserID returns the stored user ID.
func (*AuthManager) IsAuthenticated ¶
func (m *AuthManager) IsAuthenticated() bool
IsAuthenticated checks if there are valid credentials.
func (*AuthManager) Logout ¶
func (m *AuthManager) Logout() error
Logout removes stored credentials.
func (*AuthManager) Refresh ¶
func (m *AuthManager) Refresh(ctx context.Context) error
Refresh forces a token refresh.
func (*AuthManager) SetUserID ¶
func (m *AuthManager) SetUserID(userID string) error
SetUserID stores the user ID.
func (*AuthManager) Store ¶
func (m *AuthManager) Store() *CredentialStore
Store returns the credential store.
type AuthStrategy ¶
type AuthStrategy interface {
// Authenticate applies authentication to the given HTTP request.
Authenticate(ctx context.Context, req *http.Request) error
}
AuthStrategy controls how authentication is applied to HTTP requests. The default strategy is BearerAuth, which uses a TokenProvider to set the Authorization header with a Bearer token.
type BearerAuth ¶
type BearerAuth struct {
TokenProvider TokenProvider
}
BearerAuth implements AuthStrategy using OAuth Bearer tokens. This is the default authentication strategy.
func (*BearerAuth) Authenticate ¶
Authenticate sets the Authorization header with a Bearer token.
type BoxesService ¶
type BoxesService struct {
// contains filtered or unexported fields
}
BoxesService handles mailbox operations.
func NewBoxesService ¶
func NewBoxesService(client *Client) *BoxesService
NewBoxesService creates a new BoxesService.
func (*BoxesService) Get ¶
func (s *BoxesService) Get(ctx context.Context, boxID int64, params *generated.GetBoxParams) (result *generated.BoxShowResponse, err error)
Get returns a specific mailbox by ID.
func (*BoxesService) GetAsidebox ¶
func (s *BoxesService) GetAsidebox(ctx context.Context, params *generated.GetAsideboxParams) (result *generated.BoxShowResponse, err error)
GetAsidebox returns the Set Aside box.
func (*BoxesService) GetBubblebox ¶
func (s *BoxesService) GetBubblebox(ctx context.Context, params *generated.GetBubbleboxParams) (result *generated.BoxShowResponse, err error)
GetBubblebox returns the Bubbled Up box.
func (*BoxesService) GetFeedbox ¶
func (s *BoxesService) GetFeedbox(ctx context.Context, params *generated.GetFeedboxParams) (result *generated.BoxShowResponse, err error)
GetFeedbox returns the Feed.
func (*BoxesService) GetImbox ¶
func (s *BoxesService) GetImbox(ctx context.Context, params *generated.GetImboxParams) (result *generated.BoxShowResponse, err error)
GetImbox returns the Imbox.
func (*BoxesService) GetLaterbox ¶
func (s *BoxesService) GetLaterbox(ctx context.Context, params *generated.GetLaterboxParams) (result *generated.BoxShowResponse, err error)
GetLaterbox returns the Reply Later box.
func (*BoxesService) GetTrailbox ¶
func (s *BoxesService) GetTrailbox(ctx context.Context, params *generated.GetTrailboxParams) (result *generated.BoxShowResponse, err error)
GetTrailbox returns the Paper Trail.
func (*BoxesService) List ¶
func (s *BoxesService) List(ctx context.Context) (result *generated.ListBoxesResponseContent, err error)
List returns all mailboxes.
type BulkheadConfig ¶
BulkheadConfig configures concurrency limiting.
func DefaultBulkheadConfig ¶
func DefaultBulkheadConfig() *BulkheadConfig
DefaultBulkheadConfig returns production-ready defaults.
type Cache ¶
type Cache struct {
// contains filtered or unexported fields
}
Cache provides ETag-based HTTP caching.
func (*Cache) Invalidate ¶
Invalidate removes cached data for a specific key.
type CalendarTodosService ¶
type CalendarTodosService struct {
// contains filtered or unexported fields
}
CalendarTodosService handles calendar todo operations.
func NewCalendarTodosService ¶
func NewCalendarTodosService(client *Client) *CalendarTodosService
NewCalendarTodosService creates a new CalendarTodosService.
func (*CalendarTodosService) Complete ¶
func (s *CalendarTodosService) Complete(ctx context.Context, todoID int64) (result *generated.Recording, err error)
Complete marks a calendar todo as complete.
func (*CalendarTodosService) Create ¶
func (s *CalendarTodosService) Create(ctx context.Context, title string, startsAt string) (result *generated.Recording, err error)
Create creates a new calendar todo.
The HEY API expects the body wrapped as {calendar_todo: {title, starts_at}}. If startsAt is empty, it defaults to today.
func (*CalendarTodosService) Delete ¶
func (s *CalendarTodosService) Delete(ctx context.Context, todoID int64) (err error)
Delete deletes a calendar todo.
func (*CalendarTodosService) Uncomplete ¶
func (s *CalendarTodosService) Uncomplete(ctx context.Context, todoID int64) (result *generated.Recording, err error)
Uncomplete marks a calendar todo as incomplete.
type CalendarsService ¶
type CalendarsService struct {
// contains filtered or unexported fields
}
CalendarsService handles calendar operations.
func NewCalendarsService ¶
func NewCalendarsService(client *Client) *CalendarsService
NewCalendarsService creates a new CalendarsService.
func (*CalendarsService) GetRecordings ¶
func (s *CalendarsService) GetRecordings(ctx context.Context, calendarID int64, params *generated.GetCalendarRecordingsParams) (result *generated.CalendarRecordingsResponse, err error)
GetRecordings returns recordings for a specific calendar.
func (*CalendarsService) List ¶
func (s *CalendarsService) List(ctx context.Context) (result *generated.CalendarListPayload, err error)
List returns all calendars.
type ChainHooks ¶
type ChainHooks struct {
// contains filtered or unexported fields
}
ChainHooks combines multiple Hooks implementations.
func (*ChainHooks) OnOperationEnd ¶
func (c *ChainHooks) OnOperationEnd(ctx context.Context, op OperationInfo, err error, duration time.Duration)
func (*ChainHooks) OnOperationGate ¶
func (c *ChainHooks) OnOperationGate(ctx context.Context, op OperationInfo) (context.Context, error)
func (*ChainHooks) OnOperationStart ¶
func (c *ChainHooks) OnOperationStart(ctx context.Context, op OperationInfo) context.Context
func (*ChainHooks) OnRequestEnd ¶
func (c *ChainHooks) OnRequestEnd(ctx context.Context, info RequestInfo, result RequestResult)
func (*ChainHooks) OnRequestStart ¶
func (c *ChainHooks) OnRequestStart(ctx context.Context, info RequestInfo) context.Context
func (*ChainHooks) OnRetry ¶
func (c *ChainHooks) OnRetry(ctx context.Context, info RequestInfo, attempt int, err error)
type CircuitBreakerConfig ¶
type CircuitBreakerConfig struct {
FailureThreshold int
SuccessThreshold int
OpenTimeout time.Duration
FailureRateThreshold float64
SlidingWindowSize int
Now func() time.Time
}
CircuitBreakerConfig configures the circuit breaker.
func DefaultCircuitBreakerConfig ¶
func DefaultCircuitBreakerConfig() *CircuitBreakerConfig
DefaultCircuitBreakerConfig returns production-ready defaults.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is an HTTP client for the HEY API. Unlike the Basecamp SDK, HEY is user-scoped — services hang directly off Client with no AccountClient or ForAccount indirection.
Client is safe for concurrent use after construction.
func NewClient ¶
func NewClient(cfg *Config, tokenProvider TokenProvider, opts ...ClientOption) *Client
NewClient creates a new API client.
func (*Client) CalendarTodos ¶
func (c *Client) CalendarTodos() *CalendarTodosService
CalendarTodos returns the CalendarTodosService.
func (*Client) Calendars ¶
func (c *Client) Calendars() *CalendarsService
Calendars returns the CalendarsService.
func (*Client) Contacts ¶
func (c *Client) Contacts() *ContactsService
Contacts returns the ContactsService.
func (*Client) DefaultSenderID ¶ added in v0.1.1
DefaultSenderID returns the current user's default sender contact ID. The result is cached after the first successful call. Transient errors are not cached, so subsequent calls will retry the identity fetch. This is required for mutation operations that need an acting_sender_id.
func (*Client) Entries ¶
func (c *Client) Entries() *EntriesService
Entries returns the EntriesService.
func (*Client) FollowPagination ¶
func (c *Client) FollowPagination(ctx context.Context, httpResp *http.Response, firstPageCount, limit int) ([]json.RawMessage, error)
FollowPagination fetches additional pages following Link headers from an HTTP response. firstPageCount is the number of items already collected from the first page. limit is the maximum total items to return (0 = unlimited). Returns raw JSON items from subsequent pages only.
func (*Client) GetAllWithLimit ¶
func (c *Client) GetAllWithLimit(ctx context.Context, path string, limit int) ([]json.RawMessage, error)
GetAllWithLimit fetches pages for a paginated resource up to a limit.
func (*Client) GetHTML ¶ added in v0.3.0
GetHTML performs a GET request with Accept: text/html, returning raw HTML bytes. Use this for endpoints that only serve HTML (no JSON equivalent).
func (*Client) Identity ¶
func (c *Client) Identity() *IdentityService
Identity returns the IdentityService.
func (*Client) Journal ¶
func (c *Client) Journal() *JournalService
Journal returns the JournalService.
func (*Client) Messages ¶
func (c *Client) Messages() *MessagesService
Messages returns the MessagesService.
func (*Client) PatchMutation ¶ added in v0.1.1
PatchMutation performs a PATCH mutation with Accept: */*. Use this for endpoints where the server may not return JSON.
func (*Client) PostMutation ¶ added in v0.1.1
PostMutation performs a POST mutation with Accept: */*. Use this for endpoints where the server may not return JSON.
func (*Client) Postings ¶ added in v0.2.0
func (c *Client) Postings() *PostingsService
Postings returns the PostingsService.
func (*Client) TimeTracks ¶
func (c *Client) TimeTracks() *TimeTracksService
TimeTracks returns the TimeTracksService.
type ClientOption ¶
type ClientOption func(*Client)
ClientOption configures a Client.
func WithAuthStrategy ¶
func WithAuthStrategy(strategy AuthStrategy) ClientOption
WithAuthStrategy sets a custom authentication strategy.
func WithBaseDelay ¶
func WithBaseDelay(d time.Duration) ClientOption
WithBaseDelay sets the initial backoff delay.
func WithBulkhead ¶
func WithBulkhead(cfg *BulkheadConfig) ClientOption
WithBulkhead enables only the bulkhead (concurrency limiter).
func WithCircuitBreaker ¶
func WithCircuitBreaker(cfg *CircuitBreakerConfig) ClientOption
WithCircuitBreaker enables only the circuit breaker.
func WithHTTPClient ¶
func WithHTTPClient(c *http.Client) ClientOption
WithHTTPClient sets a custom HTTP client.
func WithHooks ¶
func WithHooks(hooks Hooks) ClientOption
WithHooks sets the observability hooks for the client.
func WithLogger ¶
func WithLogger(l *slog.Logger) ClientOption
WithLogger sets a custom slog logger for debug output.
func WithMaxJitter ¶
func WithMaxJitter(d time.Duration) ClientOption
WithMaxJitter sets the maximum random jitter to add to delays.
func WithMaxPages ¶
func WithMaxPages(n int) ClientOption
WithMaxPages sets the maximum pages to fetch in GetAll.
func WithMaxRetries ¶
func WithMaxRetries(n int) ClientOption
WithMaxRetries sets the maximum number of retry attempts for GET requests.
func WithRateLimit ¶
func WithRateLimit(cfg *RateLimitConfig) ClientOption
WithRateLimit enables only client-side rate limiting.
func WithResilience ¶
func WithResilience(cfg *ResilienceConfig) ClientOption
WithResilience enables circuit breaker, bulkhead, and rate limiting.
func WithTimeout ¶
func WithTimeout(d time.Duration) ClientOption
WithTimeout sets the HTTP request timeout.
func WithTransport ¶
func WithTransport(t http.RoundTripper) ClientOption
WithTransport sets a custom HTTP transport.
func WithUserAgent ¶
func WithUserAgent(ua string) ClientOption
WithUserAgent sets the User-Agent header.
type Config ¶
type Config struct {
// BaseURL is the API base URL (e.g., "https://app.hey.com").
BaseURL string `json:"base_url"`
// OAuthClientID is the OAuth 2.0 client ID for HEY.
OAuthClientID string `json:"oauth_client_id"`
// CacheDir is the directory for HTTP cache storage.
CacheDir string `json:"cache_dir"`
// CacheEnabled controls whether HTTP caching is enabled.
CacheEnabled bool `json:"cache_enabled"`
}
Config holds the resolved configuration for API access.
func DefaultConfig ¶
func DefaultConfig() *Config
DefaultConfig returns a Config with sensible defaults.
func LoadConfig ¶
LoadConfig loads configuration from a JSON file.
func (*Config) LoadConfigFromEnv ¶
func (c *Config) LoadConfigFromEnv()
LoadConfigFromEnv loads configuration from environment variables. Environment variables override any values already set in the config.
type ContactsService ¶
type ContactsService struct {
// contains filtered or unexported fields
}
ContactsService handles contact operations.
func NewContactsService ¶
func NewContactsService(client *Client) *ContactsService
NewContactsService creates a new ContactsService.
func (*ContactsService) Get ¶
func (s *ContactsService) Get(ctx context.Context, contactID int64) (result *generated.ContactDetail, err error)
Get returns a specific contact by ID.
func (*ContactsService) List ¶
func (s *ContactsService) List(ctx context.Context, params *generated.ListContactsParams) (result *generated.ListContactsResponseContent, err error)
List returns all contacts.
type CredentialStore ¶
type CredentialStore struct {
// contains filtered or unexported fields
}
CredentialStore handles secure credential storage.
func NewCredentialStore ¶
func NewCredentialStore(fallbackDir string) *CredentialStore
NewCredentialStore creates a credential store.
func (*CredentialStore) Delete ¶
func (s *CredentialStore) Delete(origin string) error
Delete removes credentials for the given origin.
func (*CredentialStore) Load ¶
func (s *CredentialStore) Load(origin string) (*Credentials, error)
Load retrieves credentials for the given origin.
func (*CredentialStore) Save ¶
func (s *CredentialStore) Save(origin string, creds *Credentials) error
Save stores credentials for the given origin.
func (*CredentialStore) UsingKeyring ¶
func (s *CredentialStore) UsingKeyring() bool
UsingKeyring returns true if the store is using the system keyring.
type Credentials ¶
type Credentials struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
ExpiresAt int64 `json:"expires_at"`
Scope string `json:"scope"`
TokenEndpoint string `json:"token_endpoint"`
UserID string `json:"user_id,omitempty"`
}
Credentials holds OAuth tokens and metadata.
type EntriesService ¶
type EntriesService struct {
// contains filtered or unexported fields
}
EntriesService handles draft and reply operations.
func NewEntriesService ¶
func NewEntriesService(client *Client) *EntriesService
NewEntriesService creates a new EntriesService.
func (*EntriesService) CreateReply ¶
func (s *EntriesService) CreateReply(ctx context.Context, entryID int64, content string, to, cc, bcc []string) (err error)
CreateReply creates a reply to an entry. The acting sender ID is automatically resolved.
func (*EntriesService) ListDrafts ¶
func (s *EntriesService) ListDrafts(ctx context.Context, params *generated.ListDraftsParams) (result *generated.ListDraftsResponseContent, err error)
ListDrafts returns all draft messages.
type Error ¶
type Error struct {
Code string
Message string
Hint string
HTTPStatus int
Retryable bool
RequestID string
Cause error
}
Error is a structured error with code, message, and optional hint.
func AsError ¶
AsError attempts to convert an error to an *Error. If the error is not an *Error, it wraps it in one.
func ErrAmbiguous ¶
ErrAmbiguous creates an ambiguous match error.
func ErrForbiddenScope ¶
func ErrForbiddenScope() *Error
ErrForbiddenScope creates a forbidden error due to insufficient scope.
func ErrNotFound ¶
ErrNotFound creates a not-found error.
func ErrNotFoundHint ¶
ErrNotFoundHint creates a not-found error with a hint.
func ErrRateLimit ¶
ErrRateLimit creates a rate-limit error.
func ErrUsageHint ¶
ErrUsageHint creates a usage error with a hint.
type GatingHooks ¶
type GatingHooks interface {
Hooks
OnOperationGate(ctx context.Context, op OperationInfo) (context.Context, error)
}
GatingHooks extends Hooks with request gating capability.
type HTTPOptions ¶
type HTTPOptions struct {
// Timeout is the request timeout (default: 30s).
Timeout time.Duration
// MaxRetries is the maximum retry attempts for GET requests (default: 3).
MaxRetries int
// BaseDelay is the initial backoff delay (default: 1s).
BaseDelay time.Duration
// MaxJitter is the maximum random jitter to add to delays (default: 100ms).
MaxJitter time.Duration
// MaxPages is the maximum pages to fetch in GetAll (default: 10000).
MaxPages int
// Transport is the HTTP transport to use. If nil, a default transport
// with sensible connection pooling is created.
Transport http.RoundTripper
}
HTTPOptions configures the HTTP client behavior.
func DefaultHTTPOptions ¶
func DefaultHTTPOptions() HTTPOptions
DefaultHTTPOptions returns HTTPOptions with sensible defaults.
type HabitsService ¶
type HabitsService struct {
// contains filtered or unexported fields
}
HabitsService handles habit tracking operations.
func NewHabitsService ¶
func NewHabitsService(client *Client) *HabitsService
NewHabitsService creates a new HabitsService.
func (*HabitsService) Complete ¶
func (s *HabitsService) Complete(ctx context.Context, day string, habitID int64) (result *generated.Recording, err error)
Complete marks a habit as complete for a given day.
func (*HabitsService) Uncomplete ¶
func (s *HabitsService) Uncomplete(ctx context.Context, day string, habitID int64) (result *generated.Recording, err error)
Uncomplete marks a habit as incomplete for a given day.
type Hooks ¶
type Hooks interface {
OnOperationStart(ctx context.Context, op OperationInfo) context.Context
OnOperationEnd(ctx context.Context, op OperationInfo, err error, duration time.Duration)
OnRequestStart(ctx context.Context, info RequestInfo) context.Context
OnRequestEnd(ctx context.Context, info RequestInfo, result RequestResult)
OnRetry(ctx context.Context, info RequestInfo, attempt int, err error)
}
Hooks provides observability callbacks for SDK operations.
func NewChainHooks ¶
NewChainHooks creates a ChainHooks from the given hooks.
type IdentityService ¶
type IdentityService struct {
// contains filtered or unexported fields
}
IdentityService handles identity and navigation operations.
func NewIdentityService ¶
func NewIdentityService(client *Client) *IdentityService
NewIdentityService creates a new IdentityService.
func (*IdentityService) GetIdentity ¶
GetIdentity returns the current user's identity.
func (*IdentityService) GetNavigation ¶
func (s *IdentityService) GetNavigation(ctx context.Context) (result *generated.NavigationResponse, err error)
GetNavigation returns the navigation structure for the current user.
type JournalService ¶
type JournalService struct {
// contains filtered or unexported fields
}
JournalService handles journal entry operations.
func NewJournalService ¶
func NewJournalService(client *Client) *JournalService
NewJournalService creates a new JournalService.
func (*JournalService) Get ¶
func (s *JournalService) Get(ctx context.Context, day string) (result *generated.Recording, err error)
Get returns a journal entry for a specific day (YYYY-MM-DD format).
func (*JournalService) GetContent ¶ added in v0.3.0
GetContent returns the HTML content of a journal entry for a specific day. It tries the JSON API first; if that returns 204 (no content), it falls back to scraping the edit page for the Trix editor content.
type ListMeta ¶
type ListMeta struct {
// TotalCount is the total number of items available (from X-Total-Count header).
// Zero if the header was not present or could not be parsed.
TotalCount int
}
ListMeta contains pagination metadata from list operations.
type Match ¶
type Match struct {
// Operation is the matched API operation name (e.g., "GetBox", "CreateMessage").
Operation string
// Operations lists all API operations for the matched pattern, keyed by HTTP method.
Operations map[string]string
// Resource is the API resource group (e.g., "Boxes", "Messages").
Resource string
// Params contains all named path parameters extracted from the URL.
Params map[string]string
// contains filtered or unexported fields
}
Match holds the components extracted from a HEY API URL.
func (*Match) ResourceID ¶
ResourceID returns the last path parameter value (the "primary" resource ID). Returns empty string if no parameters exist.
type MessagesService ¶
type MessagesService struct {
// contains filtered or unexported fields
}
MessagesService handles message operations.
func NewMessagesService ¶
func NewMessagesService(client *Client) *MessagesService
NewMessagesService creates a new MessagesService.
func (*MessagesService) Create ¶
func (s *MessagesService) Create(ctx context.Context, subject, content string, to, cc, bcc []string) (err error)
Create creates a new message. The acting sender ID is automatically resolved.
The HEY API expects a nested body with acting_sender_id, message (subject/content), and entry (addressed recipients). This method constructs the correct shape.
func (*MessagesService) CreateTopicMessage ¶
func (s *MessagesService) CreateTopicMessage(ctx context.Context, topicID int64, content string) (err error)
CreateTopicMessage creates a message within a topic (reply to a thread). The acting sender ID is automatically resolved.
type NoopHooks ¶
type NoopHooks struct{}
NoopHooks is a no-op implementation of Hooks.
func (NoopHooks) OnOperationEnd ¶
func (NoopHooks) OnOperationStart ¶
func (NoopHooks) OnRequestEnd ¶
func (NoopHooks) OnRequestEnd(context.Context, RequestInfo, RequestResult)
func (NoopHooks) OnRequestStart ¶
type OperationInfo ¶
type OperationInfo struct {
Service string
Operation string
ResourceType string
IsMutation bool
ResourceID int64
}
OperationInfo describes a semantic SDK operation.
type PostingsService ¶ added in v0.2.0
type PostingsService struct {
// contains filtered or unexported fields
}
PostingsService handles posting-level actions (move, seen, trash, etc.).
func NewPostingsService ¶ added in v0.2.0
func NewPostingsService(client *Client) *PostingsService
NewPostingsService creates a new PostingsService.
func (*PostingsService) Ignore ¶ added in v0.2.0
func (s *PostingsService) Ignore(ctx context.Context, postingID int64) error
Ignore ignores a posting (stops notifications).
func (*PostingsService) MarkSeen ¶ added in v0.2.0
func (s *PostingsService) MarkSeen(ctx context.Context, postingIDs []int64) (err error)
MarkSeen marks one or more postings as seen/read.
func (*PostingsService) MarkUnseen ¶ added in v0.2.0
func (s *PostingsService) MarkUnseen(ctx context.Context, postingIDs []int64) (err error)
MarkUnseen marks one or more postings as unseen/unread.
func (*PostingsService) MoveToFeed ¶ added in v0.2.0
func (s *PostingsService) MoveToFeed(ctx context.Context, postingID int64) error
MoveToFeed moves a posting to The Feed.
func (*PostingsService) MoveToPaperTrail ¶ added in v0.2.0
func (s *PostingsService) MoveToPaperTrail(ctx context.Context, postingID int64) error
MoveToPaperTrail moves a posting to the Paper Trail.
func (*PostingsService) MoveToReplyLater ¶ added in v0.2.0
func (s *PostingsService) MoveToReplyLater(ctx context.Context, postingID int64) error
MoveToReplyLater moves a posting to Reply Later.
func (*PostingsService) MoveToSetAside ¶ added in v0.2.0
func (s *PostingsService) MoveToSetAside(ctx context.Context, postingID int64) error
MoveToSetAside moves a posting to Set Aside.
func (*PostingsService) MoveToTrash ¶ added in v0.2.0
func (s *PostingsService) MoveToTrash(ctx context.Context, postingID int64) error
MoveToTrash moves a posting to the trash.
type RateLimitConfig ¶
type RateLimitConfig struct {
RequestsPerSecond float64
BurstSize int
RespectRetryAfter bool
Now func() time.Time
}
RateLimitConfig configures client-side rate limiting.
func DefaultRateLimitConfig ¶
func DefaultRateLimitConfig() *RateLimitConfig
DefaultRateLimitConfig returns production-ready defaults.
type RequestInfo ¶
RequestInfo contains information about an HTTP request.
type RequestResult ¶
type RequestResult struct {
StatusCode int
Duration time.Duration
Error error
FromCache bool
Retryable bool
RetryAfter int
}
RequestResult contains the result of an HTTP request.
type ResilienceConfig ¶
type ResilienceConfig struct {
CircuitBreaker *CircuitBreakerConfig
Bulkhead *BulkheadConfig
RateLimit *RateLimitConfig
}
ResilienceConfig combines all resilience settings.
func DefaultResilienceConfig ¶
func DefaultResilienceConfig() *ResilienceConfig
DefaultResilienceConfig returns production-ready defaults.
type Response ¶
Response wraps an API response.
func (*Response) UnmarshalData ¶
UnmarshalData unmarshals the response data into the given value.
type Router ¶
type Router struct {
// contains filtered or unexported fields
}
Router matches HEY API URLs against the OpenAPI-derived route table.
func DefaultRouter ¶
func DefaultRouter() *Router
DefaultRouter returns a shared Router instance using the embedded route table.
type SearchService ¶
type SearchService struct {
// contains filtered or unexported fields
}
SearchService handles search operations.
func NewSearchService ¶
func NewSearchService(client *Client) *SearchService
NewSearchService creates a new SearchService.
func (*SearchService) Search ¶
func (s *SearchService) Search(ctx context.Context, params *generated.SearchParams) (result *generated.SearchResponseContent, err error)
Search searches for content.
type StaticTokenProvider ¶
type StaticTokenProvider struct {
Token string
}
StaticTokenProvider provides a fixed token (e.g., from HEY_TOKEN env var).
func (*StaticTokenProvider) AccessToken ¶
func (p *StaticTokenProvider) AccessToken(ctx context.Context) (string, error)
AccessToken returns the static token.
type TimeTracksService ¶
type TimeTracksService struct {
// contains filtered or unexported fields
}
TimeTracksService handles time tracking operations.
func NewTimeTracksService ¶
func NewTimeTracksService(client *Client) *TimeTracksService
NewTimeTracksService creates a new TimeTracksService.
func (*TimeTracksService) GetOngoing ¶
func (s *TimeTracksService) GetOngoing(ctx context.Context) (result *generated.Recording, err error)
GetOngoing returns the ongoing time track, or nil if none is active. Per ADR-004, a 404 response is treated as "no active track" rather than an error.
func (*TimeTracksService) Start ¶
func (s *TimeTracksService) Start(ctx context.Context, body generated.StartTimeTrackJSONRequestBody) (result *generated.Recording, err error)
Start starts a new time track.
The HEY API expects the body wrapped as {calendar_time_track: {...}}.
func (*TimeTracksService) Stop ¶
func (s *TimeTracksService) Stop(ctx context.Context, timeTrackID int64) (err error)
Stop stops an ongoing time track by setting ends_at to the current time.
func (*TimeTracksService) Update ¶
func (s *TimeTracksService) Update(ctx context.Context, timeTrackID int64, body generated.UpdateTimeTrackJSONRequestBody) (result *generated.Recording, err error)
Update updates an existing time track.
The HEY API expects the body wrapped as {calendar_time_track: {...}}.
type TokenProvider ¶
TokenProvider is the interface for obtaining access tokens.
type TopicsService ¶
type TopicsService struct {
// contains filtered or unexported fields
}
TopicsService handles topic operations.
func NewTopicsService ¶
func NewTopicsService(client *Client) *TopicsService
NewTopicsService creates a new TopicsService.
func (*TopicsService) Get ¶
func (s *TopicsService) Get(ctx context.Context, topicID int64) (result *generated.Topic, err error)
Get returns a specific topic by ID.
func (*TopicsService) GetEntries ¶
func (s *TopicsService) GetEntries(ctx context.Context, topicID int64, params *generated.GetTopicEntriesParams) (result *generated.GetTopicEntriesResponseContent, err error)
GetEntries returns entries for a specific topic.
func (*TopicsService) GetEverything ¶
func (s *TopicsService) GetEverything(ctx context.Context, params *generated.GetEverythingTopicsParams) (result *generated.TopicListResponse, err error)
GetEverything returns all topics.
func (*TopicsService) GetSent ¶
func (s *TopicsService) GetSent(ctx context.Context, params *generated.GetSentTopicsParams) (result *generated.TopicListResponse, err error)
GetSent returns sent topics.
func (*TopicsService) GetSpam ¶
func (s *TopicsService) GetSpam(ctx context.Context, params *generated.GetSpamTopicsParams) (result *generated.TopicListResponse, err error)
GetSpam returns spam topics.
func (*TopicsService) GetTrash ¶
func (s *TopicsService) GetTrash(ctx context.Context, params *generated.GetTrashTopicsParams) (result *generated.TopicListResponse, err error)
GetTrash returns trash topics.
Source Files
¶
- auth.go
- auth_strategy.go
- boxes.go
- bulkhead.go
- cache.go
- calendar_todos.go
- calendars.go
- circuit_breaker.go
- client.go
- config.go
- contacts.go
- doc.go
- entries.go
- errors.go
- habits.go
- helpers.go
- http.go
- identity.go
- journal.go
- messages.go
- observability.go
- pagination.go
- postings.go
- rate_limit.go
- resilience.go
- search.go
- security.go
- time_tracks.go
- topics.go
- url.go
- version.go