Class: XeroKiwi::Client

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

Overview

Entry point for talking to Xero. Holds the OAuth2 token state, knows how to refresh it (when given client credentials), and exposes resource methods that auto-refresh before each request.

# Simple — access token only, no refresh capability.
client = XeroKiwi::Client.new(access_token: "ya29...")

# Full — refresh-capable, with persistence callback.
client = XeroKiwi::Client.new(
  access_token:     creds.access_token,
  refresh_token:    creds.refresh_token,
  expires_at:       creds.expires_at,
  client_id:        ENV["XERO_CLIENT_ID"],
  client_secret:    ENV["XERO_CLIENT_SECRET"],
  on_token_refresh: ->(token) { creds.update!(token.to_h) }
)

client.token             # => XeroKiwi::Token
client.token.expired?    # => false
client.refresh_token!    # manual force refresh
client.connections       # auto-refreshes if expiring; reactive on 401

Defined Under Namespace

Classes: ResponseHandler

Constant Summary collapse

BASE_URL =
"https://api.xero.com"
DEFAULT_USER_AGENT =
"XeroKiwi/#{XeroKiwi::VERSION} (+https://github.com/douglasgreyling/xero-kiwi)".freeze
RETRY_STATUSES =

HTTP statuses we treat as transient. faraday-retry honours Retry-After automatically when the status is in this list.

[429, 502, 503, 504].freeze
DEFAULT_RETRY_OPTIONS =
{
  max:                 4,
  interval:            0.5,
  interval_randomness: 0.5,
  backoff_factor:      2,
  retry_statuses:      RETRY_STATUSES,
  methods:             %i[get head options put delete post],
  # Faraday::RetriableResponse is the *internal* signal faraday-retry uses
  # to flag a status-code retry. It MUST be in this list, or the middleware
  # can't catch its own retry signal and 429s/503s never get retried.
  exceptions:          [
    Faraday::ConnectionFailed,
    Faraday::TimeoutError,
    Faraday::RetriableResponse,
    Errno::ETIMEDOUT
  ]
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(access_token:, refresh_token: nil, expires_at: nil, client_id: nil, client_secret: nil, on_token_refresh: nil, adapter: nil, user_agent: DEFAULT_USER_AGENT, retry_options: {}, throttle: nil) ⇒ Client

Returns a new instance of Client.



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/xero_kiwi/client.rb', line 57

def initialize(
  access_token:,
  refresh_token: nil,
  expires_at: nil,
  client_id: nil,
  client_secret: nil,
  on_token_refresh: nil,
  adapter: nil,
  user_agent: DEFAULT_USER_AGENT,
  retry_options: {},
  throttle: nil
)
  @token            = Token.new(
    access_token:  access_token,
    refresh_token: refresh_token,
    expires_at:    expires_at
  )
  @client_id        = client_id
  @client_secret    = client_secret
  @on_token_refresh = on_token_refresh
  @adapter          = adapter
  @user_agent       = user_agent
  @retry_options    = DEFAULT_RETRY_OPTIONS.merge(retry_options)
  @throttle         = throttle || Throttle::NullLimiter.new
  @refresh_mutex    = Mutex.new
end

Instance Attribute Details

#tokenObject (readonly)

Returns the value of attribute token.



55
56
57
# File 'lib/xero_kiwi/client.rb', line 55

def token
  @token
end

Instance Method Details

#branding_theme(tenant_id, branding_theme_id) ⇒ Object

Fetches a single Branding Theme by ID for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/brandingthemes

Raises:

  • (ArgumentError)


447
448
449
450
451
452
453
454
455
456
457
458
# File 'lib/xero_kiwi/client.rb', line 447

def branding_theme(tenant_id, branding_theme_id)
  tid = extract_tenant_id(tenant_id)
  raise ArgumentError, "tenant_id is required" if tid.nil? || tid.empty?
  raise ArgumentError, "branding_theme_id is required" if branding_theme_id.nil? || branding_theme_id.to_s.empty?

  with_authenticated_request do
    response = http.get("/api.xro/2.0/BrandingThemes/#{branding_theme_id}") do |req|
      req.headers["Xero-Tenant-Id"] = tid
    end
    Accounting::BrandingTheme.from_response(response.body).first
  end
end

#branding_themes(tenant_id, where: nil, order: nil, page: nil, modified_since: nil) ⇒ Object

Fetches the Branding Themes for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/brandingthemes



426
427
428
429
430
431
432
433
434
435
436
# File 'lib/xero_kiwi/client.rb', line 426

def branding_themes(tenant_id, where: nil, order: nil, page: nil, modified_since: nil)
  list_request(
    path:           "/api.xro/2.0/BrandingThemes",
    tenant_id:      tenant_id,
    resource_class: Accounting::BrandingTheme,
    where:          where,
    order:          order,
    page:           page,
    modified_since: modified_since
  )
end

#can_refresh?Boolean

True if this client was constructed with refresh credentials AND the current token still carries a refresh_token to use.

Returns:

  • (Boolean)


497
498
499
# File 'lib/xero_kiwi/client.rb', line 497

def can_refresh?
  !@client_id.nil? && !@client_secret.nil? && @token.refreshable?
end

#connectionsObject

Fetches the list of tenants the current access token has access to. See: developer.xero.com/documentation/best-practices/managing-connections/connections



86
87
88
89
90
91
# File 'lib/xero_kiwi/client.rb', line 86

def connections
  with_authenticated_request do
    response = http.get("/connections")
    Connection.from_response(response.body)
  end
end

#contact(tenant_id, contact_id) ⇒ Object

Fetches a single Contact by ID for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/contacts

Raises:

  • (ArgumentError)


172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/xero_kiwi/client.rb', line 172

def contact(tenant_id, contact_id)
  tid = extract_tenant_id(tenant_id)
  raise ArgumentError, "tenant_id is required" if tid.nil? || tid.empty?
  raise ArgumentError, "contact_id is required" if contact_id.nil? || contact_id.to_s.empty?

  with_authenticated_request do
    response = http.get("/api.xro/2.0/Contacts/#{contact_id}") do |req|
      req.headers["Xero-Tenant-Id"] = tid
    end
    Accounting::Contact.from_response(response.body).first
  end
end

#contact_group(tenant_id, contact_group_id) ⇒ Object

Fetches a single Contact Group by ID for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/contactgroups

Raises:

  • (ArgumentError)


209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/xero_kiwi/client.rb', line 209

def contact_group(tenant_id, contact_group_id)
  tid = extract_tenant_id(tenant_id)
  raise ArgumentError, "tenant_id is required" if tid.nil? || tid.empty?
  raise ArgumentError, "contact_group_id is required" if contact_group_id.nil? || contact_group_id.to_s.empty?

  with_authenticated_request do
    response = http.get("/api.xro/2.0/ContactGroups/#{contact_group_id}") do |req|
      req.headers["Xero-Tenant-Id"] = tid
    end
    Accounting::ContactGroup.from_response(response.body).first
  end
end

#contact_groups(tenant_id, where: nil, order: nil, page: nil, modified_since: nil) ⇒ Object

Fetches the Contact Groups for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/contactgroups



188
189
190
191
192
193
194
195
196
197
198
# File 'lib/xero_kiwi/client.rb', line 188

def contact_groups(tenant_id, where: nil, order: nil, page: nil, modified_since: nil)
  list_request(
    path:           "/api.xro/2.0/ContactGroups",
    tenant_id:      tenant_id,
    resource_class: Accounting::ContactGroup,
    where:          where,
    order:          order,
    page:           page,
    modified_since: modified_since
  )
end

#contacts(tenant_id, where: nil, order: nil, page: nil, modified_since: nil) ⇒ Object

Fetches the Contacts for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/contacts



151
152
153
154
155
156
157
158
159
160
161
# File 'lib/xero_kiwi/client.rb', line 151

def contacts(tenant_id, where: nil, order: nil, page: nil, modified_since: nil)
  list_request(
    path:           "/api.xro/2.0/Contacts",
    tenant_id:      tenant_id,
    resource_class: Accounting::Contact,
    where:          where,
    order:          order,
    page:           page,
    modified_since: modified_since
  )
end

#credit_note(tenant_id, credit_note_id) ⇒ Object

Fetches a single Credit Note by ID for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/creditnotes

Raises:

  • (ArgumentError)


283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/xero_kiwi/client.rb', line 283

def credit_note(tenant_id, credit_note_id)
  tid = extract_tenant_id(tenant_id)
  raise ArgumentError, "tenant_id is required" if tid.nil? || tid.empty?
  raise ArgumentError, "credit_note_id is required" if credit_note_id.nil? || credit_note_id.to_s.empty?

  with_authenticated_request do
    response = http.get("/api.xro/2.0/CreditNotes/#{credit_note_id}") do |req|
      req.headers["Xero-Tenant-Id"] = tid
    end
    Accounting::CreditNote.from_response(response.body).first
  end
end

#credit_notes(tenant_id, where: nil, order: nil, page: nil, modified_since: nil) ⇒ Object

Fetches the Credit Notes for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/creditnotes



262
263
264
265
266
267
268
269
270
271
272
# File 'lib/xero_kiwi/client.rb', line 262

def credit_notes(tenant_id, where: nil, order: nil, page: nil, modified_since: nil)
  list_request(
    path:           "/api.xro/2.0/CreditNotes",
    tenant_id:      tenant_id,
    resource_class: Accounting::CreditNote,
    where:          where,
    order:          order,
    page:           page,
    modified_since: modified_since
  )
end

#delete_connection(connection_or_id) ⇒ Object

Disconnects a tenant. Accepts either a XeroKiwi::Connection (we use its ‘id`) or a raw connection-id string. Returns true on the 204. The access token may still be valid for other connections after this —only the named tenant is detached.

Raises:

  • (ArgumentError)


464
465
466
467
468
469
470
471
472
# File 'lib/xero_kiwi/client.rb', line 464

def delete_connection(connection_or_id)
  id = extract_connection_id(connection_or_id)
  raise ArgumentError, "connection id is required" if id.nil? || id.empty?

  with_authenticated_request do
    http.delete("/connections/#{id}")
    true
  end
end

#each_branding_theme(tenant_id, where: nil, order: nil, modified_since: nil, &block) ⇒ Object



438
439
440
441
442
# File 'lib/xero_kiwi/client.rb', line 438

def each_branding_theme(tenant_id, where: nil, order: nil, modified_since: nil, &block)
  return to_enum(:each_branding_theme, tenant_id, where: where, order: order, modified_since: modified_since) unless block

  walk_pages(:branding_themes, tenant_id, where: where, order: order, modified_since: modified_since, &block)
end

#each_contact(tenant_id, where: nil, order: nil, modified_since: nil, &block) ⇒ Object



163
164
165
166
167
# File 'lib/xero_kiwi/client.rb', line 163

def each_contact(tenant_id, where: nil, order: nil, modified_since: nil, &block)
  return to_enum(:each_contact, tenant_id, where: where, order: order, modified_since: modified_since) unless block

  walk_pages(:contacts, tenant_id, where: where, order: order, modified_since: modified_since, &block)
end

#each_contact_group(tenant_id, where: nil, order: nil, modified_since: nil, &block) ⇒ Object



200
201
202
203
204
# File 'lib/xero_kiwi/client.rb', line 200

def each_contact_group(tenant_id, where: nil, order: nil, modified_since: nil, &block)
  return to_enum(:each_contact_group, tenant_id, where: where, order: order, modified_since: modified_since) unless block

  walk_pages(:contact_groups, tenant_id, where: where, order: order, modified_since: modified_since, &block)
end

#each_credit_note(tenant_id, where: nil, order: nil, modified_since: nil, &block) ⇒ Object



274
275
276
277
278
# File 'lib/xero_kiwi/client.rb', line 274

def each_credit_note(tenant_id, where: nil, order: nil, modified_since: nil, &block)
  return to_enum(:each_credit_note, tenant_id, where: where, order: order, modified_since: modified_since) unless block

  walk_pages(:credit_notes, tenant_id, where: where, order: order, modified_since: modified_since, &block)
end

#each_invoice(tenant_id, where: nil, order: nil, modified_since: nil, &block) ⇒ Object



385
386
387
388
389
# File 'lib/xero_kiwi/client.rb', line 385

def each_invoice(tenant_id, where: nil, order: nil, modified_since: nil, &block)
  return to_enum(:each_invoice, tenant_id, where: where, order: order, modified_since: modified_since) unless block

  walk_pages(:invoices, tenant_id, where: where, order: order, modified_since: modified_since, &block)
end

#each_overpayment(tenant_id, where: nil, order: nil, modified_since: nil, &block) ⇒ Object



311
312
313
314
315
# File 'lib/xero_kiwi/client.rb', line 311

def each_overpayment(tenant_id, where: nil, order: nil, modified_since: nil, &block)
  return to_enum(:each_overpayment, tenant_id, where: where, order: order, modified_since: modified_since) unless block

  walk_pages(:overpayments, tenant_id, where: where, order: order, modified_since: modified_since, &block)
end

#each_payment(tenant_id, where: nil, order: nil, modified_since: nil, &block) ⇒ Object



348
349
350
351
352
# File 'lib/xero_kiwi/client.rb', line 348

def each_payment(tenant_id, where: nil, order: nil, modified_since: nil, &block)
  return to_enum(:each_payment, tenant_id, where: where, order: order, modified_since: modified_since) unless block

  walk_pages(:payments, tenant_id, where: where, order: order, modified_since: modified_since, &block)
end

#each_prepayment(tenant_id, where: nil, order: nil, modified_since: nil, &block) ⇒ Object



237
238
239
240
241
# File 'lib/xero_kiwi/client.rb', line 237

def each_prepayment(tenant_id, where: nil, order: nil, modified_since: nil, &block)
  return to_enum(:each_prepayment, tenant_id, where: where, order: order, modified_since: modified_since) unless block

  walk_pages(:prepayments, tenant_id, where: where, order: order, modified_since: modified_since, &block)
end

#each_user(tenant_id, where: nil, order: nil, modified_since: nil, &block) ⇒ Object

Yields every User across all pages, driving ‘#users` with `page:` until an empty page signals the end. Returns an Enumerator when no block is given.



126
127
128
129
130
# File 'lib/xero_kiwi/client.rb', line 126

def each_user(tenant_id, where: nil, order: nil, modified_since: nil, &block)
  return to_enum(:each_user, tenant_id, where: where, order: order, modified_since: modified_since) unless block

  walk_pages(:users, tenant_id, where: where, order: order, modified_since: modified_since, &block)
end

#invoice(tenant_id, invoice_id) ⇒ Object

Fetches a single Invoice by ID for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/invoices

Raises:

  • (ArgumentError)


394
395
396
397
398
399
400
401
402
403
404
405
# File 'lib/xero_kiwi/client.rb', line 394

def invoice(tenant_id, invoice_id)
  tid = extract_tenant_id(tenant_id)
  raise ArgumentError, "tenant_id is required" if tid.nil? || tid.empty?
  raise ArgumentError, "invoice_id is required" if invoice_id.nil? || invoice_id.to_s.empty?

  with_authenticated_request do
    response = http.get("/api.xro/2.0/Invoices/#{invoice_id}") do |req|
      req.headers["Xero-Tenant-Id"] = tid
    end
    Accounting::Invoice.from_response(response.body).first
  end
end

#invoices(tenant_id, where: nil, order: nil, page: nil, modified_since: nil) ⇒ Object

Fetches the Invoices for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/invoices



373
374
375
376
377
378
379
380
381
382
383
# File 'lib/xero_kiwi/client.rb', line 373

def invoices(tenant_id, where: nil, order: nil, page: nil, modified_since: nil)
  list_request(
    path:           "/api.xro/2.0/Invoices",
    tenant_id:      tenant_id,
    resource_class: Accounting::Invoice,
    where:          where,
    order:          order,
    page:           page,
    modified_since: modified_since
  )
end

#online_invoice_url(tenant_id, invoice_id) ⇒ Object

Fetches the online invoice URL for a sales (ACCREC) invoice. Returns the URL string, or nil if not available. Cannot be used on DRAFT invoices. See: developer.xero.com/documentation/api/accounting/invoices

Raises:

  • (ArgumentError)


410
411
412
413
414
415
416
417
418
419
420
421
# File 'lib/xero_kiwi/client.rb', line 410

def online_invoice_url(tenant_id, invoice_id)
  tid = extract_tenant_id(tenant_id)
  raise ArgumentError, "tenant_id is required" if tid.nil? || tid.empty?
  raise ArgumentError, "invoice_id is required" if invoice_id.nil? || invoice_id.to_s.empty?

  data = with_authenticated_request do
    http.get("/api.xro/2.0/Invoices/#{invoice_id}/OnlineInvoice") do |req|
      req.headers["Xero-Tenant-Id"] = tid
    end
  end
  data.body.dig("OnlineInvoices", 0, "OnlineInvoiceUrl")
end

#organisation(tenant_id) ⇒ Object

Fetches the Organisation for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/organisation

Raises:

  • (ArgumentError)


96
97
98
99
100
101
102
103
104
105
106
# File 'lib/xero_kiwi/client.rb', line 96

def organisation(tenant_id)
  tid = extract_tenant_id(tenant_id)
  raise ArgumentError, "tenant_id is required" if tid.nil? || tid.empty?

  with_authenticated_request do
    response = http.get("/api.xro/2.0/Organisation") do |req|
      req.headers["Xero-Tenant-Id"] = tid
    end
    Accounting::Organisation.from_response(response.body)
  end
end

#overpayment(tenant_id, overpayment_id) ⇒ Object

Fetches a single Overpayment by ID for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/overpayments

Raises:

  • (ArgumentError)


320
321
322
323
324
325
326
327
328
329
330
331
# File 'lib/xero_kiwi/client.rb', line 320

def overpayment(tenant_id, overpayment_id)
  tid = extract_tenant_id(tenant_id)
  raise ArgumentError, "tenant_id is required" if tid.nil? || tid.empty?
  raise ArgumentError, "overpayment_id is required" if overpayment_id.nil? || overpayment_id.to_s.empty?

  with_authenticated_request do
    response = http.get("/api.xro/2.0/Overpayments/#{overpayment_id}") do |req|
      req.headers["Xero-Tenant-Id"] = tid
    end
    Accounting::Overpayment.from_response(response.body).first
  end
end

#overpayments(tenant_id, where: nil, order: nil, page: nil, modified_since: nil) ⇒ Object

Fetches the Overpayments for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/overpayments



299
300
301
302
303
304
305
306
307
308
309
# File 'lib/xero_kiwi/client.rb', line 299

def overpayments(tenant_id, where: nil, order: nil, page: nil, modified_since: nil)
  list_request(
    path:           "/api.xro/2.0/Overpayments",
    tenant_id:      tenant_id,
    resource_class: Accounting::Overpayment,
    where:          where,
    order:          order,
    page:           page,
    modified_since: modified_since
  )
end

#payment(tenant_id, payment_id) ⇒ Object

Fetches a single Payment by ID for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/payments

Raises:

  • (ArgumentError)


357
358
359
360
361
362
363
364
365
366
367
368
# File 'lib/xero_kiwi/client.rb', line 357

def payment(tenant_id, payment_id)
  tid = extract_tenant_id(tenant_id)
  raise ArgumentError, "tenant_id is required" if tid.nil? || tid.empty?
  raise ArgumentError, "payment_id is required" if payment_id.nil? || payment_id.to_s.empty?

  with_authenticated_request do
    response = http.get("/api.xro/2.0/Payments/#{payment_id}") do |req|
      req.headers["Xero-Tenant-Id"] = tid
    end
    Accounting::Payment.from_response(response.body).first
  end
end

#payments(tenant_id, where: nil, order: nil, page: nil, modified_since: nil) ⇒ Object

Fetches the Payments for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/payments



336
337
338
339
340
341
342
343
344
345
346
# File 'lib/xero_kiwi/client.rb', line 336

def payments(tenant_id, where: nil, order: nil, page: nil, modified_since: nil)
  list_request(
    path:           "/api.xro/2.0/Payments",
    tenant_id:      tenant_id,
    resource_class: Accounting::Payment,
    where:          where,
    order:          order,
    page:           page,
    modified_since: modified_since
  )
end

#prepayment(tenant_id, prepayment_id) ⇒ Object

Fetches a single Prepayment by ID for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/prepayments

Raises:

  • (ArgumentError)


246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/xero_kiwi/client.rb', line 246

def prepayment(tenant_id, prepayment_id)
  tid = extract_tenant_id(tenant_id)
  raise ArgumentError, "tenant_id is required" if tid.nil? || tid.empty?
  raise ArgumentError, "prepayment_id is required" if prepayment_id.nil? || prepayment_id.to_s.empty?

  with_authenticated_request do
    response = http.get("/api.xro/2.0/Prepayments/#{prepayment_id}") do |req|
      req.headers["Xero-Tenant-Id"] = tid
    end
    Accounting::Prepayment.from_response(response.body).first
  end
end

#prepayments(tenant_id, where: nil, order: nil, page: nil, modified_since: nil) ⇒ Object

Fetches the Prepayments for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/prepayments



225
226
227
228
229
230
231
232
233
234
235
# File 'lib/xero_kiwi/client.rb', line 225

def prepayments(tenant_id, where: nil, order: nil, page: nil, modified_since: nil)
  list_request(
    path:           "/api.xro/2.0/Prepayments",
    tenant_id:      tenant_id,
    resource_class: Accounting::Prepayment,
    where:          where,
    order:          order,
    page:           page,
    modified_since: modified_since
  )
end

#refresh_token!Object

Forces a refresh regardless of expiry. Returns the new Token. Raises TokenRefreshError if refresh credentials are missing or if Xero rejects the refresh.

Raises:



489
490
491
492
493
# File 'lib/xero_kiwi/client.rb', line 489

def refresh_token!
  raise TokenRefreshError.new(nil, nil, "client has no refresh capability") unless can_refresh?

  @refresh_mutex.synchronize { perform_refresh }
end

#revoke_token!Object

Revokes the current refresh token at Xero, invalidating it and every access token issued from it. Use this for “disconnect Xero” / logout flows. After this call, treat the client as dead — subsequent API calls will 401. The caller is responsible for cleaning up any persisted credential record.

Raises:



479
480
481
482
483
484
# File 'lib/xero_kiwi/client.rb', line 479

def revoke_token!
  raise TokenRefreshError.new(nil, nil, "client has no refresh capability") unless can_refresh?

  revoker.revoke_token(refresh_token: @token.refresh_token)
  true
end

#user(tenant_id, user_id) ⇒ Object

Fetches a single User by ID for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/users

Raises:

  • (ArgumentError)


135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/xero_kiwi/client.rb', line 135

def user(tenant_id, user_id)
  tid = extract_tenant_id(tenant_id)
  raise ArgumentError, "tenant_id is required" if tid.nil? || tid.empty?
  raise ArgumentError, "user_id is required" if user_id.nil? || user_id.to_s.empty?

  with_authenticated_request do
    response = http.get("/api.xro/2.0/Users/#{user_id}") do |req|
      req.headers["Xero-Tenant-Id"] = tid
    end
    Accounting::User.from_response(response.body).first
  end
end

#users(tenant_id, where: nil, order: nil, page: nil, modified_since: nil) ⇒ Object

Fetches the Users for the given tenant. Accepts a tenant-id string or a XeroKiwi::Connection (we use its tenant_id). See: developer.xero.com/documentation/api/accounting/users



111
112
113
114
115
116
117
118
119
120
121
# File 'lib/xero_kiwi/client.rb', line 111

def users(tenant_id, where: nil, order: nil, page: nil, modified_since: nil)
  list_request(
    path:           "/api.xro/2.0/Users",
    tenant_id:      tenant_id,
    resource_class: Accounting::User,
    where:          where,
    order:          order,
    page:           page,
    modified_since: modified_since
  )
end