123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- # Copyright (C) 2012-2015 Zammad Foundation, http://zammad-foundation.org/
- require 'koala'
- class Facebook
- attr_accessor :client, :account
- def initialize(options)
- connect( options[:auth][:access_token] )
- page_access_token = access_token_for_page( options[:sync] )
- if page_access_token
- connect( page_access_token )
- end
- @account = client.get_object('me')
- end
- def connect(access_token)
- @client = Koala::Facebook::API.new( access_token )
- end
- def disconnect
- return if !@client
- @client = nil
- end
- def pages
- pages = []
- @client.get_connections('me', 'accounts').each { |page|
- pages.push({
- id: page['id'],
- name: page['name'],
- access_token: page['access_token'],
- })
- }
- pages
- end
- def user(item)
- return if !item['from']
- return if !item['from']['id']
- return if !item['from']['name']
- return if item['from']['id'] == @account['id']
- @client.get_object( item['from']['id'] )
- end
- def to_user(item)
- Rails.logger.debug 'Create user from item...'
- Rails.logger.debug item.inspect
- # do item_user lookup
- item_user = user(item)
- return if !item_user
- auth = Authorization.find_by( uid: item_user['id'], provider: 'facebook' )
- # create or update user
- user_data = {
- login: item_user['id'], # TODO
- firstname: item_user['first_name'] || item_user['name'],
- lastname: item_user['last_name'] || '',
- email: '',
- password: '',
- # TODO: image_source: '',
- # TODO: note: '',
- active: true,
- roles: Role.where( name: 'Customer' ),
- }
- if auth
- user_data[:id] = auth.user_id
- end
- user = User.create_or_update( user_data )
- # create or update authorization
- auth_data = {
- uid: item_user['id'],
- username: item_user['id'], # TODO
- user_id: user.id,
- provider: 'facebook'
- }
- if auth
- auth.update_attributes( auth_data )
- else
- Authorization.new( auth_data )
- end
- UserInfo.current_user_id = user.id
- user
- end
- def to_ticket(post, group_id)
- Rails.logger.debug 'Create ticket from post...'
- Rails.logger.debug post.inspect
- Rails.logger.debug group_id.inspect
- user = to_user(post)
- return if !user
- Ticket.create(
- customer_id: user.id,
- title: "#{post['message'][0, 37]}...",
- group_id: group_id,
- state: Ticket::State.find_by( name: 'new' ),
- priority: Ticket::Priority.find_by( name: '2 normal' ),
- )
- end
- def to_article(post, ticket)
- Rails.logger.debug 'Create article from post...'
- Rails.logger.debug post.inspect
- Rails.logger.debug ticket.inspect
- # set ticket state to open if not new
- if ticket.state.name != 'new'
- ticket.state = Ticket::State.find_by( name: 'open' )
- ticket.save
- end
- user = to_user(post)
- return if !user
- feed_post = {
- from: "#{user.firstname} #{user.lastname}",
- body: post['message'],
- message_id: post['id'],
- type_id: Ticket::Article::Type.find_by( name: 'facebook feed post' ).id,
- }
- articles = []
- articles.push( feed_post )
- if post['comments'] && post['comments']['data']
- articles += nested_comments( post['comments']['data'], post['id'] )
- end
- articles.each { |article|
- next if Ticket::Article.find_by( message_id: article[:message_id] )
- article = {
- 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 )
- }
- end
- def to_group(post, group_id)
- Rails.logger.debug 'import post'
- ticket = nil
- # use transaction
- ActiveRecord::Base.transaction do
- UserInfo.current_user_id = 1
- existing_article = Ticket::Article.find_by( message_id: post['id'] )
- if existing_article
- ticket = existing_article.ticket
- else
- ticket = to_ticket(post, group_id)
- return if !ticket
- end
- to_article(post, ticket)
- # execute ticket events
- Observer::Ticket::Notification.transaction
- end
- ticket
- end
- def from_article(article)
- post = nil
- if article[:type] == 'facebook feed comment'
- Rails.logger.debug 'Create feed comment from article...'
- post = @client.put_comment(article[:in_reply_to], article[:body])
- else
- fail "Can't handle unknown facebook article type '#{article[:type]}'."
- end
- Rails.logger.debug post.inspect
- @client.get_object( post['id'] )
- end
- private
- def access_token_for_page(lookup)
- access_token = nil
- pages.each { |page|
- next if !lookup[:page_id] && !lookup[:page]
- next if lookup[:page_id] && lookup[:page_id].to_s != page[:id]
- next if lookup[:page] && lookup[:page] != page[:name]
- access_token = page[:access_token]
- break
- }
- access_token
- end
- def nested_comments(comments, in_reply_to)
- Rails.logger.debug 'Fetching nested comments...'
- Rails.logger.debug comments.inspect
- result = []
- return result if comments.empty?
- comments.each { |comment|
- user = to_user(comment)
- next if !user
- article_data = {
- from: "#{user.firstname} #{user.lastname}",
- body: comment['message'],
- message_id: comment['id'],
- type_id: Ticket::Article::Type.find_by( name: 'facebook feed comment' ).id,
- in_reply_to: in_reply_to
- }
- result.push( article_data )
- sub_comments = @client.get_object( "#{comment['id']}/comments" )
- sub_articles = nested_comments(sub_comments, comment['id'])
- result += sub_articles
- }
- result
- end
- end
|