| Class | Facebooker::Rails::Publisher |
| In: |
lib/facebooker/rails/publisher.rb
|
| Parent: | Object |
ActionMailer like module for publishing Facbook messages
To use, create a subclass and define methods Each method should start by calling send_as to specify the type of message Valid options are :email and :notification, :user_action, :profile, :ref
Below is an example of each type
class TestPublisher < Facebooker::Rails::Publisher
# The new message templates are supported as well
# First, create a method that contains your templates:
# You may include multiple one line story templates and short story templates
# but only one full story template
# Your most specific template should be first
#
# Before using, you must register your template by calling register. For this example
# You would call TestPublisher.register_publish_action
# Registering the template will store the template id returned from Facebook in the
# facebook_templates table that is created when you create your first publisher
def publish_action_template
one_line_story_template "{*actor*} did stuff with {*friend*}"
one_line_story_template "{*actor*} did stuff"
short_story_template "{*actor*} has a title {*friend*}", render(:partial=>"short_body")
short_story_template "{*actor*} has a title", render(:partial=>"short_body")
full_story_template "{*actor*} has a title {*friend*}", render(:partial=>"full_body")
action_links action_link("My text {*template_var*}","{*link_url*}")
end
# To send a registered template, you need to create a method to set the data
# The publisher will look up the template id from the facebook_templates table
def publish_action(f)
send_as :user_action
from f
story_size SHORT # or ONE_LINE or FULL
data :friend=>"Mike"
end
# Provide a from user to send a general notification
# if from is nil, this will send an announcement
def notification(to,f)
send_as :notification
recipients to
from f
fbml "Not"
end
def email(to,f)
send_as :email
recipients to
from f
title "Email"
fbml 'text'
text fbml
end
# This will render the profile in /users/profile.fbml.erb
# it will set @user to user_to_update in the template
# The mobile profile will be rendered from the app/views/test_publisher/_mobile.erb
# template
def profile_update(user_to_update,user_with_session_to_use)
send_as :profile
from user_with_session_to_use
recipients user_to_update
profile render(:file=>"users/profile.fbml.erb",:assigns=>{:user=>user_to_update})
profile_action "A string"
mobile_profile render(:partial=>"mobile",:assigns=>{:user=>user_to_update})
end
# Update the given handle ref with the content from a
# template
def ref_update(user)
send_as :ref
from user
fbml render(:file=>"users/profile",:assigns=>{:user=>user_to_update})
handle "a_ref_handle"
end
To send a message, use ActionMailer like semantics
TestPublisher.deliver_action(@user)
For testing, you may want to create an instance of the underlying message without sending it
TestPublisher.create_action(@user)
will create and return an instance of Facebooker::Feeds::Action
Publisher makes many helpers available, including the linking and asset helpers
| ONE_LINE | = | 1 | story sizes from the Facebooker API | |
| SHORT | = | 2 | ||
| FULL | = | 4 |
| _body | [RW] | |
| action_links | [W] | |
| one_line_story_templates | [RW] | |
| short_story_templates | [RW] |
# File lib/facebooker/rails/publisher.rb, line 494 def default_url_options {:host => Facebooker.canvas_server_base + Facebooker.facebook_path_prefix} end
# File lib/facebooker/rails/publisher.rb, line 502 def helper(*args) args.each do |arg| case arg when Symbol,String add_template_helper("#{arg.to_s.classify}Helper".constantize) when Module add_template_helper(arg) end end end
# File lib/facebooker/rails/publisher.rb, line 519 def inherited(child) super child.master_helper_module=Module.new child.master_helper_module.__send__(:include,self.master_helper_module) child.send(:include, child.master_helper_module) FacebookTemplate.clear_cache! end
# File lib/facebooker/rails/publisher.rb, line 469 def method_missing(name,*args) should_send = false method = '' if md = /^create_(.*)$/.match(name.to_s) method = md[1] elsif md = /^deliver_(.*)$/.match(name.to_s) method = md[1] should_send = true elsif md = /^register_(.*)$/.match(name.to_s) return FacebookTemplate.register(self, md[1]) else super end #now create the item (publisher=new).send(method,*args) case publisher._body when UserAction publisher._body.template_name = method publisher._body.template_id ||= FacebookTemplate.bundle_id_for_class_and_method(self,method) end should_send ? publisher.send_message(method) : publisher._body end
# File lib/facebooker/rails/publisher.rb, line 97 def initialize @from = nil @full_story_template = nil @recipients = nil @controller = PublisherController.new end
# File lib/facebooker/rails/publisher.rb, line 460 def register_all_templates all_templates = instance_methods.grep(/_template$/) - %w(short_story_template full_story_template one_line_story_template) all_templates.each do |template| template_name=template.sub(/_template$/,"") puts "Registering #{template_name}" send("register_"+template_name) end end
# File lib/facebooker/rails/publisher.rb, line 339 def action_link(text,target) {:text=>text, :href=>target} end
# File lib/facebooker/rails/publisher.rb, line 300 def action_links(*links) if links.blank? @action_links else @action_links = links end end
# File lib/facebooker/rails/publisher.rb, line 355 def announcement_notification?(from,body) from.nil? and body.is_a?(Notification) end
# File lib/facebooker/rails/publisher.rb, line 250 def from(*args) if args.size==0 @from else @from=args.first end end
# File lib/facebooker/rails/publisher.rb, line 282 def full_story_template(title=nil,body=nil,params={}) if title.nil? @full_story_template else @full_story_template=params.merge(:template_title=>title, :template_body=>body) end end
# File lib/facebooker/rails/publisher.rb, line 335 def image(src,target) ImageHolder.new(image_path(src),target.respond_to?(:to_str) ? target : url_for(target)) end
# File lib/facebooker/rails/publisher.rb, line 408 def initialize_template_class(assigns) template_root = "#{RAILS_ROOT}/app/views" controller_root = File.join(template_root,self.class.controller_path) #only do this on Rails 2.1 if ActionController::Base.respond_to?(:append_view_path) # only add the view path once unless ActionController::Base.view_paths.include?(controller_root) ActionController::Base.append_view_path(controller_root) ActionController::Base.append_view_path(controller_root+"/..") end view_paths = ActionController::Base.view_paths else view_paths = [template_root, controller_root] end returning ActionView::Base.new(view_paths, assigns, self) do |template| template.controller=self template.extend(self.class.master_helper_module) def template.request_comes_from_facebook? true end end end
nodoc needed for actionview
# File lib/facebooker/rails/publisher.rb, line 395 def logger RAILS_DEFAULT_LOGGER end
# File lib/facebooker/rails/publisher.rb, line 308 def method_missing(name,*args) if args.size==1 and self._body.respond_to?("#{name}=") self._body.send("#{name}=",*args) elsif self._body.respond_to?(name) self._body.send(name,*args) else super end end
# File lib/facebooker/rails/publisher.rb, line 290 def one_line_story_template(str) @one_line_story_templates ||= [] @one_line_story_templates << str end
# File lib/facebooker/rails/publisher.rb, line 347 def profile_update?(body) body.is_a?(Profile) end
define this for the publisher views
# File lib/facebooker/rails/publisher.rb, line 447 def protect_against_forgery?protect_against_forgery? @paf ||= ActionController::Base.new.send(:protect_against_forgery?) end
# File lib/facebooker/rails/publisher.rb, line 242 def recipients(*args) if args.size==0 @recipients else @recipients=args.first end end
use facebook options everywhere
# File lib/facebooker/rails/publisher.rb, line 105 def request_comes_from_facebook? true end
# File lib/facebooker/rails/publisher.rb, line 343 def requires_from_user?(from,body) ! (announcement_notification?(from,body) or ref_update?(body) or profile_update?(body)) end
# File lib/facebooker/rails/publisher.rb, line 259 def send_as(option) self._body=case option when :action Facebooker::Feed::Action.new when :story Facebooker::Feed::Story.new when :templatized_action Facebooker::Feed::TemplatizedAction.new when :notification Notification.new when :email Email.new when :profile Profile.new when :ref Ref.new when :user_action UserAction.new else raise UnknownBodyType.new("Unknown type to publish") end end
# File lib/facebooker/rails/publisher.rb, line 359 def send_message(method) @recipients = @recipients.is_a?(Array) ? @recipients : [@recipients] if from.nil? and @recipients.size==1 and requires_from_user?(from,_body) @from = @recipients.first end # notifications can # omit the from address raise InvalidSender.new("Sender must be a Facebooker::User") unless from.is_a?(Facebooker::User) || !requires_from_user?(from,_body) case _body when Facebooker::Feed::TemplatizedAction,Facebooker::Feed::Action from.publish_action(_body) when Facebooker::Feed::Story @recipients.each {|r| r.publish_story(_body)} when Notification (from.nil? ? Facebooker::Session.create : from.session).send_notification(@recipients,_body.fbml) when Email from.session.send_email(@recipients, _body.title, _body.text, _body.fbml) when Profile # If recipient and from aren't the same person, create a new user object using the # userid from recipient and the session from from @from = Facebooker::User.new(Facebooker::User.cast_to_facebook_id(@recipients.first),Facebooker::Session.create) @from.set_profile_fbml(_body.profile, _body.mobile_profile, _body.profile_action, _body.profile_main) when Ref Facebooker::Session.create.server_cache.set_ref_handle(_body.handle,_body.fbml) when UserAction @from.session.publish_user_action(_body.template_id,_body.data_hash,_body.target_ids,_body.body_general,_body.story_size) else raise UnspecifiedBodyType.new("You must specify a valid send_as") end end
# File lib/facebooker/rails/publisher.rb, line 295 def short_story_template(title,body,params={}) @short_story_templates ||= [] @short_story_templates << params.merge(:template_title=>title, :template_body=>body) end