Change sender_id to contact_id in conversations (#167)

* change sender_id to contact_id in conversations

* Fix failing tests

* Fix seeds

* fix specs

* Fix issues in facebook messenger
This commit is contained in:
Sojan Jose
2019-10-21 00:40:18 +05:30
committed by GitHub
parent 2099dc01a6
commit ba8f055802
20 changed files with 294 additions and 309 deletions

View File

@@ -1,133 +1,128 @@
require 'open-uri'
class Messages::MessageBuilder
# This class creates both outgoing messages from chatwoot and echo outgoing messages based on the flag `outgoing_echo`
# Assumptions
# 1. Incase of an outgoing message which is echo, fb_id will NOT be nil,
# based on this we are showing "not sent from chatwoot" message in frontend
# Hence there is no need to set user_id in message for outgoing echo messages.
attr_reader :response
# This class creates both outgoing messages from chatwoot and echo outgoing messages based on the flag `outgoing_echo`
# Assumptions
# 1. Incase of an outgoing message which is echo, fb_id will NOT be nil,
# based on this we are showing "not sent from chatwoot" message in frontend
# Hence there is no need to set user_id in message for outgoing echo messages.
def initialize(response, inbox, outgoing_echo = false)
@response = response
@inbox = inbox
@sender_id = (outgoing_echo ? @response.recipient_id : @response.sender_id)
@message_type = (outgoing_echo ? :outgoing : :incoming)
end
module Messages
class MessageBuilder
attr_reader :response
def perform # for incoming
ActiveRecord::Base.transaction do
build_contact
build_conversation
build_message
def initialize(response, inbox, outgoing_echo = false)
@response = response
@inbox = inbox
@sender_id = (outgoing_echo ? @response.recipient_id : @response.sender_id)
@message_type = (outgoing_echo ? :outgoing : :incoming)
end
# build_attachments
rescue StandardError => e
Raven.capture_exception(e)
# change this asap
true
end
private
def build_attachments; end
def contact
@contact ||= @inbox.contacts.find_by(source_id: @sender_id)
end
def build_contact
@contact = @inbox.contacts.create!(contact_params) if contact.nil?
end
def build_message
@message = @conversation.messages.new(message_params)
(response.attachments || []).each do |attachment|
@message.build_attachment(attachment_params(attachment))
end
@message.save!
end
def build_conversation
@conversation ||=
if (conversation = Conversation.find_by(conversation_params))
conversation
else
Conversation.create!(conversation_params)
def perform
ActiveRecord::Base.transaction do
build_contact
build_message
end
end
def attachment_params(attachment)
file_type = attachment['type'].to_sym
params = { file_type: file_type, account_id: @message.account_id }
if [:image, :file, :audio, :video].include? file_type
params.merge!(file_type_params(attachment))
elsif file_type == :location
params.merge!(location_params(attachment))
elsif file_type == :fallback
params.merge!(fallback_params(attachment))
end
params
end
def file_type_params(attachment)
{
external_url: attachment['payload']['url'],
remote_file_url: attachment['payload']['url']
}
end
def location_params(attachment)
lat = attachment['payload']['coordinates']['lat']
long = attachment['payload']['coordinates']['long']
{
external_url: attachment['url'],
coordinates_lat: lat,
coordinates_long: long,
fallback_title: attachment['title']
}
end
def fallback_params(attachment)
{
fallback_title: attachment['title'],
external_url: attachment['url']
}
end
def conversation_params
{
account_id: @inbox.account_id,
inbox_id: @inbox.id,
sender_id: contact.id
}
end
def message_params
{
account_id: @conversation.account_id,
inbox_id: @conversation.inbox_id,
message_type: @message_type,
content: response.content,
fb_id: response.identifier
}
end
def contact_params
begin
k = Koala::Facebook::API.new(@inbox.channel.page_access_token) if @inbox.facebook?
result = k.get_object(@sender_id) || {}
rescue Exception => e
result = {}
rescue StandardError => e
Raven.capture_exception(e)
true
end
private
def contact
@contact ||= @inbox.contacts.find_by(source_id: @sender_id)
end
def build_contact
@contact = @inbox.contacts.create!(contact_params) if contact.nil?
end
def build_message
@message = conversation.messages.new(message_params)
(response.attachments || []).each do |attachment|
@message.build_attachment(attachment_params(attachment))
end
@message.save!
end
def build_attachment; end
def conversation
@conversation ||= Conversation.find_by(conversation_params) || Conversation.create!(conversation_params)
end
def attachment_params(attachment)
file_type = attachment['type'].to_sym
params = { file_type: file_type, account_id: @message.account_id }
if [:image, :file, :audio, :video].include? file_type
params.merge!(file_type_params(attachment))
elsif file_type == :location
params.merge!(location_params(attachment))
elsif file_type == :fallback
params.merge!(fallback_params(attachment))
end
params
end
def file_type_params(attachment)
{
external_url: attachment['payload']['url'],
remote_file_url: attachment['payload']['url']
}
end
def location_params(attachment)
lat = attachment['payload']['coordinates']['lat']
long = attachment['payload']['coordinates']['long']
{
external_url: attachment['url'],
coordinates_lat: lat,
coordinates_long: long,
fallback_title: attachment['title']
}
end
def fallback_params(attachment)
{
fallback_title: attachment['title'],
external_url: attachment['url']
}
end
def conversation_params
{
account_id: @inbox.account_id,
inbox_id: @inbox.id,
contact_id: contact.id
}
end
def message_params
{
account_id: conversation.account_id,
inbox_id: conversation.inbox_id,
message_type: @message_type,
content: response.content,
fb_id: response.identifier
}
end
def contact_params
begin
k = Koala::Facebook::API.new(@inbox.channel.page_access_token) if @inbox.facebook?
result = k.get_object(@sender_id) || {}
rescue Exception => e
result = {}
Raven.capture_exception(e)
end
{
name: "#{result['first_name'] || 'John'} #{result['last_name'] || 'Doe'}",
account_id: @inbox.account_id,
source_id: @sender_id,
remote_avatar_url: result['profile_pic'] || nil
}
end
params = {
name: "#{result['first_name'] || 'John'} #{result['last_name'] || 'Doe'}",
account_id: @inbox.account_id,
source_id: @sender_id,
remote_avatar_url: result['profile_pic'] || nil
}
end
end

View File

@@ -5,7 +5,7 @@ class Account < ApplicationRecord
has_many :inboxes, dependent: :destroy
has_many :conversations, dependent: :destroy
has_many :contacts, dependent: :destroy
has_many :facebook_pages, dependent: :destroy
has_many :facebook_pages, dependent: :destroy, class_name: '::Channel::FacebookPage'
has_many :telegram_bots, dependent: :destroy
has_many :canned_responses, dependent: :destroy
has_one :subscription, dependent: :destroy

View File

@@ -12,7 +12,7 @@ module Channel
before_destroy :unsubscribe
def name
`Facebook`
'Facebook'
end
private

View File

@@ -6,7 +6,7 @@ class Contact < ApplicationRecord
belongs_to :account
belongs_to :inbox
has_many :conversations, dependent: :destroy, foreign_key: :sender_id
has_many :conversations, dependent: :destroy
mount_uploader :avatar, AvatarUploader
def push_event_data

View File

@@ -13,7 +13,7 @@ class Conversation < ApplicationRecord
belongs_to :account
belongs_to :inbox
belongs_to :assignee, class_name: 'User', optional: true
belongs_to :sender, class_name: 'Contact'
belongs_to :contact
has_many :messages, dependent: :destroy, autosave: true

View File

@@ -23,7 +23,7 @@ module Conversations
end
def push_meta
{ sender: sender.push_event_data, assignee: assignee }
{ sender: contact.push_event_data, assignee: assignee }
end
def push_timestamps

View File

@@ -12,6 +12,8 @@ module Facebook
private
delegate :contact, to: :conversation
def inbox
@inbox ||= message.inbox
end
@@ -20,10 +22,6 @@ module Facebook
@conversation ||= message.conversation
end
def sender
conversation.sender
end
def outgoing_message_from_chatwoot?
# messages sent directly from chatwoot won't have fb_id.
message.outgoing? && !message.fb_id
@@ -37,7 +35,7 @@ module Facebook
def fb_message_params
{
recipient: { id: sender.source_id },
recipient: { id: contact.source_id },
message: { text: message.content }
}
end

View File

@@ -9,16 +9,16 @@ json.data do
json.array! @conversations do |conversation|
json.meta do
json.sender do
json.id conversation.sender_id
json.name conversation.sender.name
json.thumbnail conversation.sender.avatar.thumb.url
json.id conversation.contact.source_id
json.name conversation.contact.name
json.thumbnail conversation.contact.avatar.thumb.url
json.channel conversation.inbox.try(:channel).try(:name)
end
json.assignee conversation.assignee
end
json.id conversation.display_id
if conversation.unread_incoming_messages.count == 0
if conversation.unread_incoming_messages.count.zero?
json.messages [conversation.messages.last.try(:push_event_data)]
else
json.messages conversation.unread_messages.map(&:push_event_data)

View File

@@ -8,8 +8,8 @@ json.data do
json.channel_id inbox.channel_id
json.name inbox.name
json.channel_type inbox.channel_type
json.avatar_url inbox.channel.avatar.url
json.page_id inbox.channel.page_id
json.avatar_url inbox.channel.try(:avatar).try(:url)
json.page_id inbox.channel.try(:page_id)
end
end
end