Skip to content

Instantly share code, notes, and snippets.

@webcracy
Created November 3, 2011 16:39
Show Gist options
  • Save webcracy/1336993 to your computer and use it in GitHub Desktop.
Save webcracy/1336993 to your computer and use it in GitHub Desktop.
Manybots - Ruby on Rails tutorial
class DashboardController < ApplicationController
before_filter :authenticate_user!
def index
end
def post_activity
test_activity = Manybots::Feed::Item.new_test_activity(current_user)
activity_from_manybots = current_user.post_to_manybots!(test_activity)
render :json => activity_from_manybots
end
end
class DeviseCreateUsers < ActiveRecord::Migration
def self.up
create_table(:users) do |t|
# t.database_authenticatable :null => false
# t.recoverable
# t.rememberable
# t.trackable
# t.encryptable
# t.confirmable
# t.lockable :lock_strategy => :failed_attempts, :unlock_strategy => :both
# t.token_authenticatable
t.column 'manybots_user_id', :integer
t.column 'name', :string
t.column 'email', :string
t.column 'manybots_avatar', :string
t.column 'manybots_token', :string
t.column 'manybots_secret', :string
t.timestamps
end
add_index :users, :manybots_user_id, :unique => true
add_index :users, :email, :unique => true
# add_index :users, :reset_password_token, :unique => true
# add_index :users, :confirmation_token, :unique => true
# add_index :users, :unlock_token, :unique => true
# add_index :users, :authentication_token, :unique => true
end
def self.down
drop_table :users
end
end
<!-- In app/views/dashboard/index.html.erb -->
<h1>You're logged in!</h1>
<p>Welcome <%= current_user.name %></p>
<p>Now that you're here, you might as well register a glorious activity on your Manybots account</p>
<p><%= link_to 'Click here to post a glorious activity', post_activity_path, :method => :post, :confirm => 'Are you sure you want to post an activity?' %>
<!-- In app/views/users/omniauth_callbacks/login.html.erb -->
<h1>Login with Manybots before continuing</h1>
<p><a href="/users/auth/manybots" title="Login with Manybots">Login with Manybots</a></p>
module OmniAuth
module Strategies
# Authenticate to Manybots via OAuth and retrieve an access token for API usage
#
# Usage:
# use OmniAuth::Strategies::Manybots, 'consumerkey', 'consumersecret'
class Manybots < OmniAuth::Strategies::OAuth
# Initialize the Manybots strategy.
#
# @option options [Hash, {}] :client_options Options to be passed directly to the OAuth Consumer
def initialize(app, consumer_key=nil, consumer_secret=nil, options={}, &block)
client_options = {
:access_token_path => '/oauth/access_token',
:authorize_path => '/oauth/authorize',
:request_token_path => '/oauth/request_token',
:site => options[:manybots_url] || 'https://www.manybots.com',
}
super(app, :manybots, consumer_key, consumer_secret, client_options, options, &block)
end
def user_data
@data ||= MultiJson.decode(@access_token.get('/me.json').body)['user']
end
def auth_hash
OmniAuth::Utils.deep_merge(
super, {
'uid' => user_data['id'],
'user_info' => user_info,
}
)
end
def user_info
{
'email' => user_data['email'],
'name' => user_data['name'],
'id' => user_data['id'],
'avatar_url' => user_data['avatar_url']
}
end
end
end
end
# Manybots Rails Initializer - configurations and OAuth methods
# place this file in config/initializers/manybots.rb
MANYBOTS_CONSUMER_KEY = 'YOUR APPs CONSUMER KEY' # You'll find this information in your app's management page on Manybots
MANYBOTS_CONSUMER_SECRET = 'YOUR APPs CONSUMER SECRET' # You'll find this information in your app's management page on Manybots
MANYBOTS_URL = "https://www.manybots.com"
# Tell devise to use the Manybots Omniauth strategy
Devise.setup do |config|
config.omniauth :manybots, MANYBOTS_CONSUMER_KEY, MANYBOTS_CONSUMER_SECRET
end
module Manybots
# The Manybots module helper has two features
# 1. Extending the User model to provide an oauth client initializer and methods to access the API
# 2. Creating Feed and Feed::Item classes and methods to easily create and parse activities
module User
# to be included in the User model with
# include Manybots::User
def manybots_client
consumer ||= OAuth::Consumer.new(MANYBOTS_CONSUMER_KEY, MANYBOTS_CONSUMER_SECRET, {
:site => MANYBOTS_URL
})
access_token = OAuth::AccessToken.new(consumer, self.manybots_token, self.manybots_secret)
end
def post_to_manybots!(activity)
result = self.manybots_client.post("#{MANYBOTS_URL}/activities.json",
{:version => '1.0', :activity => activity}.to_json,
{'Content-Type' => 'application/json', 'Accept' => 'application/json'}
)
Manybots::Feed::Item.from_json result.body
end
def recent_manybots_activities
result = self.manybots_client.get('/activities.json')
Manybots::Feed.from_json(result.body).entries
end
end
class Feed
attr_accessor :entries, :raw_structure
def initialize
end
def self.from_json(json)
res = self.new
res.raw_structure = JSON.parse(json)
res.entries = []
res.raw_structure['data']['items'].each do |item|
e = Item.new(item)
res.entries << e
end
return res
end
class Item
attr_accessor :id, :url, :icon, :published, :updated
attr_accessor :title, :summary, :content, :auto_title
attr_accessor :actor, :verb, :target, :object
attr_accessor :tags
attr_accessor :generator, :provider
def initialize(data={})
item = data
# id, title, published
if(entry = item)
@id = entry['id']
@url = entry['url']
@title = entry['title']
@summary = entry['summary']
@content = entry['content']
@icon = entry['icon']
@published = entry['published']
if entry['updated']
@updated = entry['updated']
end
end
if(entry = item)
# verb
@verb = entry['verb']
# actor, target, object
[:actor, :target, :object].each do |area|
@actor ||= Item::Object.new
@target ||= Item::Object.new
@object ||= Item::Object.new
[:id, :displayName, :objectType, :url, :image].each do |attr|
unless entry.send(:[], area.to_s).nil?
json_attr = attr.to_s.gsub(/\_(\w)/) { $1.upcase }
self.send(area).send(attr.to_s + '=', entry.send(:[], area.to_s).send(:[], json_attr))
end
end
end
# provider, generator
[:provider, :generator].each do |area|
@provider ||= Item::Object.new
@generator ||= Item::Object.new
[:url, :displayName, :url, :image].each do |attr|
unless entry.send(:[], area.to_s).nil?
json_attr = attr.to_s.gsub(/\_(\w)/) { $1.upcase }
self.send(area).send(attr.to_s + '=', entry.send(:[], area.to_s).send(:[], json_attr))
end
end
end
end
self
end
def self.from_json(data)
item = JSON.parse data
e = self.new(item)
e
end
def self.new_test_activity(user=nil)
if user.is_a? User
activity = self.new
activity.published = Time.now.xmlschema
activity.id = "http://localhost:3000/articles/#{Time.now.to_i}"
activity.url = "http://localhost:3000/articles/#{Time.now.to_i}"
activity.icon = nil
activity.actor = {
:displayName => user.name,
:url => "https://www.manybots.com/users/#{user.manybots_user_id}",
:id => "https://www.manybots.com/users/#{user.manybots_user_id}",
:image => {:url => user.manybots_avatar}
}
# auto_title is a feature that automatically replaces ACTOR, OBJECT and TARGET with their URLs
# read more about in the Manybots API documention
activity.auto_title = true
activity.title = "ACTOR successfully posted OBJECT with TARGET"
activity.verb = 'post'
activity.object = {
:id => 'http://localhost:3000/articles/' + Time.now.to_i.to_s,
:url => 'http://localhost:3000/articles/' + Time.now.to_i.to_s,
:displayName => 'A test Article',
:objectType => 'article'
}
activity.target = {
:id => 'http://localhost:3000/',
:url => 'http://localhost:3000/',
:displayName => 'Manybots Test App',
:objectType => 'application'
}
activity.tags = ['test', 'rails', 'ruby', 'code']
activity.generator = activity.target
activity.generator.merge({:image => {:url => ''}})
activity.provider = activity.target
activity.provider.merge({:image => {:url => ''}})
activity
end
end
class Object
attr_accessor :id, :url, :displayName, :objectType, :image
end
class MediaLink
attr_accessor :url, :height, :width, :duration
end
end
end
end
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def manybots
# You need to implement the method below in your model
@user = User.find_for_manybots_oauth(env["omniauth.auth"], current_user)
if @user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Manybots"
sign_in_and_redirect @user, :event => :authentication
else
session["devise.manybots_data"] = env["omniauth.auth"]
redirect_to login_path
end
end
def passthru
render :file => "#{Rails.root}/public/404.html", :status => 404, :layout => false
end
def login
unless current_user
render
else
flash[:notice] = "You are already logged in."
redirect_to root_path
end
end
def logout
if current_user
flash[:notice] = 'You were logged out.'
sign_out_and_redirect current_user
else
redirect_to root_path
end
end
end
ManybotsApp::Application.routes.draw do
match 'post_activity' => 'dashboard#post_activity', :as => :post_activity
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" } do
get '/users/auth/:provider' => 'users/omniauth_callbacks#passthru'
get 'login', :to => 'users/omniauth_callbacks#login', :as => :new_user_session
get 'logout', :to => 'users/omniauth_callbacks#logout', :as => :destroy_user_session
end
root :to => 'dashboard#index'
end
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
# :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
devise :omniauthable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :manybots_user_id, :name, :manybots_avatar, :manybots_token, :manybots_secret
include Manybots::User
def self.find_for_manybots_oauth(access_token, signed_in_resource=nil)
user_info = access_token['user_info']
credentials = access_token['credentials']
# try to find the user and if we do, we update their oauth credentials
if user = User.find_by_manybots_user_id(access_token['uid']) # the standardish way to use omniauth, for your confort
user.update_attributes({:manybots_token => credentials['token'], :manybots_secret => credentials['secret'] })
user
else # Create a user
User.create! do |user|
user.manybots_token = credentials['token']
user.manybots_secret = credentials['secret']
user.email = user_info['email']
user.name = user_info['name']
user.manybots_user_id = user_info['id'].to_i
user.manybots_avatar = user_info['image']
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment