Class: Basecamp::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/basecamp/client.rb

Overview

Main client for the Basecamp API.

Client holds shared resources and is used to create AccountClient instances for specific Basecamp accounts via the #for_account method.

Examples:

Basic usage

config = Basecamp::Config.from_env
token_provider = Basecamp::StaticTokenProvider.new(ENV["BASECAMP_ACCESS_TOKEN"])
client = Basecamp::Client.new(config: config, token_provider: token_provider)

# Get authorization info (account-independent)
auth = client.authorization.get

# Work with a specific account
 = client.("12345")
projects = .projects.list

With custom hooks

require "logger"
logger = Logger.new($stdout)
hooks = Basecamp::LoggerHooks.new(logger)

client = Basecamp::Client.new(
  config: config,
  token_provider: token_provider,
  hooks: hooks
)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config:, token_provider: nil, auth_strategy: nil, hooks: nil) ⇒ Client

Creates a new Basecamp API client.

Parameters:

  • config (Config)

    configuration settings

  • token_provider (TokenProvider, nil) (defaults to: nil)

    OAuth token provider (deprecated, use auth_strategy)

  • auth_strategy (AuthStrategy, nil) (defaults to: nil)

    authentication strategy

  • hooks (Hooks, nil) (defaults to: nil)

    observability hooks

Raises:

  • (ArgumentError)


42
43
44
45
46
47
48
49
50
# File 'lib/basecamp/client.rb', line 42

def initialize(config:, token_provider: nil, auth_strategy: nil, hooks: nil)
  raise ArgumentError, "provide either token_provider or auth_strategy, not both" if token_provider && auth_strategy
  raise ArgumentError, "provide token_provider or auth_strategy" if !token_provider && !auth_strategy

  @config = config
  @hooks = hooks || NoopHooks.new
  @http = Http.new(config: config, token_provider: token_provider, auth_strategy: auth_strategy, hooks: @hooks)
  @mutex = Mutex.new
end

Instance Attribute Details

#configConfig (readonly)

Returns client configuration.

Returns:

  • (Config)

    client configuration



34
35
36
# File 'lib/basecamp/client.rb', line 34

def config
  @config
end

#hooksHooks (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the observability hooks.

Returns:



91
92
93
# File 'lib/basecamp/client.rb', line 91

def hooks
  @hooks
end

#httpHttp (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the HTTP client for making requests.

Returns:



86
87
88
# File 'lib/basecamp/client.rb', line 86

def http
  @http
end

Instance Method Details

#account_idnil

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns nil since Client is not bound to an account.

Returns:

  • (nil)


96
97
98
# File 'lib/basecamp/client.rb', line 96

def 
  nil
end

#authorizationServices::AuthorizationService

Returns the AuthorizationService for authorization operations. This is the only service available directly on Client, as it doesn't require an account context. All other services require an AccountClient via #for_account.



77
78
79
80
81
# File 'lib/basecamp/client.rb', line 77

def authorization
  @mutex.synchronize do
    @authorization ||= Services::AuthorizationService.new(self)
  end
end

#for_account(account_id) ⇒ AccountClient

Returns an AccountClient bound to the specified Basecamp account.

The Basecamp API requires an account ID in the URL path (e.g., https://3.basecampapi.com/12345/projects.json).

Examples:

 = client.("12345")
projects = .projects.list

Parameters:

  • account_id (String, Integer)

    the Basecamp account ID

Returns:

Raises:

  • (ArgumentError)

    if account_id is empty or non-numeric



64
65
66
67
68
69
70
# File 'lib/basecamp/client.rb', line 64

def ()
   = .to_s
  raise ArgumentError, "account_id cannot be empty" if .empty?
  raise ArgumentError, "account_id must be numeric, got: #{}" unless .match?(/\A\d+\z/)

  AccountClient.new(parent: self, account_id: )
end