Skip to content

Xero Ruby SDK for OAuth 2.0 generated from XeroAPI/Xero-OpenAPI

License

Notifications You must be signed in to change notification settings

printbear/xero-ruby

 
 

Repository files navigation

xero-ruby

Xero Ruby SDK for OAuth 2.0 generated from Xero API OpenAPI Spec

RubyGem

Current release of SDK with OAuth 2.0 support

Xero Ruby SDK supports Xero's OAuth2.0 authentication (token generation & refresh) and supports the following Xero API sets.

Coming soon

  • bank feeds
  • payroll (AU))
  • payroll (NZ/UK)
  • files
  • xero hq

Looking for OAuth 1.0a support?

Check out the Xeroizer gem (maintained by community)


Installation

This SDK is published as a gem on RubyGems as xero-ruby To install this gem to your current gemset, run:

gem install 'xero-ruby'

Or, add this to your gemfile:

gem 'xero-ruby'

Getting Started

  • Create a free Xero user account
  • Login to your Xero developer /myapps dashboard & create an API application and note your API app's credentials.

Creating a Client

Require the gem:

require 'xero-ruby'

Then create a client by passing in a named hash object credentials:.

client_id, client_secret, redirect_uri: Get this from your API application in /myapps dashboard. scopes: Include scopes as comma seperated list, https://developer.xero.com/documentation/oauth2/scopes ex: 'openid profile email accounting.transactions'

creds = {
  client_id: ENV['CLIENT_ID'],
  client_secret: ENV['CLIENT_SECRET'],
  redirect_uri: ENV['REDIRECT_URI'],
  scopes: ENV['SCOPES']
}
xero_client ||= XeroRuby::ApiClient.new(credentials: creds)

Authorization & Callback

All API requests require a valid access token to be set on the client. If this is the first time you are calling the Xero API on a users behalf you will need to generate an authorized token set, which will look something like this:

{
  "id_token": "xxx.yyy.zz",
  "access_token": "xxx.yyy.zzz",
  "expires_in": 1800,
  "token_type": "Bearer",
  "refresh_token": "xxxxxx",
  "scope": "email profile openid accounting.transactions offline_access"
}

To generate a valid token_set with this SDK from Xero, have your user follow the authorization url:

@authorization_url = xero_client.authorization_url
# https://login.xero.com/identity/connect/authorize?response_type=code&client_id=<xxx>&redirect_uri=<redirect_uri>&scope=<scopes>

The get_token_set_from_callback method will set the token_set on the client, however you can also initialize a client and set the token_set explicitly using set_token_set or refresh_token_set.

# /my-redirect-uri
token_set = xero_client.get_token_set_from_callback(params)

# this is where you will want to save the token set for future API usage..
# ex: user.update!(xero_token_set: token_set)

# if you already saved a token_set you don't need the user to authenticate via UI
# and can just set the token on the client by refreshing it.
xero_client.refresh_token_set(user.token_set)

Token & SDK Helpers

Token Sets contain information about your API connection, but most important are the access_token, refresh_token, and the expiry:

  • An access_token is valid 30 minutes and a refresh_token is valid for 60 days
@token_set = xero_client.refresh_token_set(user.token_set)

# TIP: the `updatedDateUtc` will show you the most recently authorized Tenant (AKA Organisation)
connections = xero_client.connections
[{
  "id" => "xxx-yyy-zzz",
  "tenantId" => "xxx-yyy-zzz",
  "tenantType" => "ORGANISATION",
  "tenantName" => "Demo Company (US)",
  "createdDateUtc" => "2019-11-01T20:08:03.0766400",
  "updatedDateUtc" => "2020-04-15T22:37:10.4943410"
}]

# disconnect an org from a user's connections. Pass the connection ['id'] not ['tenantId'].
remaining_connections = xero_client.disconnect(connections[0]['id'])

# set token_set
token_set = xero_client.set_token_set(user.token_set)

# access token_set
token_set = xero_client.token_set

API Usage

Comprehensive xero-ruby API usage is showcased here: https://github.com/XeroAPI/xero-ruby-oauth2-app

Here is the basic workflow of using SDK once you have a valid access_token (and token_set) stored on an instance of the xero_client

  require 'xero-ruby'

  # reference `Authorization & Callback` to first store a valid token_set on the `xero_client`
  xero_client.refresh_token_set(user.token_set)

  # Using the Accounting API set (https://github.com/XeroAPI/xero-ruby/blob/master/accounting/lib/xero-ruby/api/accounting_api.rb)

  # Examples
  invoices = xero_client.accounting_api.get_invoices(user.active_tenant_id).invoices
  accounts = xero_client.accounting_api.get_accounts(user.active_tenant_id).accounts
  contacts = xero_client.accounting_api.get_contacts(user.active_tenant_id).contacts

  contacts = xero_client.accounting_api.get_contacts(current_user.active_tenant_id).contacts
  invoices = { invoices: [{ type: XeroRuby::Accounting::Invoice::ACCREC, contact: { contact_id: contacts[0].contact_id }, line_items: [{ description: "Acme Tires", quantity: BigDecimal("2.0"), unit_amount: BigDecimal("20.99"), account_code: "600", tax_type: XeroRuby::Accounting::TaxType::NONE }], date: "2019-03-11", due_date: "2018-12-10", reference: "Website Design", status: XeroRuby::Accounting::Invoice::DRAFT }]}
  invoice = xero_client.accounting_api.create_invoices(current_user.active_tenant_id, invoices).invoices.first

  # all money and fields requiring advanced precision utilize BigDecimal
  puts invoice.unit_amount
  => 0.2099e2
  
  puts invoice.unit_amount.class 
  => BigDecimal

  puts invoice.unit_amount.to_s("F")
  => "20.99"

  # or if using Rails https://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html#method-i-number_to_currency
  number_to_currency(invoice.unit_amount, :unit => "$")

  # creating an object History record
  payment = xero_client.accounting_api.get_payments(current_user.active_tenant_id).payments.first
  history_records = { history_records:[ { details: "This payment now has some History #{rand(10000)}" } ]}
  payment_history = xero_client.accounting_api.create_payment_history(user.active_tenant_id, payment.payment_id, history_records)

  # creating an object Attachment record
  account = xero_client.accounting_api.get_accounts(current_user.active_tenant_id).accounts.first
  file_name = "an-account-filename.png"
  opts = {
    include_online: true # Boolean | Allows an attachment to be seen by the end customer within their online invoice
  }
  file = File.read(Rails.root.join('app/assets/images/xero-api.png'))
  attachment = xero_client.accounting_api.create_account_attachment_by_file_name(current_user.active_tenant_id, @account.account_id, file_name, file, opts)

  # Using the Asset API set (https://github.com/XeroAPI/xero-ruby/blob/master/accounting/lib/xero-ruby/api/asset_api.rb)
  asset = {
    "assetName": "AssetName: #{rand(10000)}",
    "assetNumber": "Asset: #{rand(10000)}",
    "assetStatus": "DRAFT"
  }
  asset = xero_client.asset_api.create_asset(current_user.active_tenant_id, asset)

  # Using the Project API set (https://github.com/XeroAPI/xero-ruby/blob/master/docs/projects/ProjectApi.md)
  projects = xero_client.project_api.get_projects(current_user.active_tenant_id).items

If you have use cases outside of these examples or this readmy, please let us know!

Sample App

The best resource to understanding how to best leverage this SDK is to clone down our Sample Rails application which showcases all the features of this project. The sample app can help you quickly understand how to:

https://github.com/XeroAPI/xero-ruby-oauth2-app

  • Complete the OAuth2.0 Authorization flow
  • Store token_sets against a user object in a DB
  • Storing info about active connections
  • Change the active tenant & make api calls to multiple orgs
  • Refreshing your token sets
  • Decoding your token_set items and strategy around how/when to refresh
  • Disconnecting a connection for a user

Additional Documentation for API Endpoints

APIS

Models

About

Xero Ruby SDK for OAuth 2.0 generated from XeroAPI/Xero-OpenAPI

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Ruby 99.9%
  • Shell 0.1%