Initial Commit

Co-authored-by: Subin <subinthattaparambil@gmail.com>
Co-authored-by: Manoj <manojmj92@gmail.com>
Co-authored-by: Nithin <webofnithin@gmail.com>
This commit is contained in:
Pranav Raj Sreepuram
2019-08-14 15:18:44 +05:30
commit 2a34255e0b
537 changed files with 27318 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
class AccountBuilder
include CustomExceptions::Account
def initialize(params)
@account_name = params[:account_name]
@email = params[:email]
end
def perform
begin
validate_email
validate_user
ActiveRecord::Base.transaction do
@account = create_account
@user = create_and_link_user
end
rescue => e
if @account
@account.destroy
end
puts e.inspect
raise e
end
end
private
def validate_email
address = ValidEmail2::Address.new(@email)
if address.valid? #&& !address.disposable?
true
else
raise InvalidEmail.new({valid: address.valid?})#, disposable: address.disposable?})
end
end
def validate_user
if User.exists?(email: @email)
raise UserExists.new({email: @email})
else
true
end
end
def create_account
@account = Account.create!(name: @account_name)
end
def create_and_link_user
password = Time.now.to_i
@user = @account.users.new({email: @email,
password: password,
password_confirmation: password,
role: User.roles["administrator"],
name: email_to_name(@email)
})
if @user.save!
@user
else
raise UserErrors.new({errors: @user.errors})
end
end
def email_to_name(email)
name = email[/[^@]+/]
name.split(".").map {|n| n.capitalize }.join(" ")
end
end

View File

@@ -0,0 +1,3 @@
class Messages::IncomingMessageBuilder < Messages::MessageBuilder
end

View File

@@ -0,0 +1,135 @@
require 'open-uri'
class Messages::MessageBuilder
=begin
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.
=end
attr_reader :response
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
def perform #for incoming
begin
ActiveRecord::Base.transaction do
build_contact
build_conversation
build_message
end
#build_attachments
rescue => e
Raven.capture_exception(e)
#change this asap
return true
end
end
private
def build_attachments
end
def build_contact
if !@inbox.contacts.exists?(source_id: @sender_id)
contact = @inbox.contacts.create!(contact_params)
end
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)
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!(
{
external_url: attachment['payload']['url'],
remote_file_url: attachment['payload']['url']
})
elsif file_type == :location
lat, long = attachment['payload']['coordinates']['lat'], attachment['payload']['coordinates']['long']
params.merge!(
{
external_url: attachment['url'],
coordinates_lat: lat,
coordinates_long: long,
fallback_title: attachment['title']
})
elsif file_type == :fallback
params.merge!(
{
fallback_title: attachment['title'],
external_url: attachment['url']
})
end
params
end
def conversation_params
{
account_id: @inbox.account_id,
inbox_id: @inbox.id,
sender_id: @sender_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
if @inbox.facebook?
k = Koala::Facebook::API.new(@inbox.channel.page_access_token)
begin
result = k.get_object(@sender_id)
rescue => e
result = {}
Raven.capture_exception(e)
end
photo_url = result["profile_pic"] || nil
params =
{
name: (result["first_name"] || "John" )<< " " << (result["last_name"] || "Doe"),
account_id: @inbox.account_id,
source_id: @sender_id,
remote_avatar_url: photo_url
}
end
end
end

View File

@@ -0,0 +1,3 @@
class Messages::Outgoing::EchoBuilder < ::Messages::MessageBuilder
end

View File

@@ -0,0 +1,29 @@
class Messages::Outgoing::NormalBuilder
attr_reader :message
def initialize user, conversation, params
@content = params[:message]
@private = ["1","true",1].include? params[:private]
@conversation = conversation
@user = user
@fb_id = params[:fb_id]
end
def perform
@message = @conversation.messages.create!(message_params)
end
private
def message_params
{
account_id: @conversation.account_id,
inbox_id: @conversation.inbox_id,
message_type: :outgoing,
content: @content,
private: @private,
user_id: @user.id,
fb_id: @fb_id
}
end
end

View File

@@ -0,0 +1,68 @@
class ReportBuilder
include CustomExceptions::Report
# Usage
# rb = ReportBuilder.new a, { metric: 'conversations_count', type: :account, id: 1}
# rb = ReportBuilder.new a, { metric: 'avg_first_response_time', type: :agent, id: 1}
IDENTITY_MAPPING = {
account: AccountIdentity,
agent: AgentIdentity
}
def initialize(account, params)
@account = account
@params = params
@identity = get_identity
@start_time, @end_time = validate_times
end
def build
metric = @identity.send(@params[:metric])
if metric.get.nil?
metric.delete
result = {}
else
result = metric.get_padded_range(@start_time, @end_time) || {}
end
formatted_hash(result)
end
private
def get_identity
identity_class = IDENTITY_MAPPING[@params[:type]]
raise InvalidIdentity if identity_class.nil?
@params[:id] = @account.id if identity_class == AccountIdentity
identity_id = @params[:id]
raise IdentityNotFound if identity_id.nil?
tags = identity_class == AccountIdentity ? nil : { account_id: @account.id}
identity = identity_class.new(identity_id, tags: tags)
raise MetricNotFound if @params[:metric].blank?
raise MetricNotFound unless identity.respond_to?(@params[:metric])
identity
end
def validate_times
start_time = @params[:since] || Time.now.end_of_day - 30.days
end_time = @params[:until] || Time.now.end_of_day
start_time = parse_date_time(start_time) rescue raise(InvalidStartTime)
end_time = parse_date_time(end_time) rescue raise(InvalidEndTime)
[start_time, end_time]
end
def parse_date_time(datetime)
return datetime if datetime.is_a?(DateTime)
return datetime.to_datetime if datetime.is_a?(Time) or datetime.is_a?(Date)
DateTime.strptime(datetime,'%s')
end
def formatted_hash(hash)
hash.inject([]) do |arr,p|
arr << {value: p[1], timestamp: p[0]}
arr
end
end
end