Class: Craigslist::API::Client

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

Overview

The single entry point for both halves of the Craigslist bulk posting platform.

Craigslist splits the work across two services with different formats and different authentication: postings are created through an RSS interface authenticated with credentials embedded in the XML, and managed afterwards through a JSON API authenticated with an OAuth2 bearer token. One set of credentials covers both. This client owns that seam so callers do not have to think about it — #post and #posting are the same object's methods, and the token lifecycle is invisible.

Configuration is frozen and nothing mutates at request time, so a client is safe to share across threads. Talking to several accounts means building several clients, which is deliberate: there is no global to reconfigure and no ambient state to get wrong.

Examples:

Creating postings

client = Craigslist::API::Client.new(
  email: "you@example.com",
  password: ENV.fetch("CRAIGSLIST_PASSWORD"),
  account_id: 1234
)

posting = Craigslist::API::Posting.new(
  key: "listing-1",
  title: "1998 Toyota Hilux",
  description: "Runs great.",
  category: "ctd",
  area: "sfo",
  price: 4500,
  reply_email: "sales@example.com",
  location: {postal: "94110"}
)

results = client.validate(posting)   # dry run
results = client.post(posting) if results.all_successful?

Managing what you created

live = client.posting(results.posting_ids.first)
live.price = 4200
live.add_image("front.jpg")

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(email:, password:, account_id:, **options) ⇒ Client

Returns a new instance of Client.

Parameters:

  • email (String)

    craigslist account email

  • password (String)

    craigslist account password

  • account_id (String, Integer)

    craigslist account number

  • options (Hash)

Raises:



55
56
57
58
59
60
61
62
63
64
# File 'lib/craigslist/api/client.rb', line 55

def initialize(email:, password:, account_id:, **options)
  @config = Configuration.new(
    email: email,
    password: password,
    account_id: ,
    **options
  )

  build_components
end

Instance Attribute Details

#accountResources::Account (readonly)

Returns:



118
119
120
# File 'lib/craigslist/api/client.rb', line 118

def 
  @account
end

#billingResources::Billing (readonly)

Returns:



115
116
117
# File 'lib/craigslist/api/client.rb', line 115

def billing
  @billing
end

#configConfiguration (readonly)

Returns:



48
49
50
# File 'lib/craigslist/api/client.rb', line 48

def config
  @config
end

#imagesResources::Images (readonly)

Returns:



112
113
114
# File 'lib/craigslist/api/client.rb', line 112

def images
  @images
end

#postingsResources::Postings (readonly)

Returns:



109
110
111
# File 'lib/craigslist/api/client.rb', line 109

def postings
  @postings
end

#referenceReference (readonly)

Returns public areas and categories data.

Returns:

  • (Reference)

    public areas and categories data



121
122
123
# File 'lib/craigslist/api/client.rb', line 121

def reference
  @reference
end

Class Method Details

.from_config(config) ⇒ Client

Builds a client from an existing Craigslist::API::Configuration.

Parameters:

Returns:



70
71
72
73
74
75
# File 'lib/craigslist/api/client.rb', line 70

def self.from_config(config)
  allocate.tap do |client|
    client.instance_variable_set(:@config, config)
    client.send(:build_components)
  end
end

Instance Method Details

#account_messagesArray<Hash>

Notices attached to the most recent JSON API response.

Craigslist repeats these on every response until acknowledged, so it is worth surfacing them somewhere a human will look.

Returns:

  • (Array<Hash>)

    {"messageId", "message"} entries



158
159
160
# File 'lib/craigslist/api/client.rb', line 158

def 
  @json_transport.
end

#area_for_zip(zip) ⇒ Hash{Symbol => String}

Parameters:

  • zip (String)

Returns:

  • (Hash{Symbol => String})


142
143
144
# File 'lib/craigslist/api/client.rb', line 142

def area_for_zip(zip)
  postings.area_for_zip(zip)
end

#creditCreditSummary

Returns:



124
125
126
# File 'lib/craigslist/api/client.rb', line 124

def credit
  billing.credit
end

#inspectObject Also known as: to_s



170
171
172
# File 'lib/craigslist/api/client.rb', line 170

def inspect
  "#<#{self.class.name} email=#{config.email.inspect} account_id=#{config..inspect}>"
end

#post(postings) ⇒ ResultSet

Creates postings.

Does not raise when individual postings fail — a batch with some rejections is ordinary. Inspect the returned ResultSet.

Parameters:

Returns:



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

def post(postings)
  bulk.post(postings)
end

#posting(posting_id) ⇒ PostingHandle

A handle for working with one live posting.

Parameters:

  • posting_id (String, Integer)

Returns:



104
105
106
# File 'lib/craigslist/api/client.rb', line 104

def posting(posting_id)
  PostingHandle.new(self, posting_id)
end

#posting_blocksArray<PostingBlock>

Returns:



129
130
131
# File 'lib/craigslist/api/client.rb', line 129

def posting_blocks
  billing.posting_blocks
end

#pricing(area:, category:) ⇒ Money?

Parameters:

  • area (String)
  • category (String)

Returns:



136
137
138
# File 'lib/craigslist/api/client.rb', line 136

def pricing(area:, category:)
  billing.pricing(area: area, category: category)
end

#reset_token!void

This method returns an undefined value.

Discards the cached OAuth token, forcing the next JSON call to re-authenticate. Rarely needed; the token refreshes itself.



166
167
168
# File 'lib/craigslist/api/client.rb', line 166

def reset_token!
  @token_provider.invalidate!
end

#stats(start: nil, stop: nil) ⇒ Array<PostingStats>

Returns:

See Also:



148
149
150
# File 'lib/craigslist/api/client.rb', line 148

def stats(start: nil, stop: nil)
  .stats(start: start, stop: stop)
end

#validate(postings) ⇒ ResultSet

Checks postings without creating anything.

Sends the identical document #post would, so a clean validation is a real rehearsal rather than an approximation.

Parameters:

Returns:

Raises:



85
86
87
# File 'lib/craigslist/api/client.rb', line 85

def validate(postings)
  bulk.validate(postings)
end