diff --git a/app/models/channel/facebook.rb b/app/models/channel/facebook.rb index 4cc289611..2afb09a9a 100644 --- a/app/models/channel/facebook.rb +++ b/app/models/channel/facebook.rb @@ -7,7 +7,7 @@ class Channel::Facebook def fetch (channel) @channel = channel - @facebook = Facebook.new( @channel[:options][:auth] ) + @facebook = Facebook.new( @channel[:options] ) @sync = @channel[:options][:sync] Rails.logger.debug 'facebook fetch started' @@ -22,7 +22,7 @@ class Channel::Facebook def send(article, _notification = false) @channel = Channel.find_by( area: 'Facebook::Inbound', active: true ) - @facebook = Facebook.new( @channel[:options][:auth] ) + @facebook = Facebook.new( @channel[:options] ) tweet = @facebook.from_article(article) disconnect diff --git a/db/migrate/20150717000001_facebook_article_types.rb b/db/migrate/20150717000001_facebook_article_types.rb new file mode 100644 index 000000000..b8fad083f --- /dev/null +++ b/db/migrate/20150717000001_facebook_article_types.rb @@ -0,0 +1,17 @@ +class FacebookArticleTypes < ActiveRecord::Migration + def up + facebook_at = Ticket::Article::Type.find_by( name: 'facebook' ) + + return if !facebook_at + + facebook_at.name = 'facebook feed post' + facebook_at.save + + Ticket::Article::Type.create( + name: 'facebook feed comment', + communication: true, + updated_by_id: 1, + created_by_id: 1 + ) + end +end diff --git a/db/seeds.rb b/db/seeds.rb index c90e5804d..a28b1e794 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1501,9 +1501,10 @@ Ticket::Article::Type.create_if_not_exists( id: 4, name: 'fax', communication: t Ticket::Article::Type.create_if_not_exists( id: 5, name: 'phone', communication: true ) Ticket::Article::Type.create_if_not_exists( id: 6, name: 'twitter status', communication: true ) Ticket::Article::Type.create_if_not_exists( id: 7, name: 'twitter direct-message', communication: true ) -Ticket::Article::Type.create_if_not_exists( id: 8, name: 'facebook', communication: true ) -Ticket::Article::Type.create_if_not_exists( id: 9, name: 'note', communication: false ) -Ticket::Article::Type.create_if_not_exists( id: 10, name: 'web', communication: true ) +Ticket::Article::Type.create_if_not_exists( id: 8, name: 'facebook feed post', communication: true ) +Ticket::Article::Type.create_if_not_exists( id: 9, name: 'facebook feed comment', communication: true ) +Ticket::Article::Type.create_if_not_exists( id: 10, name: 'note', communication: false ) +Ticket::Article::Type.create_if_not_exists( id: 11, name: 'web', communication: true ) Ticket::Article::Sender.create_if_not_exists( id: 1, name: 'Agent' ) Ticket::Article::Sender.create_if_not_exists( id: 2, name: 'Customer' ) diff --git a/lib/facebook.rb b/lib/facebook.rb index a2b8d880e..a07842d3d 100644 --- a/lib/facebook.rb +++ b/lib/facebook.rb @@ -130,37 +130,41 @@ class Facebook ticket.save end - user = to_user(comment) + user = to_user(post) return if !user feed_post = { - from: user.name, + from: "#{user.firstname} #{user.lastname}", body: post['message'], message_id: post['id'], - type: Ticket::Article::Type.find_by( name: 'facebook feed post' ), + type_id: Ticket::Article::Type.find_by( name: 'facebook feed post' ).id, } articles = [] articles.push( feed_post ) - post['comments']['data'].each { |comment| + if post['comments'] + post['comments']['data'].each { |comment| - user = to_user(comment) + user = to_user(comment) - next if !user + next if !user - post_comment = { - from: user.name, - body: comment['message'], - message_id: comment['id'], - type: Ticket::Article::Type.find_by( name: 'facebook feed comment' ), + post_comment = { + from: "#{user.firstname} #{user.lastname}", + body: comment['message'], + message_id: comment['id'], + type_id: Ticket::Article::Type.find_by( name: 'facebook feed comment' ).id, + } + articles.push( post_comment ) + + # TODO: sub-comments + # comment_data = @client.get_object( comment['id'] ) } - articles.push( post_comment ) + end - # TODO: sub-comments - # comment_data = @client.get_object( comment['id'] ) - } + inverted_articles = articles.reverse - articles.invert.each { |article| + inverted_articles.each { |article| break if Ticket::Article.find_by( message_id: article[:message_id] ) @@ -168,6 +172,9 @@ class Facebook to: @account['name'], ticket_id: ticket.id, internal: false, + sender_id: Ticket::Article::Sender.lookup( name: 'Customer' ).id, + created_by_id: 1, + updated_by_id: 1, }.merge( article ) Ticket::Article.create( article ) @@ -204,12 +211,11 @@ class Facebook def from_article(article) post = nil - # TODO: article[:type] == 'facebook feed post' if article[:type] == 'facebook feed comment' Rails.logger.debug 'Create feed comment from article...' - post = @client.put_wall_post(article[:body], {}, article[:in_reply_to]) + post = @client.put_comment(article[:in_reply_to], article[:body]) else fail "Can't handle unknown facebook article type '#{article[:type]}'." end diff --git a/test/integration/facebook_test.rb b/test/integration/facebook_test.rb new file mode 100644 index 000000000..6e118ea02 --- /dev/null +++ b/test/integration/facebook_test.rb @@ -0,0 +1,154 @@ +# encoding: utf-8 +require 'integration_test_helper' + +class FacebookTest < ActiveSupport::TestCase + + # set system mode to done / to activate + Setting.set('system_init_done', true) + + # needed to check correct behavior + Group.create_if_not_exists( + id: 2, + name: 'Facebook', + note: 'All Facebook feed posts.', + updated_by_id: 1, + created_by_id: 1 + ) + + provider_key = 'CAACEdEose0cBAC56WJvrGb5avKbTlH0c7P4xZCZBfT8zG4nkgEWeFKGnnpNZC8xeedXzmqZCxEUrAumX245T4MborvAmRW52PSpuDiXwXXSMjYaZCJOih5v6CsP3xrZAfGxhPWBbI8dSoquBv8eRbUAMSir9SDSoDeKJSdSfhuytqx5wfveE8YibzT2ZAwYz0d7d2QZAN4b10d9j9UpBhXCCCahj4hyk9JQZD' + consumer_key = 'CAACEdEose0cBAHZCXAQ68snZBf2C7jT6G7pVXaWajbZCZAZAFWRZAVUb9FAMXHZBQECZBX0iL5qOeTsZA0mnR0586XTq9vYiWP8Y3qCzftrd9hnsP7J9VB6APnR67NEdY8SozxIFtctQA9Xp4Lb8lbxBmig2v5oXRIH513kImPYXJoCFUlQs0aJeZBCtRG6BekfPs5GPZB8tieQE3yGgtZBTZA3HI2TtQLZBNXyLAZD' + + provider_page_name = 'Hansi Merkurs Hutfabrik' + provider_options = { + auth: { + access_token: provider_key + }, + sync: { + page: provider_page_name, + group_id: 2, + limit: 1, + } + } + + # add channel + current = Channel.where( adapter: 'Facebook' ) + current.each(&:destroy) + Channel.create( + adapter: 'Facebook', + area: 'Facebook::Inbound', + options: provider_options, + active: true, + created_by_id: 1, + updated_by_id: 1, + ) + + test 'pages' do + + provider_options_clone = provider_options + + provider_options_clone[:sync].delete(:page) + + facebook = Facebook.new( provider_options_clone ) + + pages = facebook.pages + + page_found = false + pages.each { |page| + + next if page[:name] != provider_page_name + page_found = true + } + + assert( page_found, "Page lookup for '#{provider_page_name}'" ) + end + + test 'feed post to ticket' do + + consumer_client = Koala::Facebook::API.new( consumer_key ) + feed_post = "I've got an issue with my hat, serial number ##{rand(9999)}" + + facebook = Facebook.new( provider_options ) + + post = consumer_client.put_wall_post(feed_post, {}, facebook.account['id']) + + # fetch check system account + Channel.fetch + + # check if first article has been created + article = Ticket::Article.find_by( message_id: post['id'] ) + + assert( article, "article post '#{post['id']}' imported" ) + assert_equal( article.body, feed_post, 'ticket article inbound body' ) + assert_equal( 1, article.ticket.articles.count, 'ticket article inbound count' ) + assert_equal( feed_post, article.ticket.articles.last.body, 'ticket article inbound body' ) + + post_comment = "Any updates yet? It's urgent. I love my hat." + comment = consumer_client.put_comment(post['id'], post_comment) + + # fetch check system account + Channel.fetch + + # check if second article has been created + article = Ticket::Article.find_by( message_id: comment['id'] ) + + assert( article, "article comment '#{comment['id']}' imported" ) + assert_equal( article.body, post_comment, 'ticket article inbound body' ) + assert_equal( 2, article.ticket.articles.count, 'ticket article inbound count' ) + assert_equal( post_comment, article.ticket.articles.last.body, 'ticket article inbound body' ) + end + + test 'feed post and comment reply' do + + consumer_client = Koala::Facebook::API.new( consumer_key ) + feed_post = "I've got an issue with my hat, serial number ##{rand(9999)}" + + facebook = Facebook.new( provider_options ) + + post = consumer_client.put_wall_post(feed_post, {}, facebook.account['id']) + + # fetch check system account + Channel.fetch + + # check if first article has been created + article = Ticket::Article.find_by( message_id: post['id'] ) + + reply_text = "What's your issue Bernd?" + + # reply via ticket + outbound_article = Ticket::Article.create( + ticket_id: article.ticket.id, + body: reply_text, + in_reply_to: post['id'], + type: Ticket::Article::Type.find_by( name: 'facebook feed comment' ), + sender: Ticket::Article::Sender.find_by( name: 'Agent' ), + internal: false, + updated_by_id: 1, + created_by_id: 1, + ) + assert( outbound_article, 'outbound article created' ) + assert_equal( outbound_article.ticket.articles.count, 2, 'ticket article outbound count' ) + + post_comment = 'The peacock feather is fallen off.' + comment = consumer_client.put_comment(post['id'], post_comment) + + # fetch check system account + Channel.fetch + + reply_text = "Please send it to our address and add the ticket number #{article.ticket.number}." + + # reply via ticket + outbound_article = Ticket::Article.create( + ticket_id: article.ticket.id, + body: reply_text, + in_reply_to: comment['id'], + type: Ticket::Article::Type.find_by( name: 'facebook feed comment' ), + sender: Ticket::Article::Sender.find_by( name: 'Agent' ), + internal: false, + updated_by_id: 1, + created_by_id: 1, + ) + + assert( outbound_article, 'outbound article created' ) + assert_equal( outbound_article.ticket.articles.count, 4, 'ticket article outbound count' ) + end +end