Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 35 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,45 @@ Installation
------------
gem install yammer

What's in 0.1.2?
What's in 0.1.4?
----------------

This release offers some additional API support thanks to [ybenjo](https://github.com/ybenjo), eg suggestions, search and groups.
This release rips old the old api dependencies on Faraday and whatever else handles connection related issues and passed it all off to Yammer's own Yam gem(which itself uses Faraday).

We still only offer the most basic support for [Yammer's REST API](https://developer.yammer.com/api/).
This gem is **far** from finished or offering complete coverage of all the API methods offered by Yammer. It's our first release covering our basic needs to hook into the messages API.
Improved api support

We are releasing this early version in order to share the path we have taken, offer the community a new Ruby Gem to interact with the Yammer API and build upon it with more support of others that might find it useful.
yam.users
yam.in_group

Better Exception Handling

It was completely broken, now you can catch all sorts of exceptions with Yammer api based upon http status:

- 400: Yammer::BadRequest
- 401: Yammer::Unauthorized
- 403: Yammer::Forbidden
- 404: Yammer::NotFound
- 406: Yammer::NotAcceptable
- 500: Yammer:InternalServerError
- 502: Yammer::BadGateway
- 503: Yammer::ServiceUnavailable


Getting Started
---------------

You should probably be using Omniauth(http://github.com/intridea/omniauth), cuz its awesome, and be following that flow. Ryan Bate's excellent RailsCasts are also a great reference: http://railscasts.com/episodes/236-omniauth-part-2

Whatever controller handles the callback, you will have access to a "credentials" key in the oauth object which has an "expires" key, and a "token" key. I stash that entire object in a serialized string in my Authentication model. This token is what you will need.

token = current_user.authentications.find_by_provider("yammer").credentials.token
yam = Yammer.new(oauth_token: token)

That's it!

yam.groups
yam.users

I am eternally grateful for the work that the team that created the awesome (did I say how awesome that Gem is already? ;) ) [Twitter](https://github.com/jnunemaker/twitter) Ruby Gem put into it and made it open and free. **THANK YOU** :)

TODO
----
Expand Down Expand Up @@ -76,4 +104,4 @@ Submitting a Pull Request
Copyright
---------
Copyright (c) 2011, Bruno Mattarollo <bruno@road.ly>
See [LICENSE](https://github.com/roadly/yammer/blob/master/LICENSE.md) for details.
See [LICENSE](https://github.com/roadly/yammer/blob/master/LICENSE.md) for details.
1 change: 1 addition & 0 deletions lib/yammer.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'yam'
require 'yammer/api'
require 'yammer/client'
require 'yammer/configuration'
Expand Down
18 changes: 8 additions & 10 deletions lib/yammer/authentication.rb
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
module Yammer
# @private
module Authentication
# Check whether user is authenticated
#
# @return [Boolean]
def authenticated?
authentication.values.all?
end

private

# Authentication hash
#
# @return [Hash]
def authentication
{
:consumer_key => consumer_key,
:consumer_secret => consumer_secret,
:token => oauth_token,
:token_secret => oauth_token_secret,
oauth_token: oauth_token
}
end

# Check whether user is authenticated
#
# @return [Boolean]
def authenticated?
authentication.values.all?
end
end
end
2 changes: 2 additions & 0 deletions lib/yammer/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class Client < API
require 'yammer/client/search'
require 'yammer/client/suggestions'
require 'yammer/client/groups'
require 'yammer/client/activity'

alias :api_endpoint :endpoint

Expand All @@ -22,5 +23,6 @@ class Client < API
include Yammer::Client::Search
include Yammer::Client::Suggestions
include Yammer::Client::Groups
include Yammer::Client::Activity
end
end
9 changes: 9 additions & 0 deletions lib/yammer/client/activity.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Yammer
class Client
module Activity
def new_activity(options={})
response = post('activity', options)
end
end
end
end
21 changes: 21 additions & 0 deletions lib/yammer/client/users.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,27 @@ module Users
def find_by_id(id, options={})
response = get("users/#{id}", options, :json)
end

def users(options={})
response = get("users", options, :json)
end

def in_group(group_id, options={})
response = get("users/in_group/#{group_id}", options, :json)
end

def current(options={})
response = get("users/current", options, :json)
end

def followers(name, options={})
response = get("users/following/#{name}", options, :json)
end

def following(email, options={})
response = get("users/by_email?email=#{email}", options, :json)
end

end
end
end
15 changes: 0 additions & 15 deletions lib/yammer/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,16 @@ module Configuration
# An array of valid keys in the options hash when configuring a {Yammer::API}
VALID_OPTIONS_KEYS = [
:adapter,
:consumer_key,
:consumer_secret,
:endpoint,
:format,
:gateway,
:oauth_token,
:oauth_token_secret,
:proxy,
:user_agent].freeze

# The adapter that will be used to connect if none is set
DEFAULT_ADAPTER = :net_http

# By default, don't set an application key
DEFAULT_CONSUMER_KEY = nil

# By default, don't set an application secret
DEFAULT_CONSUMER_SECRET = nil

# The endpoint that will be used to connect if none is set
#
# @note This is configurable in case you want to use HTTP instead of HTTPS, specify a different API version.
Expand All @@ -38,9 +29,6 @@ module Configuration
# By default, don't set a user oauth token
DEFAULT_OAUTH_TOKEN = nil

# By default, don't set a user oauth secret
DEFAULT_OAUTH_TOKEN_SECRET = nil

# By default, don't use a proxy server
DEFAULT_PROXY = nil

Expand Down Expand Up @@ -72,12 +60,9 @@ def options
# Reset all configuration options to defaults
def reset
self.adapter = DEFAULT_ADAPTER
self.consumer_key = DEFAULT_CONSUMER_KEY
self.consumer_secret = DEFAULT_CONSUMER_SECRET
self.endpoint = DEFAULT_ENDPOINT
self.format = DEFAULT_FORMAT
self.oauth_token = DEFAULT_OAUTH_TOKEN
self.oauth_token_secret = DEFAULT_OAUTH_TOKEN_SECRET
self.proxy = DEFAULT_PROXY
self.user_agent = DEFAULT_USER_AGENT
self.gateway = DEFAULT_GATEWAY
Expand Down
36 changes: 1 addition & 35 deletions lib/yammer/connection.rb
Original file line number Diff line number Diff line change
@@ -1,44 +1,10 @@
require 'faraday_middleware'
require 'faraday/request/multipart_with_file'
require 'faraday/request/gateway'
require 'faraday/request/yammer_oauth'
require 'faraday/response/raise_http_4xx'
require 'faraday/response/raise_http_5xx'

module Yammer
# @private
module Connection
private

def connection(format=format)
options = {
:headers => {
:accept => "application/#{format}",
:user_agent => user_agent,
},
:proxy => proxy,
:ssl => {:verify => false},
:url => api_endpoint,
}

Faraday.new(options) do |builder|
builder.use Faraday::Request::MultipartWithFile
builder.use Faraday::Request::YammerOAuth, authentication if authenticated?
builder.use Faraday::Request::Multipart
builder.use Faraday::Request::UrlEncoded
builder.use Faraday::Request::Gateway, gateway if gateway
builder.use Faraday::Response::RaiseHttp4xx
case format.to_s.downcase
when 'json'
builder.use Faraday::Response::Mashify
builder.use Faraday::Response::ParseJson
when 'xml'
builder.use Faraday::Response::Mashify
builder.use Faraday::Response::ParseXml
end
builder.use Faraday::Response::RaiseHttp5xx
builder.adapter(adapter)
end
Yam.new(oauth_token, endpoint)
end
end
end
51 changes: 51 additions & 0 deletions lib/yammer/error.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,52 @@
module Yammer

# This gem seems to monkey patch faraday to catch certain exceptions
# and even that attempt does not seem to be loaded anywhere, so instead
# we'll catch the error on every request(and possibly elsewhere)
# and then pass the exception to this class who will figure out the proper
# high level exception to raise
class ErrorProxy
def self.new(exception)
return self.determine_exception(exception)
end

def self.determine_exception(exception)
exception = exception
message = exception.message
status = exception.response[:status]
headers = exception.response[:headers]

case status.to_i
when 400
Yammer::BadRequest.new(error_message(message), headers)
when 401
Yammer::Unauthorized.new(error_message(message), headers)
when 403
Yammer::Forbidden.new(error_message(message), headers)
when 404
Yammer::NotFound.new(error_message(message), headers)
when 429
Yammer::TooManyRequests.new(error_message(message), headers)
when 406
Yammer::NotAcceptable.new(error_message(message), headers)
when 500
Yammer::InternalServerError.new(error_message("Something is technically wrong."), headers)
when 502
Yammer::BadGateway.new(error_message("Yammer is down or being upgraded."), headers)
when 503
Yammer::ServiceUnavailable.new(error_message("(__-){ Yammer is over capacity."), headers)
else
Exception.new("Unhandled Exception Status: #{status} - #{message}")
end
end

private
def self.error_message(msg)
#TODO: this can be used in the future to print nicer messages
msg
end
end

# Custom error class for rescuing from all Yammer errors
class Error < StandardError
attr_reader :http_headers
Expand Down Expand Up @@ -48,4 +96,7 @@ class BadGateway < Error; end

# Raised when Yammer returns the HTTP status code 503
class ServiceUnavailable < Error; end

# Raised when you hit Yammer's request rate limit
class TooManyRequests < Error;end
end
29 changes: 19 additions & 10 deletions lib/yammer/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,31 @@ def delete(path, options={}, format=format)
# Perform an HTTP request
def request(method, path, options, format)
begin
response = connection(format).send(method) do |request|
case method.to_sym
when :get, :delete
request.url(formatted_path(path, format), options)
when :post, :put
request.path = formatted_path(path, format)
request.body = options unless options.empty?
end
end
'raw' == format.to_s.downcase ? response : response.body
case method.to_sym
when :get, :delete
response = connection.send(method, formatted_path(path, format), options)
when :post
response = connection.send(method, formatted_path(path, format), options)
when :put
raise "PUT verbs are not yet supported!"
# request.path = formatted_path(path, format)
# request.body = options unless options.empty?
end

#TODO: format is not obeyed. From Yam we get back an array of objects
response

rescue MultiJson::DecodeError
Hashie::Mash.new
rescue Faraday::Error::ClientError => e
raise Yammer::ErrorProxy.new(e)

end
end

def formatted_path(path, format)
#paths must have a leading /
path = "/#{path}" if path[0] != "/"
case format.to_s.downcase
when 'json', 'xml'
[path, format].compact.join('.')
Expand Down
2 changes: 1 addition & 1 deletion lib/yammer/version.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module Yammer
# The version of the gem
VERSION = '0.1.2'.freeze unless defined?(::Yammer::VERSION)
VERSION = '0.1.6'.freeze unless defined?(::Yammer::VERSION)
end
21 changes: 4 additions & 17 deletions yammer.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,13 @@ $:.push File.expand_path("../lib", __FILE__)
require "yammer/version"

Gem::Specification.new do |gem|
gem.add_development_dependency 'maruku', '~> 0.6'
gem.add_development_dependency 'nokogiri', '~> 1.4'
gem.add_development_dependency 'rake', '~> 0.9'
gem.add_development_dependency 'rspec', '~> 2.6'
gem.add_development_dependency 'simplecov', '~> 0.4'
gem.add_development_dependency 'webmock', '~> 1.6'
gem.add_development_dependency 'yard', '~> 0.7'
gem.add_development_dependency 'ZenTest', '~> 4.5'
gem.add_runtime_dependency 'hashie', '~> 1.0.0'
gem.add_runtime_dependency 'faraday', '~> 0.6.1'
gem.add_runtime_dependency 'faraday_middleware', '~> 0.6.3'
gem.add_runtime_dependency 'multi_json', '~> 1.0.0'
gem.add_runtime_dependency 'multi_xml', '~> 0.2.0'
gem.add_runtime_dependency 'simple_oauth', '~> 0.1.5'
gem.authors = ["Bruno Mattarollo"]
gem.add_runtime_dependency 'yam', '~> 0.0.6'
gem.authors = ["Bruno Mattarollo, Peter Philips"]
gem.description = %q{A Ruby wrapper for the Yammer REST API}
gem.email = ['bruno.mattarollo@gmail.com']
gem.email = ['bruno.mattarollo@gmail.com', 'pete@p373.net']
gem.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
gem.files = `git ls-files`.split("\n")
gem.homepage = 'https://github.com/roadly/yammer'
gem.homepage = 'https://github.com/synth/yammer'
gem.name = 'yammer'
gem.require_paths = ['lib']
gem.required_rubygems_version = Gem::Requirement.new('>= 1.3.6')
Expand Down