XingAPI is the offical ruby client for the XING-API. It provides easy access to all API endpoints and simplifies response parsing, error handling and tries to ease the oauth pain. Before you can start using the client, you need a XING account and create an application in the developer portal to have a consumer_key and consumer_secret.
Installation
gem install xing_api
Getting started
The simplest way to do the oauth handshake and request your own user profile:
client = XingApi::Client.new consumer_key: "YOUR_CONSUMER_KEY", consumer_secret: "YOUR_CONSUMER_SECRET"
hash = client.get_request_token # => {:request_token=>"6479c262c06f4a002643", :request_token_secret=>"d7f5a128c01574e5bf10", :authorize_url=>"https://api.xing.com/v1/authorize?oauth_token=6479c262c06f4a002643"}
# open hash[:authorize_url] in your browser and authorize the access, remember the verifier, request_token and request_token_secret for the next step!
client.get_access_token("YOUR_VERIFIER", request_token: "YOUR_REQUEST_TOKEN", request_token_secret: "YOUR_REQUEST_TOKEN_SECRET")
# ready to rock, but you have to supply the client instance with every call
XingApi::User.me(client: client)
If your know your oauth_token and oauth_token_secret already:
XingApi::Client.configure do |config|
config.consumer_key = "YOUR_CONSUMER_KEY"
config.consumer_secret = "YOUR_CONSUMER_SECRET"
config.oauth_token = "THE_USERS_OAUTH_TOKEN"
config.oauth_token_secret = "THE_USERS_OAUTH_TOKEN_SECRET"
end
# ready to rock, no need for a client instance to pass around
XingApi::User.me
Integrating it in a rails app
Outside of a console you problably want to use it a bit differently. So in a rails project for example, an initializer is a good place to put the consumer config:
XingApi::Client.configure do |config|
config.consumer_key = "YOUR_CONSUMER_KEY"
config.consumer_secret = "YOUR_CONSUMER_SECRET"
end
And, assuming you did the handshake for your user already and saved the result of Client#get_access_token together with your users id, you just need to create a client instance with the saved token and secret:
oauth_token, oauth_token_secret = # load from your db
client = XingApi::Client.new(oauth_token: oauth_token, oauth_token_secret: oauth_token_secret)
# ready to rock, there is no global token defined, so you have to supply the client instance
XingApi::User.me(client: client)
Or if you're code is executed single threaded anyway:
oauth_token, oauth_token_secret = # load from your db
XingApi::Client.configure do |config|
config.oauth_token = oauth_token
config.oauth_token_secret = oauth_token_secret
end
# no client instance needed, because oauth token is set globally
XingApi::User.me
Authenticate the user (a.k.a. the oauth handshake) is also simple, but you need to store the request_token and secret (temporarily) and the access_token and secret permanently (this token might work up to ten years), there is no need to do the handshake every time. At some point to need to start the process (assuming to configured the consumer_key and consumer_secret and your app is reachable via https://yoursite.com):
XingApi::Client.new.get_request_token("https://yoursite.com/xing_callback")
>> {:request_token=>"647...", :request_token_secret=>"d7f...", :authorize_url=>"https://api.xing.com/v1/authorize?oauth_token=647..."}
You need to store the request_token and the request_token_secret in your database and then redirect the user to the authorize_url, the user will leave your site and authorize on the xing.com. On the user granted access to your consumer, XING will redirect him back to
https://yoursite.com/xing_callback?oauth_token=647...&oauth_verifier=12345
Your app needs to get the access token next:
request_token, request_token_secret = # load from your db based on params[:oauth_token]
XingApi::Client.new.get_access_token(params[:oauth_verifier], request_token: request_token, request_token_secret: request_token_secret)
>> {:access_token=>"831...", :access_token_secret=>"d4a..."}
Store these in your database, and you're done.
Response headers
Besides of the response body that is returned you can also access the response headers:
response = XingApi::User.me
response[:users][0][:display_name]
>> "My Name"
response.headers["location"]
>> "https://api.xing.com/v1/some/location"
Error handling
Every API call might fail for a bunch of different reasons, some are call specific others might happen for every call. Every error case has a unique name, which you can use for specific error handling:
begin
XingApi::User.me(fields: 'id,display_name,foobar')
rescue XingApi::Error => e
e.status_code # 403
e.name # "INVALID_PARAMETERS"
e.text # "Invalid parameters (Invalid user field(s) given: foobar)"
e.errors # [{ field: 'some_field', reason: 'SOME_REASON' }]
end
There are some errors which your app should handle in any case:
- XingApi::InvalidOauthTokenError (the token is not valid anymore, remove the entry from your db and start the handshake again)
- XingApi::RateLimitExceededError (your consumer did too many request, try again later)
- XingApi::ServerError (server side error)
Overview of all resources
Activities
-
XingApi::Activity.delete(activity_id, options = {})
(docs) -
XingApi::Activity.find(activity_id, options = {})
(docs) -
XingApi::Activity.share(activity_id, options = {})
(docs) -
XingApi::Activity::Comment.list(activity_id, options = {})
(docs) -
XingApi::Activity::Comment.create(activity_id, comment, options = {})
(docs) -
XingApi::Activity::Comment.delete(activity_id, comment_id, options = {})
(docs) -
XingApi::Activity::Like.list(activity_id, options = {})
(docs) -
XingApi::Activity::Like.create(activity_id, options = {})
(docs) -
XingApi::Activity::Like.delete(activity_id, options = {})
(docs)
Bookmarks
-
XingApi::Bookmark.create(user_id, options = {})
(docs) -
XingApi::Bookmark.delete(user_id, options = {})
(docs) -
XingApi::Bookmark.list(options = {})
(docs)
companies
-
XingApi::Company.find(company_id, options = {})
(docs) -
XingApi::Company.search(keywords, options = {})
(docs) -
XingApi::Company.unfollow(company_id, options = {})
(docs) -
XingApi::Company.follow(company_id, options = {})
(docs) -
XingApi::Company.employees(company_id, options = {})
(docs) -
XingApi::Company.contacts(company_id, options = {})
(docs) -
XingApi::Company::Update.list(company_id, options = {})
(docs) -
XingApi::Company::Update.create(company_id, headline, content, options = {})
(docs) -
XingApi::Company::Update.edit(update_id, options = {})
(docs) -
XingApi::Company::Update.delete(update_id, options = {})
(docs) -
XingApi::Company::Update.like(update_id, options = {})
(docs) -
XingApi::Company::Update.unlike(update_id, options = {})
(docs) -
XingApi::Company::Update::Comment.list(update_id, options = {})
(docs) -
XingApi::Company::Update::Comment.create(update_id, content, options = {})
(docs) -
XingApi::Company::Update::Comment.delete(update_id, comment_id, options = {})
(docs)
Contacts
-
XingApi::Contact.list(user_id, options = {})
(docs) -
XingApi::Contact.list_ids(options = {})
(docs) -
XingApi::Contact.shared(user_id, options = {})
(docs) -
XingApi::Contact::Tag.list(user_id, options = {})
(docs) -
XingApi::ContactRequest.accept(user_id, options = {})
(docs) -
XingApi::ContactRequest.create(user_id, options = {})
(docs) -
XingApi::ContactRequest.deny(user_id, options = {})
(docs) -
XingApi::ContactRequest.list(options = {})
(docs) -
XingApi::ContactRequest.sent(options = {})
(docs)
Messages
-
XingApi::Conversation.create(recipient_ids, subject, content, options = {})
(docs) -
XingApi::Conversation.delete(conversation_id, options = {})
(docs) -
XingApi::Conversation.find(conversation_id, options = {})
(docs) -
XingApi::Conversation.list(options = {})
(docs) -
XingApi::Conversation.read(conversation_id, options = {})
(docs) -
XingApi::Conversation.unread(conversation_id, options = {})
(docs) -
XingApi::Conversation.valid_recipient(recipient_id, options = {})
(docs) -
XingApi::Conversation::Attachment.download_url(conversation_id, attachment_id, options = {})
(docs) -
XingApi::Conversation::Attachment.list(conversation_id, options = {})
(docs) -
XingApi::Conversation::Message.create(conversation_id, content, options = {})
(docs) -
XingApi::Conversation::Message.find(conversation_id, message_id, options = {})
(docs) -
XingApi::Conversation::Message.list(conversation_id, options = {})
(docs) -
XingApi::Conversation::Message.read(conversation_id, message_id, options = {})
(docs) -
XingApi::Conversation::Message.unread(conversation_id, message_id, options = {})
(docs) -
XingApi::Invite.create(emails, options = {})
(docs)
Groups
-
XingApi::Group.list(user_id, options = {})
(docs) -
XingApi::Group.search(keywords, options = {})
(docs) -
XingApi::Group.read(group_id, options = {})
(docs) -
XingApi::Group.join(group_id, options = {})
(docs) -
XingApi::Group.leave(group_id, options = {})
(docs) -
XingApi::Group::Forum.list(group_id, options = {})
(docs) -
XingApi::Group::Forum::Post.create(forum_id, title, content, options = {})
(docs) -
XingApi::Group::Forum::Post.list(forum_id, options = {})
(docs) -
XingApi::Group::MediaPreview.create(url, options = {})
(docs) -
XingApi::Group::Post.list(group_id, options = {})
(docs) -
XingApi::Group::Post.find(post_id, options = {})
(docs) -
XingApi::Group::Post.delete(post_id, options = {})
(docs) -
XingApi::Group::Post::Comment.list(post_id, options = {})
(docs) -
XingApi::Group::Post::Comment.create(post_id, content, options = {})
(docs) -
XingApi::Group::Post::Comment.delete(comment_id, options = {})
(docs) -
XingApi::Group::Post::Comment::Like.list(comment_id, options = {})
(docs) -
XingApi::Group::Post::Comment::Like.create(comment_id, options = {})
(docs) -
XingApi::Group::Post::Comment::Like.delete(comment_id, options = {})
(docs) -
XingApi::Group::Post::Like.list(post_id, options = {})
(docs) -
XingApi::Group::Post::Like.create(post_id, options = {})
(docs) -
XingApi::Group::Post::Like.delete(post_id, options = {})
(docs)
Jobs
-
XingApi::Job.find(job_id, options = {})
(docs) -
XingApi::Job.recommendations(options = {})
(docs) -
XingApi::Job.search(query, options = {})
(docs)
News
-
XingApi::News::Article::Like.list(article_id, options = {})
(docs) -
XingApi::News::Article::Like.create(article_id, options = {})
(docs) -
XingApi::News::Article::Like.delete(article_id, options = {})
(docs) -
XingApi::News::Article.find(article_id, options = {})
(docs) -
XingApi::News::Article.update(article_id, version, options = {})
(docs) -
XingApi::News::Article.delete(article_id, version, options = {})
(docs) -
XingApi::News::Page.find(page_id, options = {})
(docs) -
XingApi::News::Page.list_editable(options = {})
(docs) -
XingApi::News::Page.list_following(options = {})
(docs) -
XingApi::News::Page::Article.create(page_id, source_url, title, options = {})
(docs) -
XingApi::News::Page::Article.list(page_id, options = {})
(docs)
Profile Messages
-
XingApi::ProfileMessage.delete(options = {})
(docs) -
XingApi::ProfileMessage.find(user_id, options = {})
(docs) -
XingApi::ProfileMessage.update(message, options = {})
(docs)
Visits
-
XingApi::ProfileVisit.create(user_id, options = {})
(docs) -
XingApi::ProfileVisit.list(options = {})
(docs)
Users
-
XingApi::User.activities(user_id, options = {})
(docs) -
XingApi::User.find(user_id, options = {})
(docs) -
XingApi::User.find_by_emails(emails, options = {})
(docs) -
XingApi::User.id_card(options = {})
(docs) -
XingApi::User.me(options = {})
(docs) -
XingApi::User.share_link(uri, options = {})
(docs) -
XingApi::User.network_activities(options = {})
(docs) -
XingApi::User.paths(user_id, options = {})
(docs) -
XingApi::User.search(keywords, options = {})
(docs) -
XingApi::User.shared(user_id, options = {})
(docs) -
XingApi::User.status_message(message, options = {})
(docs) -
XingApi::User.update(options = {})
(docs) -
XingApi::User::BusinessAddress.update(options = {})
(docs) -
XingApi::User::BirthDate.update(day, month, year, options = {})
(docs) -
XingApi::User::Company.create(name, title, industry, employment_type, options = {})
(docs) -
XingApi::User::Company.delete(company_id, options = {})
(docs) -
XingApi::User::Company.primary_company(company_id, options = {})
(docs) -
XingApi::User::Company.update(company_id, options = {})
(docs) -
XingApi::User::Company.recommendations(options = {})
(docs) -
XingApi::User::Company.following(options = {})
(docs) -
XingApi::User::Company.managing(options = {})
(docs) -
XingApi::User::Language.delete(language, options = {})
(docs) -
XingApi::User::Language.update(language, options = {})
(docs) -
XingApi::User::Photo.delete(options = {})
(docs) -
XingApi::User::Photo.update(body_hash, options = {})
(docs) -
XingApi::User::PrivateAddress.update(options = {})
(docs) -
XingApi::User::Recommendation.delete(user_id, options = {})
(docs) -
XingApi::User::Recommendation.list(options = {})
(docs) -
XingApi::User::School.create(name, options = {})
(docs) -
XingApi::User::School.delete(school_id, options = {})
(docs) -
XingApi::User::School.update(school_id, options = {})
(docs) -
XingApi::User::School.primary_school(school_id, options = {})
(docs) -
XingApi::User::Qualification.create(description, options = {})
(docs) -
XingApi::User::WebProfile.delete(profile, options = {})
(docs)
Contact
If you have problems or feedback, feel free to contact us:
- XING-Developer-Group: https://www.xing.com/net/xingdevs/
- Mail: api-support@xing.com
- Twitter: @xingapi
If you want to contribute, just fork this project and send us a pull request.
Authors
Mark Schmidt and Johannes Strampe Please find out more about our work in our dev blog.
Copyright (c) 2016 XING AG
Released under the MIT license. For full details see LICENSE included in this distribution.