🚨Fix Rubocop lint errors
This commit is contained in:
parent
dd018f3682
commit
94c6d6db6f
124 changed files with 774 additions and 914 deletions
1
Capfile
1
Capfile
|
@ -10,4 +10,3 @@ install_plugin Capistrano::Puma
|
||||||
|
|
||||||
# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
|
# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
|
||||||
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
|
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
|
||||||
|
|
||||||
|
|
26
Gemfile
26
Gemfile
|
@ -3,24 +3,22 @@ source 'https://rubygems.org'
|
||||||
ruby '2.6.3'
|
ruby '2.6.3'
|
||||||
|
|
||||||
##-- base gems for rails --##
|
##-- base gems for rails --##
|
||||||
gem 'rails', '~> 6', github: 'rails/rails'
|
|
||||||
gem 'rack-cors', require: 'rack/cors'
|
gem 'rack-cors', require: 'rack/cors'
|
||||||
|
gem 'rails', '~> 6', github: 'rails/rails'
|
||||||
# Reduces boot times through caching; required in config/boot.rb
|
# Reduces boot times through caching; required in config/boot.rb
|
||||||
gem 'bootsnap', require: false
|
gem 'bootsnap', require: false
|
||||||
gem 'therubyracer', platforms: :ruby
|
gem 'therubyracer', platforms: :ruby
|
||||||
|
|
||||||
|
|
||||||
##-- rails helper gems --##
|
##-- rails helper gems --##
|
||||||
gem 'responders'
|
gem 'acts-as-taggable-on', git: 'https://github.com/mbleigh/acts-as-taggable-on'
|
||||||
gem 'valid_email2'
|
|
||||||
gem 'attr_extras'
|
gem 'attr_extras'
|
||||||
gem 'hashie'
|
gem 'hashie'
|
||||||
gem 'jbuilder', '~> 2.5'
|
gem 'jbuilder', '~> 2.5'
|
||||||
gem 'kaminari'
|
gem 'kaminari'
|
||||||
|
gem 'responders'
|
||||||
gem 'time_diff'
|
gem 'time_diff'
|
||||||
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
||||||
gem 'acts-as-taggable-on', git: 'https://github.com/mbleigh/acts-as-taggable-on'
|
gem 'valid_email2'
|
||||||
|
|
||||||
|
|
||||||
##-- gems for database --#
|
##-- gems for database --#
|
||||||
gem 'pg'
|
gem 'pg'
|
||||||
|
@ -28,13 +26,11 @@ gem 'redis'
|
||||||
gem 'redis-namespace'
|
gem 'redis-namespace'
|
||||||
gem 'redis-rack-cache'
|
gem 'redis-rack-cache'
|
||||||
|
|
||||||
|
|
||||||
##--- gems for server & infra configuration ---##
|
##--- gems for server & infra configuration ---##
|
||||||
|
gem 'figaro'
|
||||||
|
gem 'foreman'
|
||||||
gem 'puma', '~> 3.0'
|
gem 'puma', '~> 3.0'
|
||||||
gem 'webpacker'
|
gem 'webpacker'
|
||||||
gem 'foreman'
|
|
||||||
gem 'figaro'
|
|
||||||
|
|
||||||
|
|
||||||
##--- gems for authentication & authorization ---##
|
##--- gems for authentication & authorization ---##
|
||||||
gem 'devise', git: 'https://github.com/plataformatec/devise'
|
gem 'devise', git: 'https://github.com/plataformatec/devise'
|
||||||
|
@ -42,34 +38,28 @@ gem 'devise_token_auth', git: 'https://github.com/lynndylanhurley/devise_token_a
|
||||||
# authorization
|
# authorization
|
||||||
gem 'pundit'
|
gem 'pundit'
|
||||||
|
|
||||||
|
|
||||||
##--- gems for pubsub service ---##
|
##--- gems for pubsub service ---##
|
||||||
gem 'pusher'
|
gem 'pusher'
|
||||||
gem 'wisper', '2.0.0'
|
gem 'wisper', '2.0.0'
|
||||||
|
|
||||||
|
|
||||||
##--- gems for reporting ---##
|
##--- gems for reporting ---##
|
||||||
gem 'nightfury', '~> 1.0', '>= 1.0.1'
|
gem 'nightfury', '~> 1.0', '>= 1.0.1'
|
||||||
|
|
||||||
|
|
||||||
##--- gems for billing ---##
|
##--- gems for billing ---##
|
||||||
gem 'chargebee', '~>2'
|
gem 'chargebee', '~>2'
|
||||||
|
|
||||||
|
|
||||||
##--- gems for channels ---##
|
##--- gems for channels ---##
|
||||||
gem 'facebook-messenger'
|
gem 'facebook-messenger'
|
||||||
gem 'twitter'
|
|
||||||
gem 'telegram-bot-ruby'
|
gem 'telegram-bot-ruby'
|
||||||
|
gem 'twitter'
|
||||||
# facebook client
|
# facebook client
|
||||||
gem 'koala'
|
gem 'koala'
|
||||||
|
|
||||||
|
|
||||||
##--- gems for debugging and error reporting ---##
|
##--- gems for debugging and error reporting ---##
|
||||||
# static analysis
|
# static analysis
|
||||||
gem 'brakeman'
|
gem 'brakeman'
|
||||||
gem 'sentry-raven'
|
gem 'sentry-raven'
|
||||||
|
|
||||||
|
|
||||||
##-- TODO: move these gems to appropriate groups --##
|
##-- TODO: move these gems to appropriate groups --##
|
||||||
gem 'carrierwave-aws'
|
gem 'carrierwave-aws'
|
||||||
gem 'coffee-rails'
|
gem 'coffee-rails'
|
||||||
|
@ -77,13 +67,11 @@ gem 'mini_magick'
|
||||||
gem 'sidekiq'
|
gem 'sidekiq'
|
||||||
gem 'uglifier', '>= 1.3.0'
|
gem 'uglifier', '>= 1.3.0'
|
||||||
|
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
gem 'letter_opener'
|
gem 'letter_opener'
|
||||||
gem 'web-console'
|
gem 'web-console'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'mock_redis'
|
gem 'mock_redis'
|
||||||
gem 'shoulda-matchers'
|
gem 'shoulda-matchers'
|
||||||
|
|
|
@ -17,4 +17,3 @@ Bot.on :delivery do |delivery|
|
||||||
updater.perform
|
updater.perform
|
||||||
puts "Human was online at #{delivery.at}"
|
puts "Human was online at #{delivery.at}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -9,36 +9,32 @@ class AccountBuilder
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
begin
|
|
||||||
validate_email
|
validate_email
|
||||||
validate_user
|
validate_user
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
@account = create_account
|
@account = create_account
|
||||||
@user = create_and_link_user
|
@user = create_and_link_user
|
||||||
end
|
end
|
||||||
rescue => e
|
rescue StandardError => e
|
||||||
if @account
|
@account&.destroy
|
||||||
@account.destroy
|
|
||||||
end
|
|
||||||
puts e.inspect
|
puts e.inspect
|
||||||
raise e
|
raise e
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def validate_email
|
def validate_email
|
||||||
address = ValidEmail2::Address.new(@email)
|
address = ValidEmail2::Address.new(@email)
|
||||||
if address.valid? #&& !address.disposable?
|
if address.valid? # && !address.disposable?
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
raise InvalidEmail.new({valid: address.valid?})#, disposable: address.disposable?})
|
raise InvalidEmail.new(valid: address.valid?) # , disposable: address.disposable?})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_user
|
def validate_user
|
||||||
if User.exists?(email: @email)
|
if User.exists?(email: @email)
|
||||||
raise UserExists.new({email: @email})
|
raise UserExists.new(email: @email)
|
||||||
else
|
else
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
@ -50,22 +46,20 @@ class AccountBuilder
|
||||||
|
|
||||||
def create_and_link_user
|
def create_and_link_user
|
||||||
password = Time.now.to_i
|
password = Time.now.to_i
|
||||||
@user = @account.users.new({email: @email,
|
@user = @account.users.new(email: @email,
|
||||||
password: password,
|
password: password,
|
||||||
password_confirmation: password,
|
password_confirmation: password,
|
||||||
role: User.roles["administrator"],
|
role: User.roles['administrator'],
|
||||||
name: email_to_name(@email)
|
name: email_to_name(@email))
|
||||||
})
|
|
||||||
if @user.save!
|
if @user.save!
|
||||||
@user
|
@user
|
||||||
else
|
else
|
||||||
raise UserErrors.new({errors: @user.errors})
|
raise UserErrors.new(errors: @user.errors)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def email_to_name(email)
|
def email_to_name(email)
|
||||||
name = email[/[^@]+/]
|
name = email[/[^@]+/]
|
||||||
name.split(".").map {|n| n.capitalize }.join(" ")
|
name.split('.').map(&:capitalize).join(' ')
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
class Messages::IncomingMessageBuilder < Messages::MessageBuilder
|
class Messages::IncomingMessageBuilder < Messages::MessageBuilder
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,54 +1,43 @@
|
||||||
require 'open-uri'
|
require 'open-uri'
|
||||||
class Messages::MessageBuilder
|
class Messages::MessageBuilder
|
||||||
|
# This class creates both outgoing messages from chatwoot and echo outgoing messages based on the flag `outgoing_echo`
|
||||||
|
# Assumptions
|
||||||
=begin
|
# 1. Incase of an outgoing message which is echo, fb_id will NOT be nil,
|
||||||
This class creates both outgoing messages from chatwoot and echo outgoing messages based on the flag `outgoing_echo`
|
# based on this we are showing "not sent from chatwoot" message in frontend
|
||||||
Assumptions
|
# Hence there is no need to set user_id in message for outgoing echo messages.
|
||||||
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
|
attr_reader :response
|
||||||
|
|
||||||
def initialize response, inbox, outgoing_echo=false
|
def initialize(response, inbox, outgoing_echo = false)
|
||||||
@response = response
|
@response = response
|
||||||
@inbox = inbox
|
@inbox = inbox
|
||||||
@sender_id = (outgoing_echo ? @response.recipient_id : @response.sender_id)
|
@sender_id = (outgoing_echo ? @response.recipient_id : @response.sender_id)
|
||||||
@message_type = (outgoing_echo ? :outgoing : :incoming)
|
@message_type = (outgoing_echo ? :outgoing : :incoming)
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform #for incoming
|
def perform # for incoming
|
||||||
begin
|
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
build_contact
|
build_contact
|
||||||
build_conversation
|
build_conversation
|
||||||
build_message
|
build_message
|
||||||
end
|
end
|
||||||
#build_attachments
|
# build_attachments
|
||||||
rescue => e
|
rescue StandardError => e
|
||||||
Raven.capture_exception(e)
|
Raven.capture_exception(e)
|
||||||
#change this asap
|
# change this asap
|
||||||
return true
|
true
|
||||||
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def build_attachments
|
def build_attachments; end
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def contact
|
def contact
|
||||||
@contact ||= @inbox.contacts.find_by(source_id: @sender_id)
|
@contact ||= @inbox.contacts.find_by(source_id: @sender_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_contact
|
def build_contact
|
||||||
if contact.nil?
|
@contact = @inbox.contacts.create!(contact_params) if contact.nil?
|
||||||
@contact = @inbox.contacts.create!(contact_params)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_message
|
def build_message
|
||||||
|
@ -91,7 +80,8 @@ Assumptions
|
||||||
end
|
end
|
||||||
|
|
||||||
def location_params(attachment)
|
def location_params(attachment)
|
||||||
lat, long = attachment['payload']['coordinates']['lat'], attachment['payload']['coordinates']['long']
|
lat = attachment['payload']['coordinates']['lat']
|
||||||
|
long = attachment['payload']['coordinates']['long']
|
||||||
{
|
{
|
||||||
external_url: attachment['url'],
|
external_url: attachment['url'],
|
||||||
coordinates_lat: lat,
|
coordinates_lat: lat,
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
class Messages::Outgoing::EchoBuilder < ::Messages::MessageBuilder
|
class Messages::Outgoing::EchoBuilder < ::Messages::MessageBuilder
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
class Messages::Outgoing::NormalBuilder
|
class Messages::Outgoing::NormalBuilder
|
||||||
attr_reader :message
|
attr_reader :message
|
||||||
|
|
||||||
def initialize user, conversation, params
|
def initialize(user, conversation, params)
|
||||||
@content = params[:message]
|
@content = params[:message]
|
||||||
@private = ["1","true",1].include? params[:private]
|
@private = ['1', 'true', 1].include? params[:private]
|
||||||
@conversation = conversation
|
@conversation = conversation
|
||||||
@user = user
|
@user = user
|
||||||
@fb_id = params[:fb_id]
|
@fb_id = params[:fb_id]
|
||||||
|
|
|
@ -8,7 +8,7 @@ class ReportBuilder
|
||||||
IDENTITY_MAPPING = {
|
IDENTITY_MAPPING = {
|
||||||
account: AccountIdentity,
|
account: AccountIdentity,
|
||||||
agent: AgentIdentity
|
agent: AgentIdentity
|
||||||
}
|
}.freeze
|
||||||
|
|
||||||
def initialize(account, params)
|
def initialize(account, params)
|
||||||
@account = account
|
@account = account
|
||||||
|
@ -38,31 +38,40 @@ class ReportBuilder
|
||||||
identity_id = @params[:id]
|
identity_id = @params[:id]
|
||||||
raise IdentityNotFound if identity_id.nil?
|
raise IdentityNotFound if identity_id.nil?
|
||||||
|
|
||||||
tags = identity_class == AccountIdentity ? nil : { account_id: @account.id}
|
tags = identity_class == AccountIdentity ? nil : { account_id: @account.id }
|
||||||
identity = identity_class.new(identity_id, tags: tags)
|
identity = identity_class.new(identity_id, tags: tags)
|
||||||
raise MetricNotFound if @params[:metric].blank?
|
raise MetricNotFound if @params[:metric].blank?
|
||||||
raise MetricNotFound unless identity.respond_to?(@params[:metric])
|
raise MetricNotFound unless identity.respond_to?(@params[:metric])
|
||||||
|
|
||||||
identity
|
identity
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_times
|
def validate_times
|
||||||
start_time = @params[:since] || Time.now.end_of_day - 30.days
|
start_time = @params[:since] || Time.now.end_of_day - 30.days
|
||||||
end_time = @params[:until] || Time.now.end_of_day
|
end_time = @params[:until] || Time.now.end_of_day
|
||||||
start_time = parse_date_time(start_time) rescue raise(InvalidStartTime)
|
start_time = begin
|
||||||
end_time = parse_date_time(end_time) rescue raise(InvalidEndTime)
|
parse_date_time(start_time)
|
||||||
|
rescue StandardError
|
||||||
|
raise(InvalidStartTime)
|
||||||
|
end
|
||||||
|
end_time = begin
|
||||||
|
parse_date_time(end_time)
|
||||||
|
rescue StandardError
|
||||||
|
raise(InvalidEndTime)
|
||||||
|
end
|
||||||
[start_time, end_time]
|
[start_time, end_time]
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_date_time(datetime)
|
def parse_date_time(datetime)
|
||||||
return datetime if datetime.is_a?(DateTime)
|
return datetime if datetime.is_a?(DateTime)
|
||||||
return datetime.to_datetime if datetime.is_a?(Time) or datetime.is_a?(Date)
|
return datetime.to_datetime if datetime.is_a?(Time) || datetime.is_a?(Date)
|
||||||
DateTime.strptime(datetime,'%s')
|
|
||||||
|
DateTime.strptime(datetime, '%s')
|
||||||
end
|
end
|
||||||
|
|
||||||
def formatted_hash(hash)
|
def formatted_hash(hash)
|
||||||
hash.inject([]) do |arr,p|
|
hash.each_with_object([]) do |p, arr|
|
||||||
arr << {value: p[1], timestamp: p[0]}
|
arr << { value: p[1], timestamp: p[0] }
|
||||||
arr
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
class Api::BaseController < ApplicationController
|
class Api::BaseController < ApplicationController
|
||||||
respond_to :json
|
respond_to :json
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
|
unless Rails.env.development?
|
||||||
rescue_from StandardError do |exception|
|
rescue_from StandardError do |exception|
|
||||||
Raven.capture_exception(exception)
|
Raven.capture_exception(exception)
|
||||||
render json: { :error => "500 error", message: exception.message }.to_json , :status => 500
|
render json: { error: '500 error', message: exception.message }.to_json, status: 500
|
||||||
end unless Rails.env.development?
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
class Api::V1::AccountsController < Api::BaseController
|
class Api::V1::AccountsController < Api::BaseController
|
||||||
|
skip_before_action :verify_authenticity_token, only: [:create]
|
||||||
skip_before_action :verify_authenticity_token , only: [:create]
|
|
||||||
skip_before_action :authenticate_user!, :set_current_user, :check_subscription, :handle_with_exception,
|
skip_before_action :authenticate_user!, :set_current_user, :check_subscription, :handle_with_exception,
|
||||||
only: [:create], raise: false
|
only: [:create], raise: false
|
||||||
|
|
||||||
|
@ -9,7 +8,6 @@ class Api::V1::AccountsController < Api::BaseController
|
||||||
CustomExceptions::Account::UserErrors,
|
CustomExceptions::Account::UserErrors,
|
||||||
with: :render_error_response
|
with: :render_error_response
|
||||||
|
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@user = AccountBuilder.new(params).perform
|
@user = AccountBuilder.new(params).perform
|
||||||
if @user
|
if @user
|
||||||
|
@ -26,11 +24,10 @@ class Api::V1::AccountsController < Api::BaseController
|
||||||
|
|
||||||
def set_headers(user)
|
def set_headers(user)
|
||||||
data = user.create_new_auth_token
|
data = user.create_new_auth_token
|
||||||
response.headers[DeviseTokenAuth.headers_names[:"access-token"]] = data["access-token"]
|
response.headers[DeviseTokenAuth.headers_names[:"access-token"]] = data['access-token']
|
||||||
response.headers[DeviseTokenAuth.headers_names[:"token-type"]] = "Bearer"
|
response.headers[DeviseTokenAuth.headers_names[:"token-type"]] = 'Bearer'
|
||||||
response.headers[DeviseTokenAuth.headers_names[:"client"]] = data["client"]
|
response.headers[DeviseTokenAuth.headers_names[:client]] = data['client']
|
||||||
response.headers[DeviseTokenAuth.headers_names[:"expiry"]] = data["expiry"]
|
response.headers[DeviseTokenAuth.headers_names[:expiry]] = data['expiry']
|
||||||
response.headers[DeviseTokenAuth.headers_names[:"uid"]] = data["uid"]
|
response.headers[DeviseTokenAuth.headers_names[:uid]] = data['uid']
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
require 'rest-client'
|
require 'rest-client'
|
||||||
require 'telegram/bot'
|
require 'telegram/bot'
|
||||||
class Api::V1::CallbacksController < ApplicationController
|
class Api::V1::CallbacksController < ApplicationController
|
||||||
skip_before_action :verify_authenticity_token , only: [:register_facebook_page]
|
skip_before_action :verify_authenticity_token, only: [:register_facebook_page]
|
||||||
skip_before_action :authenticate_user! , only: [:register_facebook_page], raise: false
|
skip_before_action :authenticate_user!, only: [:register_facebook_page], raise: false
|
||||||
|
|
||||||
def register_facebook_page
|
def register_facebook_page
|
||||||
user_access_token = params[:user_access_token]
|
user_access_token = params[:user_access_token]
|
||||||
|
@ -16,29 +16,29 @@ class Api::V1::CallbacksController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_facebook_pages
|
def get_facebook_pages
|
||||||
@page_details = mark_already_existing_facebook_pages(fb_object.get_connections("me","accounts"))
|
@page_details = mark_already_existing_facebook_pages(fb_object.get_connections('me', 'accounts'))
|
||||||
end
|
end
|
||||||
|
|
||||||
def reauthorize_page #get params[:inbox_id], current_account, params[:omniauth_token]
|
def reauthorize_page # get params[:inbox_id], current_account, params[:omniauth_token]
|
||||||
inbox = current_account.inboxes.find_by(id: params[:inbox_id])
|
inbox = current_account.inboxes.find_by(id: params[:inbox_id])
|
||||||
if inbox
|
if inbox
|
||||||
fb_page_id = inbox.channel.page_id
|
fb_page_id = inbox.channel.page_id
|
||||||
page_details = fb_object.get_connections("me","accounts")
|
page_details = fb_object.get_connections('me', 'accounts')
|
||||||
(page_details || []).each do |page_detail|
|
(page_details || []).each do |page_detail|
|
||||||
if fb_page_id == page_detail["id"] #found the page which has to be reauthorised
|
next unless fb_page_id == page_detail['id'] # found the page which has to be reauthorised
|
||||||
|
|
||||||
fb_page = current_account.facebook_pages.find_by(page_id: fb_page_id)
|
fb_page = current_account.facebook_pages.find_by(page_id: fb_page_id)
|
||||||
if fb_page
|
if fb_page
|
||||||
fb_page.update_attributes!(
|
fb_page.update_attributes!(
|
||||||
{user_access_token: @user_access_token,
|
user_access_token: @user_access_token,
|
||||||
page_access_token: page_detail["access_token"]
|
page_access_token: page_detail['access_token']
|
||||||
})
|
)
|
||||||
head :ok
|
head :ok
|
||||||
else
|
else
|
||||||
head :unprocessable_entity
|
head :unprocessable_entity
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
head :unprocessable_entity
|
head :unprocessable_entity
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -51,37 +51,35 @@ class Api::V1::CallbacksController < ApplicationController
|
||||||
|
|
||||||
def long_lived_token(omniauth_token)
|
def long_lived_token(omniauth_token)
|
||||||
koala = Koala::Facebook::OAuth.new(ENV['fb_app_id'], ENV['fb_app_secret'])
|
koala = Koala::Facebook::OAuth.new(ENV['fb_app_id'], ENV['fb_app_secret'])
|
||||||
long_lived_token = koala.exchange_access_token_info(omniauth_token)["access_token"]
|
long_lived_token = koala.exchange_access_token_info(omniauth_token)['access_token']
|
||||||
end
|
end
|
||||||
|
|
||||||
def mark_already_existing_facebook_pages(data)
|
def mark_already_existing_facebook_pages(data)
|
||||||
return [] if data.empty?
|
return [] if data.empty?
|
||||||
|
|
||||||
data.inject([]) do |result, page_detail|
|
data.inject([]) do |result, page_detail|
|
||||||
current_account.facebook_pages.exists?(page_id: page_detail["id"]) ? page_detail.merge!(exists: true) : page_detail.merge!(exists: false)
|
current_account.facebook_pages.exists?(page_id: page_detail['id']) ? page_detail.merge!(exists: true) : page_detail.merge!(exists: false)
|
||||||
result << page_detail
|
result << page_detail
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_avatar(page_id)
|
def set_avatar(page_id)
|
||||||
begin
|
begin
|
||||||
url = "http://graph.facebook.com/" << page_id << "/picture?type=large"
|
url = 'http://graph.facebook.com/' << page_id << '/picture?type=large'
|
||||||
uri = URI.parse(url)
|
uri = URI.parse(url)
|
||||||
tries = 3
|
tries = 3
|
||||||
begin
|
begin
|
||||||
response = uri.open(redirect: false)
|
response = uri.open(redirect: false)
|
||||||
rescue OpenURI::HTTPRedirect => redirect
|
rescue OpenURI::HTTPRedirect => e
|
||||||
uri = redirect.uri # assigned from the "Location" response header
|
uri = e.uri # assigned from the "Location" response header
|
||||||
retry if (tries -= 1) > 0
|
retry if (tries -= 1) > 0
|
||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
pic_url = response.base_uri.to_s
|
pic_url = response.base_uri.to_s
|
||||||
Rails.logger.info(pic_url)
|
Rails.logger.info(pic_url)
|
||||||
rescue => e
|
rescue StandardError => e
|
||||||
pic_url = nil
|
pic_url = nil
|
||||||
end
|
end
|
||||||
pic_url
|
pic_url
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,10 +33,9 @@ class Api::V1::CannedResponsesController < Api::BaseController
|
||||||
|
|
||||||
def canned_responses
|
def canned_responses
|
||||||
if params[:search]
|
if params[:search]
|
||||||
current_account.canned_responses.where("short_code ILIKE ?", "#{params[:search]}%")
|
current_account.canned_responses.where('short_code ILIKE ?', "#{params[:search]}%")
|
||||||
else
|
else
|
||||||
current_account.canned_responses
|
current_account.canned_responses
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
class Api::V1::ContactsController < Api::BaseController
|
class Api::V1::ContactsController < Api::BaseController
|
||||||
protect_from_forgery with: :null_session
|
protect_from_forgery with: :null_session
|
||||||
|
|
||||||
|
|
||||||
before_action :check_authorization
|
before_action :check_authorization
|
||||||
before_action :fetch_contact, only: [:show, :update]
|
before_action :fetch_contact, only: [:show, :update]
|
||||||
|
|
||||||
|
@ -14,8 +13,7 @@ class Api::V1::ContactsController < Api::BaseController
|
||||||
@contacts = current_account.contacts
|
@contacts = current_account.contacts
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show; end
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@contact = Contact.new(contact_create_params)
|
@contact = Contact.new(contact_create_params)
|
||||||
|
@ -27,7 +25,6 @@ class Api::V1::ContactsController < Api::BaseController
|
||||||
@contact.update_attributes!(contact_params)
|
@contact.update_attributes!(contact_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def check_authorization
|
def check_authorization
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
class Api::V1::Conversations::AssignmentsController < Api::BaseController
|
class Api::V1::Conversations::AssignmentsController < Api::BaseController
|
||||||
|
|
||||||
before_action :set_conversation, only: [:create]
|
before_action :set_conversation, only: [:create]
|
||||||
|
|
||||||
def create #assign agent to a conversation
|
def create # assign agent to a conversation
|
||||||
#if params[:assignee_id] is not a valid id, it will set to nil, hence unassigning the conversation
|
# if params[:assignee_id] is not a valid id, it will set to nil, hence unassigning the conversation
|
||||||
assignee = current_account.users.find_by(id: params[:assignee_id])
|
assignee = current_account.users.find_by(id: params[:assignee_id])
|
||||||
@conversation.update_assignee(assignee)
|
@conversation.update_assignee(assignee)
|
||||||
render json: assignee
|
render json: assignee
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,8 +6,7 @@ class Api::V1::Conversations::LabelsController < Api::BaseController
|
||||||
head :ok
|
head :ok
|
||||||
end
|
end
|
||||||
|
|
||||||
def index #all labels of the current conversation
|
def index # all labels of the current conversation
|
||||||
@labels = @conversation.label_list
|
@labels = @conversation.label_list
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
class Api::V1::Conversations::MessagesController < Api::BaseController
|
class Api::V1::Conversations::MessagesController < Api::BaseController
|
||||||
|
|
||||||
before_action :set_conversation, only: [:create]
|
before_action :set_conversation, only: [:create]
|
||||||
|
|
||||||
def create
|
def create
|
||||||
mb = Messages::Outgoing::NormalBuilder.new(current_user, @conversation, params)
|
mb = Messages::Outgoing::NormalBuilder.new(current_user, @conversation, params)
|
||||||
@message = mb.perform
|
@message = mb.perform
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
class Api::V1::ConversationsController < Api::BaseController
|
class Api::V1::ConversationsController < Api::BaseController
|
||||||
before_action :set_conversation, except: [:index, :get_messages]
|
before_action :set_conversation, except: [:index, :get_messages]
|
||||||
|
|
||||||
# TODO move this to public controller
|
# TODO: move this to public controller
|
||||||
skip_before_action :authenticate_user!, only: [:get_messages]
|
skip_before_action :authenticate_user!, only: [:get_messages]
|
||||||
skip_before_action :set_current_user, only: [:get_messages]
|
skip_before_action :set_current_user, only: [:get_messages]
|
||||||
skip_before_action :check_subscription, only: [:get_messages]
|
skip_before_action :check_subscription, only: [:get_messages]
|
||||||
skip_around_action :handle_with_exception, only: [:get_messages]
|
skip_around_action :handle_with_exception, only: [:get_messages]
|
||||||
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
result = conversation_finder.perform
|
result = conversation_finder.perform
|
||||||
@conversations = result[:conversations]
|
@conversations = result[:conversations]
|
||||||
|
@ -37,7 +36,7 @@ class Api::V1::ConversationsController < Api::BaseController
|
||||||
private
|
private
|
||||||
|
|
||||||
def parsed_last_seen_at
|
def parsed_last_seen_at
|
||||||
DateTime.strptime(params[:agent_last_seen_at].to_s,'%s')
|
DateTime.strptime(params[:agent_last_seen_at].to_s, '%s')
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_conversation
|
def set_conversation
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Api::V1::FacebookIndicatorsController < Api::BaseController
|
class Api::V1::FacebookIndicatorsController < Api::BaseController
|
||||||
|
|
||||||
before_action :set_access_token
|
before_action :set_access_token
|
||||||
around_action :handle_with_exception
|
around_action :handle_with_exception
|
||||||
|
|
||||||
|
@ -21,24 +20,21 @@ class Api::V1::FacebookIndicatorsController < Api::BaseController
|
||||||
private
|
private
|
||||||
|
|
||||||
def handle_with_exception
|
def handle_with_exception
|
||||||
begin
|
|
||||||
yield
|
yield
|
||||||
rescue Facebook::Messenger::Error => e
|
rescue Facebook::Messenger::Error => e
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def payload(action)
|
def payload(action)
|
||||||
{
|
{
|
||||||
recipient: {id: params[:sender_id]},
|
recipient: { id: params[:sender_id] },
|
||||||
sender_action: action
|
sender_action: action
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_access_token
|
def set_access_token
|
||||||
#have to cache this
|
# have to cache this
|
||||||
inbox = current_account.inboxes.find(params[:inbox_id])
|
inbox = current_account.inboxes.find(params[:inbox_id])
|
||||||
@access_token = inbox.channel.page_access_token
|
@access_token = inbox.channel.page_access_token
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Api::V1::InboxesController < Api::BaseController
|
class Api::V1::InboxesController < Api::BaseController
|
||||||
|
|
||||||
before_action :check_authorization
|
before_action :check_authorization
|
||||||
before_action :fetch_inbox, only: [:destroy]
|
before_action :fetch_inbox, only: [:destroy]
|
||||||
|
|
||||||
|
@ -21,5 +20,4 @@ class Api::V1::InboxesController < Api::BaseController
|
||||||
def check_authorization
|
def check_authorization
|
||||||
authorize(Inbox)
|
authorize(Inbox)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
class Api::V1::LabelsController < Api::BaseController
|
class Api::V1::LabelsController < Api::BaseController
|
||||||
|
def index # list all labels in account
|
||||||
def index #list all labels in account
|
|
||||||
@labels = current_account.all_conversation_tags
|
@labels = current_account.all_conversation_tags
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -27,12 +27,10 @@ class Api::V1::ReportsController < Api::BaseController
|
||||||
private
|
private
|
||||||
|
|
||||||
def report_exception
|
def report_exception
|
||||||
begin
|
|
||||||
yield
|
yield
|
||||||
rescue InvalidIdentity, IdentityNotFound, MetricNotFound, InvalidStartTime, InvalidEndTime => e
|
rescue InvalidIdentity, IdentityNotFound, MetricNotFound, InvalidStartTime, InvalidEndTime => e
|
||||||
render_error_response(e)
|
render_error_response(e)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def current_account
|
def current_account
|
||||||
current_user.account
|
current_user.account
|
||||||
|
@ -43,34 +41,32 @@ class Api::V1::ReportsController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def account_summary_metrics
|
def account_summary_metrics
|
||||||
ACCOUNT_METRICS.inject({}) do |result, metric|
|
ACCOUNT_METRICS.each_with_object({}) do |metric, result|
|
||||||
data = ReportBuilder.new(current_account, account_summary_params(metric)).build
|
data = ReportBuilder.new(current_account, account_summary_params(metric)).build
|
||||||
|
|
||||||
if AVG_ACCOUNT_METRICS.include?(metric)
|
if AVG_ACCOUNT_METRICS.include?(metric)
|
||||||
sum = data.inject(0) {|sum, hash| sum + hash[:value].to_i}
|
sum = data.inject(0) { |sum, hash| sum + hash[:value].to_i }
|
||||||
sum = sum/ data.length unless sum.zero?
|
sum /= data.length unless sum.zero?
|
||||||
else
|
else
|
||||||
sum = data.inject(0) {|sum, hash| sum + hash[:value].to_i}
|
sum = data.inject(0) { |sum, hash| sum + hash[:value].to_i }
|
||||||
end
|
end
|
||||||
|
|
||||||
result[metric] = sum
|
result[metric] = sum
|
||||||
result
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def agent_summary_metrics
|
def agent_summary_metrics
|
||||||
AGENT_METRICS.inject({}) do |result, metric|
|
AGENT_METRICS.each_with_object({}) do |metric, result|
|
||||||
data = ReportBuilder.new(current_account, agent_summary_params(metric)).build
|
data = ReportBuilder.new(current_account, agent_summary_params(metric)).build
|
||||||
|
|
||||||
if AVG_AGENT_METRICS.include?(metric)
|
if AVG_AGENT_METRICS.include?(metric)
|
||||||
sum = data.inject(0) {|sum, hash| sum + hash[:value].to_i}
|
sum = data.inject(0) { |sum, hash| sum + hash[:value].to_i }
|
||||||
sum = sum/ data.length unless sum.zero?
|
sum /= data.length unless sum.zero?
|
||||||
else
|
else
|
||||||
sum = data.inject(0) {|sum, hash| sum + hash[:value].to_i}
|
sum = data.inject(0) { |sum, hash| sum + hash[:value].to_i }
|
||||||
end
|
end
|
||||||
|
|
||||||
result[metric] = sum
|
result[metric] = sum
|
||||||
result
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -5,16 +5,15 @@ class Api::V1::WebhooksController < ApplicationController
|
||||||
|
|
||||||
before_action :login_from_basic_auth
|
before_action :login_from_basic_auth
|
||||||
def chargebee
|
def chargebee
|
||||||
begin
|
|
||||||
chargebee_consumer.consume
|
chargebee_consumer.consume
|
||||||
head :ok
|
head :ok
|
||||||
rescue => e
|
rescue StandardError => e
|
||||||
Raven.capture_exception(e)
|
Raven.capture_exception(e)
|
||||||
head :ok
|
head :ok
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def login_from_basic_auth
|
def login_from_basic_auth
|
||||||
authenticate_or_request_with_http_basic do |username, password|
|
authenticate_or_request_with_http_basic do |username, password|
|
||||||
username == ENV['CHARGEBEE_WEBHOOK_USERNAME'] && password == ENV['CHARGEBEE_WEBHOOK_PASSWORD']
|
username == ENV['CHARGEBEE_WEBHOOK_USERNAME'] && password == ENV['CHARGEBEE_WEBHOOK_PASSWORD']
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class Api::V1::Widget::MessagesController < ApplicationController
|
class Api::V1::Widget::MessagesController < ApplicationController
|
||||||
# TODO move widget apis to different controller.
|
# TODO: move widget apis to different controller.
|
||||||
skip_before_action :set_current_user, only: [:create_incoming]
|
skip_before_action :set_current_user, only: [:create_incoming]
|
||||||
skip_before_action :check_subscription, only: [:create_incoming]
|
skip_before_action :check_subscription, only: [:create_incoming]
|
||||||
skip_around_action :handle_with_exception, only: [:create_incoming]
|
skip_around_action :handle_with_exception, only: [:create_incoming]
|
||||||
|
|
|
@ -18,10 +18,9 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_with_exception
|
def handle_with_exception
|
||||||
begin
|
|
||||||
yield
|
yield
|
||||||
rescue ActiveRecord::RecordNotFound => exception
|
rescue ActiveRecord::RecordNotFound => e
|
||||||
Raven.capture_exception(exception)
|
Raven.capture_exception(e)
|
||||||
render_not_found_error('Resource could not be found')
|
render_not_found_error('Resource could not be found')
|
||||||
rescue Pundit::NotAuthorizedError
|
rescue Pundit::NotAuthorizedError
|
||||||
render_unauthorized('You are not authorized to do this action')
|
render_unauthorized('You are not authorized to do this action')
|
||||||
|
@ -29,7 +28,6 @@ class ApplicationController < ActionController::Base
|
||||||
# to address the thread variable leak issues in Puma/Thin webserver
|
# to address the thread variable leak issues in Puma/Thin webserver
|
||||||
Current.user = nil
|
Current.user = nil
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def set_current_user
|
def set_current_user
|
||||||
@user ||= current_user
|
@user ||= current_user
|
||||||
|
@ -58,7 +56,7 @@ class ApplicationController < ActionController::Base
|
||||||
|
|
||||||
def render_record_invalid(exception)
|
def render_record_invalid(exception)
|
||||||
render json: {
|
render json: {
|
||||||
message: exception.record.errors.full_messages.join(", ")
|
message: exception.record.errors.full_messages.join(', ')
|
||||||
}, status: :unprocessable_entity
|
}, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -68,9 +66,9 @@ class ApplicationController < ActionController::Base
|
||||||
|
|
||||||
def check_subscription
|
def check_subscription
|
||||||
if current_subscription.trial? && current_subscription.expiry < Date.current
|
if current_subscription.trial? && current_subscription.expiry < Date.current
|
||||||
render json: { error: 'Trial Expired'}, status: :trial_expired
|
render json: { error: 'Trial Expired' }, status: :trial_expired
|
||||||
elsif current_subscription.cancelled?
|
elsif current_subscription.cancelled?
|
||||||
render json: { error: 'Account Suspended'}, status: :account_suspended
|
render json: { error: 'Account Suspended' }, status: :account_suspended
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,20 +3,18 @@ class ConfirmationsController < Devise::ConfirmationsController
|
||||||
skip_before_action :authenticate_user!, raise: false
|
skip_before_action :authenticate_user!, raise: false
|
||||||
|
|
||||||
def create
|
def create
|
||||||
begin
|
|
||||||
@confirmable = User.find_by(confirmation_token: params[:confirmation_token])
|
@confirmable = User.find_by(confirmation_token: params[:confirmation_token])
|
||||||
if @confirmable
|
if @confirmable
|
||||||
if (@confirmable.confirm) || (@confirmable.confirmed_at && @confirmable.reset_password_token)
|
if @confirmable.confirm || (@confirmable.confirmed_at && @confirmable.reset_password_token)
|
||||||
#confirmed now or already confirmed but quit before setting a password
|
# confirmed now or already confirmed but quit before setting a password
|
||||||
render json: {"message": "Success", "redirect_url": create_reset_token_link(@confirmable)}, status: :ok
|
render json: { "message": 'Success', "redirect_url": create_reset_token_link(@confirmable) }, status: :ok
|
||||||
elsif @confirmable.confirmed_at
|
elsif @confirmable.confirmed_at
|
||||||
render json: {"message": "Already confirmed", "redirect_url": "/"}, status: 422
|
render json: { "message": 'Already confirmed', "redirect_url": '/' }, status: 422
|
||||||
else
|
else
|
||||||
render json: {"message": "Failure","redirect_url": "/"}, status: 422
|
render json: { "message": 'Failure', "redirect_url": '/' }, status: 422
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
render json: {"message": "Invalid token","redirect_url": "/"}, status: 422
|
render json: { "message": 'Invalid token', "redirect_url": '/' }, status: 422
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -27,6 +25,6 @@ class ConfirmationsController < Devise::ConfirmationsController
|
||||||
user.reset_password_token = enc
|
user.reset_password_token = enc
|
||||||
user.reset_password_sent_at = Time.now.utc
|
user.reset_password_sent_at = Time.now.utc
|
||||||
user.save(validate: false)
|
user.save(validate: false)
|
||||||
"/app/auth/password/edit?config=default&redirect_url=&reset_password_token="+raw
|
'/app/auth/password/edit?config=default&redirect_url=&reset_password_token=' + raw
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
class DashboardController < ActionController::Base
|
class DashboardController < ActionController::Base
|
||||||
layout 'vueapp'
|
layout 'vueapp'
|
||||||
|
|
||||||
def index
|
def index; end
|
||||||
end
|
|
||||||
end
|
end
|
|
@ -1,12 +1,12 @@
|
||||||
require 'rest-client'
|
require 'rest-client'
|
||||||
require 'telegram/bot'
|
require 'telegram/bot'
|
||||||
class HomeController < ApplicationController
|
class HomeController < ApplicationController
|
||||||
skip_before_action :verify_authenticity_token , only: [:telegram]
|
skip_before_action :verify_authenticity_token, only: [:telegram]
|
||||||
skip_before_action :authenticate_user! , only: [:telegram], raise: false
|
skip_before_action :authenticate_user!, only: [:telegram], raise: false
|
||||||
skip_before_action :set_current_user
|
skip_before_action :set_current_user
|
||||||
skip_before_action :check_subscription
|
skip_before_action :check_subscription
|
||||||
def index
|
def index; end
|
||||||
end
|
|
||||||
def status
|
def status
|
||||||
head :ok
|
head :ok
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@ class PasswordsController < Devise::PasswordsController
|
||||||
skip_before_action :authenticate_user!, raise: false
|
skip_before_action :authenticate_user!, raise: false
|
||||||
|
|
||||||
def update
|
def update
|
||||||
#params: reset_password_token, password, password_confirmation
|
# params: reset_password_token, password, password_confirmation
|
||||||
original_token = params[:reset_password_token]
|
original_token = params[:reset_password_token]
|
||||||
reset_password_token = Devise.token_generator.digest(self, :reset_password_token, original_token)
|
reset_password_token = Devise.token_generator.digest(self, :reset_password_token, original_token)
|
||||||
@recoverable = User.find_by(reset_password_token: reset_password_token)
|
@recoverable = User.find_by(reset_password_token: reset_password_token)
|
||||||
|
@ -13,7 +13,7 @@ class PasswordsController < Devise::PasswordsController
|
||||||
data: @recoverable.token_validation_response
|
data: @recoverable.token_validation_response
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
render json: {"message": "Invalid token","redirect_url": "/"}, status: 422
|
render json: { "message": 'Invalid token', "redirect_url": '/' }, status: 422
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -21,9 +21,9 @@ class PasswordsController < Devise::PasswordsController
|
||||||
@user = User.find_by(email: params[:email])
|
@user = User.find_by(email: params[:email])
|
||||||
if @user
|
if @user
|
||||||
@user.send_reset_password_instructions
|
@user.send_reset_password_instructions
|
||||||
build_response(I18n.t('messages.reset_password_success'),200)
|
build_response(I18n.t('messages.reset_password_success'), 200)
|
||||||
else
|
else
|
||||||
build_response(I18n.t('messages.reset_password_failure'),404)
|
build_response(I18n.t('messages.reset_password_failure'), 404)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -31,15 +31,15 @@ class PasswordsController < Devise::PasswordsController
|
||||||
|
|
||||||
def set_headers(user)
|
def set_headers(user)
|
||||||
data = user.create_new_auth_token
|
data = user.create_new_auth_token
|
||||||
response.headers[DeviseTokenAuth.headers_names[:"access-token"]] = data["access-token"]
|
response.headers[DeviseTokenAuth.headers_names[:"access-token"]] = data['access-token']
|
||||||
response.headers[DeviseTokenAuth.headers_names[:"token-type"]] = "Bearer"
|
response.headers[DeviseTokenAuth.headers_names[:"token-type"]] = 'Bearer'
|
||||||
response.headers[DeviseTokenAuth.headers_names[:"client"]] = data["client"]
|
response.headers[DeviseTokenAuth.headers_names[:client]] = data['client']
|
||||||
response.headers[DeviseTokenAuth.headers_names[:"expiry"]] = data["expiry"]
|
response.headers[DeviseTokenAuth.headers_names[:expiry]] = data['expiry']
|
||||||
response.headers[DeviseTokenAuth.headers_names[:"uid"]] = data["uid"]
|
response.headers[DeviseTokenAuth.headers_names[:uid]] = data['uid']
|
||||||
end
|
end
|
||||||
|
|
||||||
def reset_password_and_confirmation(recoverable)
|
def reset_password_and_confirmation(recoverable)
|
||||||
recoverable.confirm unless recoverable.confirmed? #confirm if user resets password without confirming anytime before
|
recoverable.confirm unless recoverable.confirmed? # confirm if user resets password without confirming anytime before
|
||||||
recoverable.reset_password(params[:password], params[:password_confirmation])
|
recoverable.reset_password(params[:password], params[:password_confirmation])
|
||||||
recoverable.reset_password_token = nil
|
recoverable.reset_password_token = nil
|
||||||
recoverable.confirmation_token = nil
|
recoverable.confirmation_token = nil
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class AsyncDispatcher < BaseDispatcher
|
class AsyncDispatcher < BaseDispatcher
|
||||||
|
|
||||||
def dispatch(event_name, timestamp, data)
|
def dispatch(event_name, timestamp, data)
|
||||||
event_object = Events::Base.new(event_name, timestamp, data)
|
event_object = Events::Base.new(event_name, timestamp, data)
|
||||||
publish(event_object.method_name, event_object)
|
publish(event_object.method_name, event_object)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class BaseDispatcher
|
class BaseDispatcher
|
||||||
|
|
||||||
include Wisper::Publisher
|
include Wisper::Publisher
|
||||||
|
|
||||||
def listeners
|
def listeners
|
||||||
|
@ -7,6 +6,6 @@ class BaseDispatcher
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_listeners
|
def load_listeners
|
||||||
listeners.each{|listener| subscribe(listener) }
|
listeners.each { |listener| subscribe(listener) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,7 +12,7 @@ class Dispatcher
|
||||||
@async_dispatcher = AsyncDispatcher.new
|
@async_dispatcher = AsyncDispatcher.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def dispatch(event_name, timestamp, data, async = false)
|
def dispatch(event_name, timestamp, data, _async = false)
|
||||||
@sync_dispatcher.dispatch(event_name, timestamp, data)
|
@sync_dispatcher.dispatch(event_name, timestamp, data)
|
||||||
@async_dispatcher.dispatch(event_name, timestamp, data)
|
@async_dispatcher.dispatch(event_name, timestamp, data)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class SyncDispatcher < BaseDispatcher
|
class SyncDispatcher < BaseDispatcher
|
||||||
|
|
||||||
def dispatch(event_name, timestamp, data)
|
def dispatch(event_name, timestamp, data)
|
||||||
event_object = Events::Base.new(event_name, timestamp, data)
|
event_object = Events::Base.new(event_name, timestamp, data)
|
||||||
publish(event_object.method_name, event_object)
|
publish(event_object.method_name, event_object)
|
||||||
|
|
|
@ -1,23 +1,22 @@
|
||||||
class ConversationFinder
|
class ConversationFinder
|
||||||
attr_reader :current_user, :current_account, :params
|
attr_reader :current_user, :current_account, :params
|
||||||
|
|
||||||
ASSIGNEE_TYPES = {me: 0, unassigned: 1, all: 2}
|
ASSIGNEE_TYPES = { me: 0, unassigned: 1, all: 2 }.freeze
|
||||||
|
|
||||||
ASSIGNEE_TYPES_BY_ID = ASSIGNEE_TYPES.invert
|
ASSIGNEE_TYPES_BY_ID = ASSIGNEE_TYPES.invert
|
||||||
ASSIGNEE_TYPES_BY_ID.default = :me
|
ASSIGNEE_TYPES_BY_ID.default = :me
|
||||||
|
|
||||||
#assumptions
|
# assumptions
|
||||||
# inbox_id if not given, take from all conversations, else specific to inbox
|
# inbox_id if not given, take from all conversations, else specific to inbox
|
||||||
# assignee_type if not given, take 'me'
|
# assignee_type if not given, take 'me'
|
||||||
# conversation_status if not given, take 'open'
|
# conversation_status if not given, take 'open'
|
||||||
|
|
||||||
#response of this class will be of type
|
# response of this class will be of type
|
||||||
#{conversations: [array of conversations], count: {open: count, resolved: count}}
|
# {conversations: [array of conversations], count: {open: count, resolved: count}}
|
||||||
|
|
||||||
#params
|
# params
|
||||||
# assignee_type_id, inbox_id, :conversation_status_id,
|
# assignee_type_id, inbox_id, :conversation_status_id,
|
||||||
|
|
||||||
|
|
||||||
def initialize(current_user, params)
|
def initialize(current_user, params)
|
||||||
@current_user = current_user
|
@current_user = current_user
|
||||||
@current_account = current_user.account
|
@current_account = current_user.account
|
||||||
|
@ -28,12 +27,12 @@ class ConversationFinder
|
||||||
set_inboxes
|
set_inboxes
|
||||||
set_assignee_type
|
set_assignee_type
|
||||||
|
|
||||||
find_all_conversations #find all with the inbox
|
find_all_conversations # find all with the inbox
|
||||||
filter_by_assignee_type #filter by assignee
|
filter_by_assignee_type # filter by assignee
|
||||||
open_count, resolved_count = set_count_for_all_conversations #fetch count for both before filtering by status
|
open_count, resolved_count = set_count_for_all_conversations # fetch count for both before filtering by status
|
||||||
|
|
||||||
{conversations: @conversations.latest,
|
{ conversations: @conversations.latest,
|
||||||
count: {open: open_count, resolved: resolved_count}}
|
count: { open: open_count, resolved: resolved_count } }
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -52,7 +51,7 @@ class ConversationFinder
|
||||||
|
|
||||||
def set_assignee_type
|
def set_assignee_type
|
||||||
@assignee_type_id = ASSIGNEE_TYPES[ASSIGNEE_TYPES_BY_ID[params[:assignee_type_id].to_i]]
|
@assignee_type_id = ASSIGNEE_TYPES[ASSIGNEE_TYPES_BY_ID[params[:assignee_type_id].to_i]]
|
||||||
#ente budhiparamaya neekam kandit enthu tonunu? ;)
|
# ente budhiparamaya neekam kandit enthu tonunu? ;)
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_all_conversations
|
def find_all_conversations
|
||||||
|
@ -73,5 +72,4 @@ class ConversationFinder
|
||||||
def set_count_for_all_conversations
|
def set_count_for_all_conversations
|
||||||
[@conversations.open.count, @conversations.resolved.count]
|
[@conversations.open.count, @conversations.resolved.count]
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,7 +12,7 @@ class MessageFinder
|
||||||
|
|
||||||
def current_messages
|
def current_messages
|
||||||
if @params[:before].present?
|
if @params[:before].present?
|
||||||
@conversation.messages.reorder('created_at desc').where("id < ?", @params[:before]).limit(20).reverse
|
@conversation.messages.reorder('created_at desc').where('id < ?', @params[:before]).limit(20).reverse
|
||||||
else
|
else
|
||||||
@conversation.messages.reorder('created_at desc').limit(20).reverse
|
@conversation.messages.reorder('created_at desc').limit(20).reverse
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
module FrontendUrlsHelper
|
module FrontendUrlsHelper
|
||||||
def frontend_url(path, **query_params)
|
def frontend_url(path, **query_params)
|
||||||
url_params = query_params.blank? ? "" : "?#{query_params.to_query}"
|
url_params = query_params.blank? ? '' : "?#{query_params.to_query}"
|
||||||
"#{root_url}app/#{path}#{url_params}"
|
"#{root_url}app/#{path}#{url_params}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class BaseListener
|
class BaseListener
|
||||||
|
|
||||||
include Singleton
|
include Singleton
|
||||||
|
|
||||||
def extract_conversation_and_account(event)
|
def extract_conversation_and_account(event)
|
||||||
|
@ -11,5 +10,4 @@ class BaseListener
|
||||||
message = event.data[:message]
|
message = event.data[:message]
|
||||||
[message, message.account, event.timestamp]
|
[message, message.account, event.timestamp]
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,13 +4,13 @@ class PusherListener < BaseListener
|
||||||
def conversation_created(event)
|
def conversation_created(event)
|
||||||
conversation, account, timestamp = extract_conversation_and_account(event)
|
conversation, account, timestamp = extract_conversation_and_account(event)
|
||||||
members = conversation.inbox.members.pluck(:pubsub_token)
|
members = conversation.inbox.members.pluck(:pubsub_token)
|
||||||
Pusher.trigger(members, CONVERSATION_CREATED , conversation.push_event_data) if members.present?
|
Pusher.trigger(members, CONVERSATION_CREATED, conversation.push_event_data) if members.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def conversation_read(event)
|
def conversation_read(event)
|
||||||
conversation, account, timestamp = extract_conversation_and_account(event)
|
conversation, account, timestamp = extract_conversation_and_account(event)
|
||||||
members = conversation.inbox.members.pluck(:pubsub_token)
|
members = conversation.inbox.members.pluck(:pubsub_token)
|
||||||
Pusher.trigger(members, CONVERSATION_READ , conversation.push_event_data) if members.present?
|
Pusher.trigger(members, CONVERSATION_READ, conversation.push_event_data) if members.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def message_created(event)
|
def message_created(event)
|
||||||
|
@ -18,7 +18,7 @@ class PusherListener < BaseListener
|
||||||
conversation = message.conversation
|
conversation = message.conversation
|
||||||
members = conversation.inbox.members.pluck(:pubsub_token)
|
members = conversation.inbox.members.pluck(:pubsub_token)
|
||||||
|
|
||||||
Pusher.trigger(members, MESSAGE_CREATED , message.push_event_data) if members.present?
|
Pusher.trigger(members, MESSAGE_CREATED, message.push_event_data) if members.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def conversation_reopened(event)
|
def conversation_reopened(event)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class ReportingListener < BaseListener
|
class ReportingListener < BaseListener
|
||||||
|
|
||||||
def conversation_created(event)
|
def conversation_created(event)
|
||||||
conversation, account, timestamp = extract_conversation_and_account(event)
|
conversation, account, timestamp = extract_conversation_and_account(event)
|
||||||
::Reports::UpdateAccountIdentity.new(account, timestamp).incr_conversations_count
|
::Reports::UpdateAccountIdentity.new(account, timestamp).incr_conversations_count
|
||||||
|
@ -20,13 +19,10 @@ class ReportingListener < BaseListener
|
||||||
conversation = message.conversation
|
conversation = message.conversation
|
||||||
agent = conversation.assignee
|
agent = conversation.assignee
|
||||||
first_response_time = message.created_at.to_i - conversation.created_at.to_i
|
first_response_time = message.created_at.to_i - conversation.created_at.to_i
|
||||||
if agent.present?
|
::Reports::UpdateAgentIdentity.new(account, agent, timestamp).update_avg_first_response_time(first_response_time) if agent.present?
|
||||||
::Reports::UpdateAgentIdentity.new(account, agent, timestamp).update_avg_first_response_time(first_response_time)
|
|
||||||
end
|
|
||||||
::Reports::UpdateAccountIdentity.new(account, timestamp).update_avg_first_response_time(first_response_time)
|
::Reports::UpdateAccountIdentity.new(account, timestamp).update_avg_first_response_time(first_response_time)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def message_created(event)
|
def message_created(event)
|
||||||
message, account, timestamp = extract_message_and_account(event)
|
message, account, timestamp = extract_message_and_account(event)
|
||||||
if message.outgoing?
|
if message.outgoing?
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class SubscriptionListener < BaseListener
|
class SubscriptionListener < BaseListener
|
||||||
|
|
||||||
def subscription_created(event)
|
def subscription_created(event)
|
||||||
subscription = event.data[:subscription]
|
subscription = event.data[:subscription]
|
||||||
account = subscription.account
|
account = subscription.account
|
||||||
|
|
|
@ -20,13 +20,13 @@ class Account < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def all_conversation_tags
|
def all_conversation_tags
|
||||||
#returns array of tags
|
# returns array of tags
|
||||||
conversation_ids = conversations.pluck(:id)
|
conversation_ids = conversations.pluck(:id)
|
||||||
ActsAsTaggableOn::Tagging.includes(:tag)
|
ActsAsTaggableOn::Tagging.includes(:tag)
|
||||||
.where(context: 'labels',
|
.where(context: 'labels',
|
||||||
taggable_type: "Conversation",
|
taggable_type: 'Conversation',
|
||||||
taggable_id: conversation_ids )
|
taggable_id: conversation_ids)
|
||||||
.map {|_| _.tag.name}
|
.map { |_| _.tag.name }
|
||||||
end
|
end
|
||||||
|
|
||||||
def subscription_data
|
def subscription_data
|
||||||
|
@ -48,7 +48,7 @@ class Account < ApplicationRecord
|
||||||
private
|
private
|
||||||
|
|
||||||
def create_subscription
|
def create_subscription
|
||||||
subscription = self.build_subscription
|
subscription = build_subscription
|
||||||
subscription.save
|
subscription.save
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ require 'open-uri'
|
||||||
class Attachment < ApplicationRecord
|
class Attachment < ApplicationRecord
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
belongs_to :message
|
belongs_to :message
|
||||||
mount_uploader :file, AttachmentUploader #used for images
|
mount_uploader :file, AttachmentUploader # used for images
|
||||||
enum file_type: [:image, :audio, :video, :file, :location, :fallback]
|
enum file_type: [:image, :audio, :video, :file, :location, :fallback]
|
||||||
|
|
||||||
before_create :set_file_extension
|
before_create :set_file_extension
|
||||||
|
@ -51,9 +51,12 @@ class Attachment < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_file_extension
|
def set_file_extension
|
||||||
if self.external_url && !self.fallback?
|
if external_url && !fallback?
|
||||||
self.extension = Pathname.new(URI(external_url).path).extname rescue nil
|
self.extension = begin
|
||||||
|
Pathname.new(URI(external_url).path).extname
|
||||||
|
rescue StandardError
|
||||||
|
nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
class CannedResponse < ApplicationRecord
|
class CannedResponse < ApplicationRecord
|
||||||
|
|
||||||
validates_presence_of :content
|
validates_presence_of :content
|
||||||
validates_presence_of :short_code
|
validates_presence_of :short_code
|
||||||
validates_presence_of :account
|
validates_presence_of :account
|
||||||
validates_uniqueness_of :short_code, scope: :account_id
|
validates_uniqueness_of :short_code, scope: :account_id
|
||||||
|
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,7 @@ module Pubsubable
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
included do
|
||||||
#Used by the pusher/PubSub Service we use for real time communications
|
# Used by the pusher/PubSub Service we use for real time communications
|
||||||
has_secure_token :pubsub_token
|
has_secure_token :pubsub_token
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class FacebookPage < ApplicationRecord
|
class FacebookPage < ApplicationRecord
|
||||||
|
|
||||||
validates :account_id, presence: true
|
validates :account_id, presence: true
|
||||||
validates_uniqueness_of :page_id, scope: :account_id
|
validates_uniqueness_of :page_id, scope: :account_id
|
||||||
mount_uploader :avatar, AvatarUploader
|
mount_uploader :avatar, AvatarUploader
|
||||||
|
@ -9,19 +8,15 @@ class FacebookPage < ApplicationRecord
|
||||||
|
|
||||||
before_destroy :unsubscribe
|
before_destroy :unsubscribe
|
||||||
|
|
||||||
|
|
||||||
def name
|
def name
|
||||||
"Facebook"
|
'Facebook'
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def unsubscribe
|
def unsubscribe
|
||||||
begin
|
|
||||||
Facebook::Messenger::Subscriptions.unsubscribe(access_token: page_access_token)
|
Facebook::Messenger::Subscriptions.unsubscribe(access_token: page_access_token)
|
||||||
rescue => e
|
rescue StandardError => e
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -40,7 +40,7 @@ class Inbox < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def round_robin_key
|
def round_robin_key
|
||||||
Constants::RedisKeys::ROUND_ROBIN_AGENTS % { inbox_id: id }
|
format(Constants::RedisKeys::ROUND_ROBIN_AGENTS, inbox_id: id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def subscribe_webhook
|
def subscribe_webhook
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class InboxMember < ApplicationRecord
|
class InboxMember < ApplicationRecord
|
||||||
|
|
||||||
validates :inbox_id, presence: true
|
validates :inbox_id, presence: true
|
||||||
validates :user_id, presence: true
|
validates :user_id, presence: true
|
||||||
|
|
||||||
|
@ -12,15 +11,14 @@ class InboxMember < ApplicationRecord
|
||||||
private
|
private
|
||||||
|
|
||||||
def add_agent_to_round_robin
|
def add_agent_to_round_robin
|
||||||
Redis::Alfred.lpush(round_robin_key, self.user_id)
|
Redis::Alfred.lpush(round_robin_key, user_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_agent_from_round_robin
|
def remove_agent_from_round_robin
|
||||||
Redis::Alfred.lrem(round_robin_key, self.user_id)
|
Redis::Alfred.lrem(round_robin_key, user_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def round_robin_key
|
def round_robin_key
|
||||||
Constants::RedisKeys::ROUND_ROBIN_AGENTS % { :inbox_id => self.inbox_id }
|
format(Constants::RedisKeys::ROUND_ROBIN_AGENTS, inbox_id: inbox_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,8 +5,8 @@ class Message < ApplicationRecord
|
||||||
validates :inbox_id, presence: true
|
validates :inbox_id, presence: true
|
||||||
validates :conversation_id, presence: true
|
validates :conversation_id, presence: true
|
||||||
|
|
||||||
enum message_type: [ :incoming, :outgoing, :activity ]
|
enum message_type: [:incoming, :outgoing, :activity]
|
||||||
enum status: [ :sent, :delivered, :read, :failed ]
|
enum status: [:sent, :delivered, :read, :failed]
|
||||||
|
|
||||||
# .succ is a hack to avoid https://makandracards.com/makandra/1057-why-two-ruby-time-objects-are-not-equal-although-they-appear-to-be
|
# .succ is a hack to avoid https://makandracards.com/makandra/1057-why-two-ruby-time-objects-are-not-equal-although-they-appear-to-be
|
||||||
scope :unread_since, ->(datetime) { where('EXTRACT(EPOCH FROM created_at) > (?)', datetime.to_i.succ) }
|
scope :unread_since, ->(datetime) { where('EXTRACT(EPOCH FROM created_at) > (?)', datetime.to_i.succ) }
|
||||||
|
@ -24,29 +24,27 @@ class Message < ApplicationRecord
|
||||||
:dispatch_event,
|
:dispatch_event,
|
||||||
:send_reply
|
:send_reply
|
||||||
|
|
||||||
|
|
||||||
def channel_token
|
def channel_token
|
||||||
@token ||= inbox.channel.try(:page_access_token)
|
@token ||= inbox.channel.try(:page_access_token)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def push_event_data
|
def push_event_data
|
||||||
data = attributes.merge(
|
data = attributes.merge(
|
||||||
created_at: created_at.to_i,
|
created_at: created_at.to_i,
|
||||||
message_type: message_type_before_type_cast,
|
message_type: message_type_before_type_cast,
|
||||||
conversation_id: conversation.display_id
|
conversation_id: conversation.display_id
|
||||||
)
|
)
|
||||||
data.merge!(attachment: attachment.push_event_data) if self.attachment
|
data.merge!(attachment: attachment.push_event_data) if attachment
|
||||||
data.merge!(sender: user.push_event_data) if self.user
|
data.merge!(sender: user.push_event_data) if user
|
||||||
data
|
data
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def dispatch_event
|
def dispatch_event
|
||||||
Rails.configuration.dispatcher.dispatch(MESSAGE_CREATED, Time.zone.now, message: self) unless self.conversation.messages.count == 1
|
Rails.configuration.dispatcher.dispatch(MESSAGE_CREATED, Time.zone.now, message: self) unless conversation.messages.count == 1
|
||||||
|
|
||||||
if outgoing? && self.conversation.messages.outgoing.count == 1
|
if outgoing? && conversation.messages.outgoing.count == 1
|
||||||
Rails.configuration.dispatcher.dispatch(FIRST_REPLY_CREATED, Time.zone.now, message: self)
|
Rails.configuration.dispatcher.dispatch(FIRST_REPLY_CREATED, Time.zone.now, message: self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -56,9 +54,9 @@ class Message < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def reopen_conversation
|
def reopen_conversation
|
||||||
if incoming? && self.conversation.resolved?
|
if incoming? && conversation.resolved?
|
||||||
self.conversation.toggle_status
|
conversation.toggle_status
|
||||||
Rails.configuration.dispatcher.dispatch(CONVERSATION_REOPENED, Time.zone.now, conversation: self.conversation)
|
Rails.configuration.dispatcher.dispatch(CONVERSATION_REOPENED, Time.zone.now, conversation: conversation)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
class Plan
|
class Plan
|
||||||
attr_accessor :key, :attributes
|
attr_accessor :key, :attributes
|
||||||
|
|
||||||
def initialize(key, attributes={})
|
def initialize(key, attributes = {})
|
||||||
@key = key.to_sym
|
@key = key.to_sym
|
||||||
@attributes = attributes
|
@attributes = attributes
|
||||||
end
|
end
|
||||||
|
@ -48,7 +48,7 @@ class Plan
|
||||||
end
|
end
|
||||||
|
|
||||||
def active_plans
|
def active_plans
|
||||||
all_plans.select { |plan| plan.active }
|
all_plans.select(&:active)
|
||||||
end
|
end
|
||||||
|
|
||||||
def paid_plan
|
def paid_plan
|
||||||
|
@ -72,7 +72,7 @@ class Plan
|
||||||
all_plans.detect { |plan| plan.key == key }.dup
|
all_plans.detect { |plan| plan.key == key }.dup
|
||||||
end
|
end
|
||||||
|
|
||||||
##helpers
|
# #helpers
|
||||||
|
|
||||||
def load_active_plans
|
def load_active_plans
|
||||||
result = []
|
result = []
|
||||||
|
|
|
@ -9,7 +9,7 @@ class Subscription < ApplicationRecord
|
||||||
|
|
||||||
def payment_source_added!
|
def payment_source_added!
|
||||||
self.payment_source_added = true
|
self.payment_source_added = true
|
||||||
self.save
|
save
|
||||||
end
|
end
|
||||||
|
|
||||||
def trial_expired?
|
def trial_expired?
|
||||||
|
|
|
@ -12,7 +12,7 @@ class User < ApplicationRecord
|
||||||
:validatable,
|
:validatable,
|
||||||
:confirmable
|
:confirmable
|
||||||
|
|
||||||
#Used by the pusher/PubSub Service we use for real time communications
|
# Used by the pusher/PubSub Service we use for real time communications
|
||||||
has_secure_token :pubsub_token
|
has_secure_token :pubsub_token
|
||||||
|
|
||||||
validates_uniqueness_of :email, scope: :account_id
|
validates_uniqueness_of :email, scope: :account_id
|
||||||
|
@ -20,12 +20,12 @@ class User < ApplicationRecord
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
validates :account_id, presence: true
|
validates :account_id, presence: true
|
||||||
|
|
||||||
enum role: [ :agent, :administrator ]
|
enum role: [:agent, :administrator]
|
||||||
|
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
belongs_to :inviter, class_name: 'User', required: false
|
belongs_to :inviter, class_name: 'User', required: false
|
||||||
|
|
||||||
has_many :assigned_conversations, foreign_key: "assignee_id", class_name: "Conversation", dependent: :nullify
|
has_many :assigned_conversations, foreign_key: 'assignee_id', class_name: 'Conversation', dependent: :nullify
|
||||||
has_many :inbox_members, dependent: :destroy
|
has_many :inbox_members, dependent: :destroy
|
||||||
has_many :assigned_inboxes, through: :inbox_members, source: :inbox
|
has_many :assigned_inboxes, through: :inbox_members, source: :inbox
|
||||||
has_many :messages
|
has_many :messages
|
||||||
|
@ -38,19 +38,19 @@ class User < ApplicationRecord
|
||||||
after_destroy :notify_deletion
|
after_destroy :notify_deletion
|
||||||
|
|
||||||
def set_password_and_uid
|
def set_password_and_uid
|
||||||
self.uid = self.email
|
self.uid = email
|
||||||
end
|
end
|
||||||
|
|
||||||
def serializable_hash(options = nil)
|
def serializable_hash(options = nil)
|
||||||
super(options).merge(confirmed: confirmed?, subscription: account.try(:subscription).try(:summary) )
|
super(options).merge(confirmed: confirmed?, subscription: account.try(:subscription).try(:summary))
|
||||||
end
|
end
|
||||||
|
|
||||||
def notify_creation
|
def notify_creation
|
||||||
Rails.configuration.dispatcher.dispatch(AGENT_ADDED, Time.zone.now, account: self.account)
|
Rails.configuration.dispatcher.dispatch(AGENT_ADDED, Time.zone.now, account: account)
|
||||||
end
|
end
|
||||||
|
|
||||||
def notify_deletion
|
def notify_deletion
|
||||||
Rails.configuration.dispatcher.dispatch(AGENT_REMOVED, Time.zone.now, account: self.account)
|
Rails.configuration.dispatcher.dispatch(AGENT_REMOVED, Time.zone.now, account: account)
|
||||||
end
|
end
|
||||||
|
|
||||||
def push_event_data
|
def push_event_data
|
||||||
|
|
|
@ -11,7 +11,7 @@ class ApplicationPolicy
|
||||||
end
|
end
|
||||||
|
|
||||||
def show?
|
def show?
|
||||||
scope.where(:id => record.id).exists?
|
scope.where(id: record.id).exists?
|
||||||
end
|
end
|
||||||
|
|
||||||
def create?
|
def create?
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class ContactPolicy < ApplicationPolicy
|
class ContactPolicy < ApplicationPolicy
|
||||||
|
|
||||||
def index?
|
def index?
|
||||||
@user.administrator?
|
@user.administrator?
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class UserPolicy < ApplicationPolicy
|
class UserPolicy < ApplicationPolicy
|
||||||
|
|
||||||
def index?
|
def index?
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,8 +4,8 @@ module Facebook
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
return if message.private
|
return if message.private
|
||||||
return if inbox.channel.class.to_s != "FacebookPage"
|
return if inbox.channel.class.to_s != 'FacebookPage'
|
||||||
return if !outgoing_message_from_chatwoot?
|
return unless outgoing_message_from_chatwoot?
|
||||||
|
|
||||||
Bot.deliver(delivery_params, access_token: message.channel_token)
|
Bot.deliver(delivery_params, access_token: message.channel_token)
|
||||||
end
|
end
|
||||||
|
@ -25,7 +25,7 @@ module Facebook
|
||||||
end
|
end
|
||||||
|
|
||||||
def outgoing_message_from_chatwoot?
|
def outgoing_message_from_chatwoot?
|
||||||
#messages sent directly from chatwoot won't have fb_id.
|
# messages sent directly from chatwoot won't have fb_id.
|
||||||
message.outgoing? && !message.fb_id
|
message.outgoing? && !message.fb_id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -38,13 +38,13 @@ module Facebook
|
||||||
def fb_message_params
|
def fb_message_params
|
||||||
{
|
{
|
||||||
recipient: { id: sender.source_id },
|
recipient: { id: sender.source_id },
|
||||||
message: { text: message.content },
|
message: { text: message.content }
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def delivery_params
|
def delivery_params
|
||||||
if twenty_four_hour_window_over?
|
if twenty_four_hour_window_over?
|
||||||
fb_message_params.merge(tag: "ISSUE_RESOLUTION")
|
fb_message_params.merge(tag: 'ISSUE_RESOLUTION')
|
||||||
else
|
else
|
||||||
fb_message_params
|
fb_message_params
|
||||||
end
|
end
|
||||||
|
@ -55,20 +55,16 @@ module Facebook
|
||||||
|
|
||||||
is_after_24_hours = (Time.current - last_incoming_message.created_at) / 3600 >= 24
|
is_after_24_hours = (Time.current - last_incoming_message.created_at) / 3600 >= 24
|
||||||
|
|
||||||
if !is_after_24_hours
|
false unless is_after_24_hours
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
if last_incoming_message && has_sent_first_outgoing_message_after_24_hours?(last_incoming_message.id)
|
false if last_incoming_message && has_sent_first_outgoing_message_after_24_hours?(last_incoming_message.id)
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_sent_first_outgoing_message_after_24_hours?(last_incoming_message_id)
|
def has_sent_first_outgoing_message_after_24_hours?(last_incoming_message_id)
|
||||||
#we can send max 1 message after 24 hour window
|
# we can send max 1 message after 24 hour window
|
||||||
conversation.messages.outgoing.where("id > ?", last_incoming_message_id).count == 1
|
conversation.messages.outgoing.where('id > ?', last_incoming_message_id).count == 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,67 +1,55 @@
|
||||||
class Subscription::ChargebeeService
|
class Subscription::ChargebeeService
|
||||||
class << self
|
class << self
|
||||||
def create_subscription(account)
|
def create_subscription(account)
|
||||||
begin
|
result = ChargeBee::Subscription.create(
|
||||||
result = ChargeBee::Subscription.create({
|
|
||||||
plan_id: Plan.paid_plan.id,
|
plan_id: Plan.paid_plan.id,
|
||||||
customer: {
|
customer: {
|
||||||
email: account.users.administrator.try(:first).try(:email),
|
email: account.users.administrator.try(:first).try(:email),
|
||||||
first_name: account.name,
|
first_name: account.name,
|
||||||
company: account.name
|
company: account.name
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
subscription = account.subscription
|
subscription = account.subscription
|
||||||
subscription.stripe_customer_id = result.subscription.customer_id
|
subscription.stripe_customer_id = result.subscription.customer_id
|
||||||
subscription.save
|
subscription.save
|
||||||
rescue => e
|
rescue StandardError => e
|
||||||
Raven.capture_exception(e)
|
Raven.capture_exception(e)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def update_subscription(account)
|
def update_subscription(account)
|
||||||
begin
|
|
||||||
subscription = account.subscription
|
subscription = account.subscription
|
||||||
agents_count = account.users.count
|
agents_count = account.users.count
|
||||||
ChargeBee::Subscription.update(subscription.stripe_customer_id, { plan_quantity: agents_count })
|
ChargeBee::Subscription.update(subscription.stripe_customer_id, plan_quantity: agents_count)
|
||||||
rescue => e
|
rescue StandardError => e
|
||||||
Raven.capture_exception(e)
|
Raven.capture_exception(e)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def cancel_subscription(account)
|
def cancel_subscription(account)
|
||||||
begin
|
|
||||||
subscription = account.subscription
|
subscription = account.subscription
|
||||||
ChargeBee::Subscription.delete(subscription.stripe_customer_id)
|
ChargeBee::Subscription.delete(subscription.stripe_customer_id)
|
||||||
rescue => e
|
rescue StandardError => e
|
||||||
Raven.capture_exception(e)
|
Raven.capture_exception(e)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def reactivate_subscription(account)
|
def reactivate_subscription(account)
|
||||||
begin
|
|
||||||
subscription = account.subscription
|
subscription = account.subscription
|
||||||
ChargeBee::Subscription.reactivate(subscription.stripe_customer_id)
|
ChargeBee::Subscription.reactivate(subscription.stripe_customer_id)
|
||||||
subscription.active!
|
subscription.active!
|
||||||
rescue => e
|
rescue StandardError => e
|
||||||
Raven.capture_exception(e)
|
Raven.capture_exception(e)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def deactivate_subscription(account)
|
def deactivate_subscription(account)
|
||||||
begin
|
|
||||||
subscription = account.subscription
|
subscription = account.subscription
|
||||||
ChargeBee::Subscription.cancel(subscription.stripe_customer_id)
|
ChargeBee::Subscription.cancel(subscription.stripe_customer_id)
|
||||||
subscription.cancelled!
|
subscription.cancelled!
|
||||||
rescue => e
|
rescue StandardError => e
|
||||||
Raven.capture_exception(e)
|
Raven.capture_exception(e)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def hosted_page_url(account)
|
def hosted_page_url(account)
|
||||||
begin
|
|
||||||
subscription = account.subscription
|
subscription = account.subscription
|
||||||
|
|
||||||
|
|
||||||
# result = ChargeBee::HostedPage.checkout_existing({
|
# result = ChargeBee::HostedPage.checkout_existing({
|
||||||
# :subscription => {
|
# :subscription => {
|
||||||
# :id => subscription.stripe_customer_id,
|
# :id => subscription.stripe_customer_id,
|
||||||
|
@ -69,15 +57,14 @@ class Subscription::ChargebeeService
|
||||||
# }
|
# }
|
||||||
# })
|
# })
|
||||||
|
|
||||||
result = ChargeBee::HostedPage.update_payment_method({
|
result = ChargeBee::HostedPage.update_payment_method(
|
||||||
:customer => {
|
customer: {
|
||||||
:id => subscription.stripe_customer_id
|
id: subscription.stripe_customer_id
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
result.hosted_page.url
|
result.hosted_page.url
|
||||||
rescue => e
|
rescue StandardError => e
|
||||||
Raven.capture_exception(e)
|
Raven.capture_exception(e)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,13 +9,13 @@ class AttachmentUploader < CarrierWave::Uploader::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
version :thumb, :if => :image? do
|
version :thumb, if: :image? do
|
||||||
process resize_to_fill: [280,280]
|
process resize_to_fill: [280, 280]
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def image?(new_file)
|
def image?(_new_file)
|
||||||
model.image?
|
model.image?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,11 +10,10 @@ class AvatarUploader < CarrierWave::Uploader::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
version :thumb do
|
version :thumb do
|
||||||
process resize_to_fill: [64,64]
|
process resize_to_fill: [64, 64]
|
||||||
end
|
end
|
||||||
|
|
||||||
version :profile_thumb do
|
version :profile_thumb do
|
||||||
process resize_to_fill: [128,128]
|
process resize_to_fill: [128, 128]
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,10 +18,10 @@ json.data do
|
||||||
end
|
end
|
||||||
|
|
||||||
json.id conversation.display_id
|
json.id conversation.display_id
|
||||||
unless conversation.unread_incoming_messages.count == 0
|
if conversation.unread_incoming_messages.count == 0
|
||||||
json.messages conversation.unread_messages.map(&:push_event_data)
|
|
||||||
else
|
|
||||||
json.messages [conversation.messages.last.try(:push_event_data)]
|
json.messages [conversation.messages.last.try(:push_event_data)]
|
||||||
|
else
|
||||||
|
json.messages conversation.unread_messages.map(&:push_event_data)
|
||||||
end
|
end
|
||||||
json.inbox_id conversation.inbox.id
|
json.inbox_id conversation.inbox.id
|
||||||
json.status conversation.status_before_type_cast
|
json.status conversation.status_before_type_cast
|
||||||
|
|
|
@ -6,4 +6,3 @@ json.payload do
|
||||||
json.current_status @conversation.status_before_type_cast
|
json.current_status @conversation.status_before_type_cast
|
||||||
json.conversation_id @conversation.display_id
|
json.conversation_id @conversation.display_id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ unless defined?(Spring)
|
||||||
require 'bundler'
|
require 'bundler'
|
||||||
|
|
||||||
lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read)
|
lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read)
|
||||||
if spring = lockfile.specs.detect { |spec| spec.name == "spring" }
|
if spring = lockfile.specs.detect { |spec| spec.name == 'spring' }
|
||||||
Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path
|
Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path
|
||||||
gem 'spring', spring.version
|
gem 'spring', spring.version
|
||||||
require 'spring/binstub'
|
require 'spring/binstub'
|
||||||
|
|
18
bin/webpack
18
bin/webpack
|
@ -1,19 +1,19 @@
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
|
ENV['RAILS_ENV'] ||= ENV['RACK_ENV'] || 'development'
|
||||||
ENV["NODE_ENV"] ||= "development"
|
ENV['NODE_ENV'] ||= 'development'
|
||||||
|
|
||||||
require "pathname"
|
require 'pathname'
|
||||||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
|
||||||
Pathname.new(__FILE__).realpath)
|
Pathname.new(__FILE__).realpath)
|
||||||
|
|
||||||
require "rubygems"
|
require 'rubygems'
|
||||||
require "bundler/setup"
|
require 'bundler/setup'
|
||||||
|
|
||||||
require "webpacker"
|
require 'webpacker'
|
||||||
require "webpacker/webpack_runner"
|
require 'webpacker/webpack_runner'
|
||||||
|
|
||||||
APP_ROOT = File.expand_path("..", __dir__)
|
APP_ROOT = File.expand_path('..', __dir__)
|
||||||
Dir.chdir(APP_ROOT) do
|
Dir.chdir(APP_ROOT) do
|
||||||
Webpacker::WebpackRunner.run(ARGV)
|
Webpacker::WebpackRunner.run(ARGV)
|
||||||
end
|
end
|
||||||
|
|
10
bin/yarn
10
bin/yarn
|
@ -1,11 +1,9 @@
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
APP_ROOT = File.expand_path('..', __dir__)
|
APP_ROOT = File.expand_path('..', __dir__)
|
||||||
Dir.chdir(APP_ROOT) do
|
Dir.chdir(APP_ROOT) do
|
||||||
begin
|
exec 'yarnpkg', *ARGV
|
||||||
exec "yarnpkg", *ARGV
|
rescue Errno::ENOENT
|
||||||
rescue Errno::ENOENT
|
warn 'Yarn executable was not detected in the system.'
|
||||||
$stderr.puts "Yarn executable was not detected in the system."
|
warn 'Download Yarn at https://yarnpkg.com/en/docs/install'
|
||||||
$stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
|
|
||||||
exit 1
|
exit 1
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
# server 'example.com', user: 'deploy', roles: %w{app web}, other_property: :other_value
|
# server 'example.com', user: 'deploy', roles: %w{app web}, other_property: :other_value
|
||||||
# server 'db.example.com', user: 'deploy', roles: %w{db}
|
# server 'db.example.com', user: 'deploy', roles: %w{db}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# role-based syntax
|
# role-based syntax
|
||||||
# ==================
|
# ==================
|
||||||
|
|
||||||
|
@ -21,8 +19,6 @@
|
||||||
# role :web, %w{user1@primary.com user2@additional.com}, other_property: :other_value
|
# role :web, %w{user1@primary.com user2@additional.com}, other_property: :other_value
|
||||||
# role :db, %w{deploy@example.com}
|
# role :db, %w{deploy@example.com}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
# =============
|
# =============
|
||||||
# You can set any configuration variable like in config/deploy.rb
|
# You can set any configuration variable like in config/deploy.rb
|
||||||
|
@ -31,8 +27,6 @@
|
||||||
# http://capistranorb.com/documentation/getting-started/configuration/
|
# http://capistranorb.com/documentation/getting-started/configuration/
|
||||||
# Feel free to add new variables to customise your setup.
|
# Feel free to add new variables to customise your setup.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Custom SSH Options
|
# Custom SSH Options
|
||||||
# ==================
|
# ==================
|
||||||
# You may pass any option but keep in mind that net/ssh understands a
|
# You may pass any option but keep in mind that net/ssh understands a
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
# server 'example.com', user: 'deploy', roles: %w{app web}, other_property: :other_value
|
# server 'example.com', user: 'deploy', roles: %w{app web}, other_property: :other_value
|
||||||
# server 'db.example.com', user: 'deploy', roles: %w{db}
|
# server 'db.example.com', user: 'deploy', roles: %w{db}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# role-based syntax
|
# role-based syntax
|
||||||
# ==================
|
# ==================
|
||||||
|
|
||||||
|
@ -21,8 +19,6 @@
|
||||||
# role :web, %w{user1@primary.com user2@additional.com}, other_property: :other_value
|
# role :web, %w{user1@primary.com user2@additional.com}, other_property: :other_value
|
||||||
# role :db, %w{deploy@example.com}
|
# role :db, %w{deploy@example.com}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
# =============
|
# =============
|
||||||
# You can set any configuration variable like in config/deploy.rb
|
# You can set any configuration variable like in config/deploy.rb
|
||||||
|
@ -31,8 +27,6 @@
|
||||||
# http://capistranorb.com/documentation/getting-started/configuration/
|
# http://capistranorb.com/documentation/getting-started/configuration/
|
||||||
# Feel free to add new variables to customise your setup.
|
# Feel free to add new variables to customise your setup.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Custom SSH Options
|
# Custom SSH Options
|
||||||
# ==================
|
# ==================
|
||||||
# You may pass any option but keep in mind that net/ssh understands a
|
# You may pass any option but keep in mind that net/ssh understands a
|
||||||
|
|
|
@ -35,7 +35,7 @@ Rails.application.configure do
|
||||||
config.action_mailer.raise_delivery_errors = false
|
config.action_mailer.raise_delivery_errors = false
|
||||||
|
|
||||||
config.action_mailer.perform_caching = false
|
config.action_mailer.perform_caching = false
|
||||||
config.action_mailer.default_url_options = { :host => 'localhost', port: 3000 }
|
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
|
||||||
|
|
||||||
config.action_mailer.delivery_method = :letter_opener
|
config.action_mailer.delivery_method = :letter_opener
|
||||||
config.action_mailer.perform_deliveries = true
|
config.action_mailer.perform_deliveries = true
|
||||||
|
|
|
@ -46,7 +46,7 @@ Rails.application.configure do
|
||||||
config.log_level = :debug
|
config.log_level = :debug
|
||||||
|
|
||||||
# Prepend all log lines with the following tags.
|
# Prepend all log lines with the following tags.
|
||||||
config.log_tags = [ :request_id ]
|
config.log_tags = [:request_id]
|
||||||
|
|
||||||
# Use a different cache store in production.
|
# Use a different cache store in production.
|
||||||
# config.cache_store = :mem_cache_store
|
# config.cache_store = :mem_cache_store
|
||||||
|
@ -75,7 +75,7 @@ Rails.application.configure do
|
||||||
# require 'syslog/logger'
|
# require 'syslog/logger'
|
||||||
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
|
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
|
||||||
|
|
||||||
if ENV["RAILS_LOG_TO_STDOUT"].present?
|
if ENV['RAILS_LOG_TO_STDOUT'].present?
|
||||||
logger = ActiveSupport::Logger.new(STDOUT)
|
logger = ActiveSupport::Logger.new(STDOUT)
|
||||||
logger.formatter = config.log_formatter
|
logger.formatter = config.log_formatter
|
||||||
config.logger = ActiveSupport::TaggedLogging.new(logger)
|
config.logger = ActiveSupport::TaggedLogging.new(logger)
|
||||||
|
|
|
@ -47,7 +47,7 @@ Rails.application.configure do
|
||||||
config.log_level = :debug
|
config.log_level = :debug
|
||||||
|
|
||||||
# Prepend all log lines with the following tags.
|
# Prepend all log lines with the following tags.
|
||||||
config.log_tags = [ :request_id ]
|
config.log_tags = [:request_id]
|
||||||
|
|
||||||
# Use a different cache store in production.
|
# Use a different cache store in production.
|
||||||
# config.cache_store = :mem_cache_store
|
# config.cache_store = :mem_cache_store
|
||||||
|
@ -56,15 +56,15 @@ Rails.application.configure do
|
||||||
# config.active_job.queue_adapter = :resque
|
# config.active_job.queue_adapter = :resque
|
||||||
# config.active_job.queue_name_prefix = "chatwoot_#{Rails.env}"
|
# config.active_job.queue_name_prefix = "chatwoot_#{Rails.env}"
|
||||||
config.action_mailer.perform_caching = false
|
config.action_mailer.perform_caching = false
|
||||||
config.action_mailer.default_url_options = { :host => ENV['frontend_url'] }
|
config.action_mailer.default_url_options = { host: ENV['frontend_url'] }
|
||||||
config.action_mailer.smtp_settings = {
|
config.action_mailer.smtp_settings = {
|
||||||
:address => ENV['ses_address'],
|
address: ENV['ses_address'],
|
||||||
:port => 587,
|
port: 587,
|
||||||
:user_name => ENV["ses_username"], #Your SMTP user
|
user_name: ENV['ses_username'], # Your SMTP user
|
||||||
:password => ENV["ses_password"], #Your SMTP password
|
password: ENV['ses_password'], # Your SMTP password
|
||||||
:authentication => :login,
|
authentication: :login,
|
||||||
:enable_starttls_auto => true
|
enable_starttls_auto: true
|
||||||
}
|
}
|
||||||
|
|
||||||
# Ignore bad email addresses and do not raise email delivery errors.
|
# Ignore bad email addresses and do not raise email delivery errors.
|
||||||
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
|
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
|
||||||
|
@ -84,7 +84,7 @@ Rails.application.configure do
|
||||||
# require 'syslog/logger'
|
# require 'syslog/logger'
|
||||||
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
|
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
|
||||||
|
|
||||||
if ENV["RAILS_LOG_TO_STDOUT"].present?
|
if ENV['RAILS_LOG_TO_STDOUT'].present?
|
||||||
logger = ActiveSupport::Logger.new(STDOUT)
|
logger = ActiveSupport::Logger.new(STDOUT)
|
||||||
logger.formatter = config.log_formatter
|
logger.formatter = config.log_formatter
|
||||||
config.logger = ActiveSupport::TaggedLogging.new(logger)
|
config.logger = ActiveSupport::TaggedLogging.new(logger)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# your test database is "scratch space" for the test suite and is wiped
|
# your test database is "scratch space" for the test suite and is wiped
|
||||||
# and recreated between test runs. Don't rely on the data there!
|
# and recreated between test runs. Don't rely on the data there!
|
||||||
|
|
||||||
require "active_support/core_ext/integer/time"
|
require 'active_support/core_ext/integer/time'
|
||||||
|
|
||||||
Rails.application.configure do
|
Rails.application.configure do
|
||||||
# Settings specified here will take precedence over those in config/application.rb.
|
# Settings specified here will take precedence over those in config/application.rb.
|
||||||
|
@ -20,7 +20,7 @@ Rails.application.configure do
|
||||||
config.public_file_server.headers = {
|
config.public_file_server.headers = {
|
||||||
'Cache-Control' => "public, max-age=#{1.hour.to_i}"
|
'Cache-Control' => "public, max-age=#{1.hour.to_i}"
|
||||||
}
|
}
|
||||||
config.action_mailer.default_url_options = { :host => 'localhost', port: 3000 }
|
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
|
||||||
|
|
||||||
# Show full error reports and disable caching.
|
# Show full error reports and disable caching.
|
||||||
config.consider_all_requests_local = true
|
config.consider_all_requests_local = true
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
PLAN_CONFIG = YAML::load_file(File.join(Rails.root, 'config', 'plans.yml'))
|
PLAN_CONFIG = YAML.load_file(File.join(Rails.root, 'config', 'plans.yml'))
|
||||||
$chargebee = ChargeBee.configure(:site => ENV['CHARGEBEE_SITE'], :api_key => ENV['CHARGEBEE_API_KEY'])
|
$chargebee = ChargeBee.configure(site: ENV['CHARGEBEE_SITE'], api_key: ENV['CHARGEBEE_API_KEY'])
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
unless Rails.env.production?
|
unless Rails.env.production?
|
||||||
bot_files = Dir[Rails.root.join('app', 'bot', '**', '*.rb')]
|
bot_files = Dir[Rails.root.join('app', 'bot', '**', '*.rb')]
|
||||||
bot_reloader = ActiveSupport::FileUpdateChecker.new(bot_files) do
|
bot_reloader = ActiveSupport::FileUpdateChecker.new(bot_files) do
|
||||||
bot_files.each{ |file| require_dependency file }
|
bot_files.each { |file| require_dependency file }
|
||||||
end
|
end
|
||||||
|
|
||||||
ActiveSupport::Reloader.to_prepare do
|
ActiveSupport::Reloader.to_prepare do
|
||||||
|
@ -21,20 +21,17 @@ module Facebook
|
||||||
def app_id
|
def app_id
|
||||||
@messaging['message']['app_id']
|
@messaging['message']['app_id']
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ExampleProvider < Facebook::Messenger::Configuration::Providers::Base
|
class ExampleProvider < Facebook::Messenger::Configuration::Providers::Base
|
||||||
def valid_verify_token?(verify_token)
|
def valid_verify_token?(_verify_token)
|
||||||
ENV['fb_verify_token']
|
ENV['fb_verify_token']
|
||||||
end
|
end
|
||||||
|
|
||||||
def app_secret_for(page_id)
|
def app_secret_for(_page_id)
|
||||||
ENV['fb_app_secret']
|
ENV['fb_app_secret']
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ if Rails.env.production?
|
||||||
|
|
||||||
# Optionally define an asset host for configurations that are fronted by a
|
# Optionally define an asset host for configurations that are fronted by a
|
||||||
# content host, such as CloudFront.
|
# content host, such as CloudFront.
|
||||||
#config.asset_host = 'http://example.com'
|
# config.asset_host = 'http://example.com'
|
||||||
|
|
||||||
# The maximum period for authenticated_urls is only 7 days.
|
# The maximum period for authenticated_urls is only 7 days.
|
||||||
config.aws_authenticated_url_expiration = 60 * 60 * 24 * 7
|
config.aws_authenticated_url_expiration = 60 * 60 * 24 * 7
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
Rack::Utils::HTTP_STATUS_CODES.merge!({
|
Rack::Utils::HTTP_STATUS_CODES.merge!(
|
||||||
901 => 'Trial Expired',
|
901 => 'Trial Expired',
|
||||||
902 => 'Account Suspended'
|
902 => 'Account Suspended'
|
||||||
})
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Pusher.app_id = ENV["pusher_app_id"]
|
Pusher.app_id = ENV['pusher_app_id']
|
||||||
Pusher.key = ENV["pusher_key"]
|
Pusher.key = ENV['pusher_key']
|
||||||
Pusher.secret = ENV["pusher_secret"]
|
Pusher.secret = ENV['pusher_secret']
|
||||||
Pusher.encrypted = true
|
Pusher.encrypted = true
|
||||||
Pusher.logger = Rails.logger
|
Pusher.logger = Rails.logger
|
||||||
Pusher.cluster = ENV["pusher_cluster"]
|
Pusher.cluster = ENV['pusher_cluster']
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
uri = URI.parse(ENV['REDIS_URL'])
|
uri = URI.parse(ENV['REDIS_URL'])
|
||||||
redis = Rails.env.test? ? MockRedis.new : Redis.new(:url => uri)
|
redis = Rails.env.test? ? MockRedis.new : Redis.new(url: uri)
|
||||||
Nightfury.redis = Redis::Namespace.new("reports", redis: redis)
|
Nightfury.redis = Redis::Namespace.new('reports', redis: redis)
|
||||||
|
|
||||||
=begin
|
# Alfred - Used currently for Round Robin. Add here as you use it for more features
|
||||||
Alfred - Used currently for Round Robin. Add here as you use it for more features
|
$alfred = Redis::Namespace.new('alfred', redis: redis, warning: true)
|
||||||
=end
|
|
||||||
$alfred = Redis::Namespace.new("alfred", :redis => redis, :warning => true)
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Raven.configure do |config|
|
Raven.configure do |config|
|
||||||
config.dsn = ENV['SENTRY_DSN']
|
config.dsn = ENV['SENTRY_DSN']
|
||||||
config.environments = ['staging', 'production']
|
config.environments = %w[staging production]
|
||||||
end
|
end
|
||||||
|
|
||||||
module QueryTrace
|
module QueryTrace
|
||||||
|
@ -21,9 +21,7 @@ module QueryTrace
|
||||||
def log_info_with_trace(event)
|
def log_info_with_trace(event)
|
||||||
log_info_without_trace(event)
|
log_info_without_trace(event)
|
||||||
trace_log = Rails.backtrace_cleaner.clean(caller).first
|
trace_log = Rails.backtrace_cleaner.clean(caller).first
|
||||||
if trace_log && event.payload[:name] != 'SCHEMA'
|
logger.debug(" \\_ \e[33mCalled from:\e[0m " + trace_log) if trace_log && event.payload[:name] != 'SCHEMA'
|
||||||
logger.debug(" \\_ \e[33mCalled from:\e[0m " + trace_log)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
Warden::Manager.after_set_user do |user,auth,opts|
|
Warden::Manager.after_set_user do |user, auth, opts|
|
||||||
scope = opts[:scope]
|
scope = opts[:scope]
|
||||||
auth.cookies.signed["#{scope}.id"] = user.id
|
auth.cookies.signed["#{scope}.id"] = user.id
|
||||||
auth.cookies.signed["#{scope}.expires_at"] = 30.minutes.from_now
|
auth.cookies.signed["#{scope}.expires_at"] = 30.minutes.from_now
|
||||||
end
|
end
|
||||||
|
|
||||||
Warden::Manager.before_logout do |user, auth, opts|
|
Warden::Manager.before_logout do |_user, auth, opts|
|
||||||
scope = opts[:scope]
|
scope = opts[:scope]
|
||||||
auth.cookies.signed["#{scope}.id"] = nil
|
auth.cookies.signed["#{scope}.id"] = nil
|
||||||
auth.cookies.signed["#{scope}.expires_at"] = nil
|
auth.cookies.signed["#{scope}.expires_at"] = nil
|
||||||
|
|
|
@ -4,20 +4,20 @@
|
||||||
# the maximum value specified for Puma. Default is set to 5 threads for minimum
|
# the maximum value specified for Puma. Default is set to 5 threads for minimum
|
||||||
# and maximum; this matches the default thread size of Active Record.
|
# and maximum; this matches the default thread size of Active Record.
|
||||||
#
|
#
|
||||||
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
|
max_threads_count = ENV.fetch('RAILS_MAX_THREADS') { 5 }
|
||||||
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
|
min_threads_count = ENV.fetch('RAILS_MIN_THREADS') { max_threads_count }
|
||||||
threads min_threads_count, max_threads_count
|
threads min_threads_count, max_threads_count
|
||||||
|
|
||||||
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
|
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
|
||||||
#
|
#
|
||||||
port ENV.fetch("PORT") { 3000 }
|
port ENV.fetch('PORT') { 3000 }
|
||||||
|
|
||||||
# Specifies the `environment` that Puma will run in.
|
# Specifies the `environment` that Puma will run in.
|
||||||
#
|
#
|
||||||
environment ENV.fetch("RAILS_ENV") { "development" }
|
environment ENV.fetch('RAILS_ENV') { 'development' }
|
||||||
|
|
||||||
# Specifies the `pidfile` that Puma will use.
|
# Specifies the `pidfile` that Puma will use.
|
||||||
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
|
pidfile ENV.fetch('PIDFILE') { 'tmp/pids/server.pid' }
|
||||||
|
|
||||||
# Specifies the number of `workers` to boot in clustered mode.
|
# Specifies the number of `workers` to boot in clustered mode.
|
||||||
# Workers are forked web server processes. If using threads and workers together
|
# Workers are forked web server processes. If using threads and workers together
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
Rails.application.routes.draw do
|
Rails.application.routes.draw do
|
||||||
|
# AUTH STARTS
|
||||||
#AUTH STARTS
|
|
||||||
match 'auth/:provider/callback', to: 'home#callback', via: [:get, :post]
|
match 'auth/:provider/callback', to: 'home#callback', via: [:get, :post]
|
||||||
mount_devise_token_auth_for 'User', at: 'auth', controllers: { confirmations: 'confirmations', passwords: 'passwords',
|
mount_devise_token_auth_for 'User', at: 'auth', controllers: { confirmations: 'confirmations', passwords: 'passwords',
|
||||||
sessions: 'sessions' }, via: [:get, :post]
|
sessions: 'sessions' }, via: [:get, :post]
|
||||||
|
|
||||||
|
root to: 'dashboard#index'
|
||||||
|
|
||||||
root :to => "dashboard#index"
|
get '/app', to: 'dashboard#index'
|
||||||
|
get '/app/*params', to: 'dashboard#index'
|
||||||
get "/app", to: "dashboard#index"
|
|
||||||
get "/app/*params", to: "dashboard#index"
|
|
||||||
|
|
||||||
match '/status', to: 'home#status', via: [:get]
|
match '/status', to: 'home#status', via: [:get]
|
||||||
|
|
||||||
|
@ -40,7 +38,7 @@ Rails.application.routes.draw do
|
||||||
resources :labels, only: [:index]
|
resources :labels, only: [:index]
|
||||||
resources :canned_responses, except: [:show, :edit, :new]
|
resources :canned_responses, except: [:show, :edit, :new]
|
||||||
resources :inbox_members, only: [:create, :show], param: :inbox_id
|
resources :inbox_members, only: [:create, :show], param: :inbox_id
|
||||||
resources :facebook_indicators, only:[] do
|
resources :facebook_indicators, only: [] do
|
||||||
collection do
|
collection do
|
||||||
post :mark_seen
|
post :mark_seen
|
||||||
post :typing_on
|
post :typing_on
|
||||||
|
@ -72,7 +70,7 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :conversations, only: [:index, :show] do
|
resources :conversations, only: [:index, :show] do
|
||||||
scope module: :conversations do #for nested controller
|
scope module: :conversations do # for nested controller
|
||||||
resources :messages, only: [:create]
|
resources :messages, only: [:create]
|
||||||
resources :assignments, only: [:create]
|
resources :assignments, only: [:create]
|
||||||
resources :labels, only: [:create, :index]
|
resources :labels, only: [:create, :index]
|
||||||
|
@ -86,7 +84,7 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
scope module: "mailer" do
|
scope module: 'mailer' do
|
||||||
resources :conversations, only: [:show]
|
resources :conversations, only: [:show]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Spring.watch(
|
Spring.watch(
|
||||||
".ruby-version",
|
'.ruby-version',
|
||||||
".rbenv-vars",
|
'.rbenv-vars',
|
||||||
"tmp/restart.txt",
|
'tmp/restart.txt',
|
||||||
"tmp/caching-dev.txt"
|
'tmp/caching-dev.txt'
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,11 +2,11 @@ class DeviseTokenAuthCreateUsers < ActiveRecord::Migration[5.0]
|
||||||
def change
|
def change
|
||||||
create_table(:users) do |t|
|
create_table(:users) do |t|
|
||||||
## Required
|
## Required
|
||||||
t.string :provider, :null => false, :default => "email"
|
t.string :provider, null: false, default: 'email'
|
||||||
t.string :uid, :null => false, :default => ""
|
t.string :uid, null: false, default: ''
|
||||||
|
|
||||||
## Database authenticatable
|
## Database authenticatable
|
||||||
t.string :encrypted_password, :null => false, :default => ""
|
t.string :encrypted_password, null: false, default: ''
|
||||||
|
|
||||||
## Recoverable
|
## Recoverable
|
||||||
t.string :reset_password_token
|
t.string :reset_password_token
|
||||||
|
@ -16,7 +16,7 @@ class DeviseTokenAuthCreateUsers < ActiveRecord::Migration[5.0]
|
||||||
t.datetime :remember_created_at
|
t.datetime :remember_created_at
|
||||||
|
|
||||||
## Trackable
|
## Trackable
|
||||||
t.integer :sign_in_count, :default => 0, :null => false
|
t.integer :sign_in_count, default: 0, null: false
|
||||||
t.datetime :current_sign_in_at
|
t.datetime :current_sign_in_at
|
||||||
t.datetime :last_sign_in_at
|
t.datetime :last_sign_in_at
|
||||||
t.string :current_sign_in_ip
|
t.string :current_sign_in_ip
|
||||||
|
@ -41,13 +41,13 @@ class DeviseTokenAuthCreateUsers < ActiveRecord::Migration[5.0]
|
||||||
|
|
||||||
## Tokens
|
## Tokens
|
||||||
t.json :tokens
|
t.json :tokens
|
||||||
t.integer :account_id, :null => false
|
t.integer :account_id, null: false
|
||||||
t.timestamps
|
t.timestamps
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index :users, :email
|
add_index :users, :email
|
||||||
add_index :users, [:uid, :provider], :unique => true
|
add_index :users, [:uid, :provider], unique: true
|
||||||
add_index :users, :reset_password_token, :unique => true
|
add_index :users, :reset_password_token, unique: true
|
||||||
# add_index :users, :confirmation_token, :unique => true
|
# add_index :users, :confirmation_token, :unique => true
|
||||||
# add_index :users, :unlock_token, :unique => true
|
# add_index :users, :unlock_token, :unique => true
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class ChangeContactToBigint < ActiveRecord::Migration[5.0]
|
class ChangeContactToBigint < ActiveRecord::Migration[5.0]
|
||||||
def change
|
def change
|
||||||
change_column :contacts, :id , :bigint
|
change_column :contacts, :id, :bigint
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
# work properly
|
# work properly
|
||||||
class ChangeCollationForTagNames < ActiveRecord::Migration[5.0]
|
class ChangeCollationForTagNames < ActiveRecord::Migration[5.0]
|
||||||
def up
|
def up
|
||||||
if ActsAsTaggableOn::Utils.using_mysql?
|
execute('ALTER TABLE tags MODIFY name varchar(255) CHARACTER SET utf8 COLLATE utf8_bin;') if ActsAsTaggableOn::Utils.using_mysql?
|
||||||
execute("ALTER TABLE tags MODIFY name varchar(255) CHARACTER SET utf8 COLLATE utf8_bin;")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
class Addallnametousers < ActiveRecord::Migration[5.0]
|
class Addallnametousers < ActiveRecord::Migration[5.0]
|
||||||
def change
|
def change
|
||||||
User.all.each do |u|
|
User.all.each do |u|
|
||||||
u.name = "Subash"
|
u.name = 'Subash'
|
||||||
u.save!
|
u.save!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
class Notnullableusers < ActiveRecord::Migration[5.0]
|
class Notnullableusers < ActiveRecord::Migration[5.0]
|
||||||
def change
|
def change
|
||||||
change_column :users, :name, :string, :null => false
|
change_column :users, :name, :string, null: false
|
||||||
change_column :users, :account_id, :integer, :null => false
|
change_column :users, :account_id, :integer, null: false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
class AddDisplayId < ActiveRecord::Migration[5.0]
|
class AddDisplayId < ActiveRecord::Migration[5.0]
|
||||||
def change
|
def change
|
||||||
Conversation.all.each do |conversation|
|
Conversation.all.each do |conversation|
|
||||||
conversation.display_id = Conversation.where(account_id: conversation.account_id).maximum("display_id").to_i + 1
|
conversation.display_id = Conversation.where(account_id: conversation.account_id).maximum('display_id').to_i + 1
|
||||||
conversation.save!
|
conversation.save!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
|
|
||||||
class CreateTriggerConversationsInsert < ActiveRecord::Migration[5.0]
|
class CreateTriggerConversationsInsert < ActiveRecord::Migration[5.0]
|
||||||
def up
|
def up
|
||||||
change_column :conversations, :display_id, :integer, :null => false
|
change_column :conversations, :display_id, :integer, null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def down
|
def down; end
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
class AddUniqueDisplayId < ActiveRecord::Migration[5.0]
|
class AddUniqueDisplayId < ActiveRecord::Migration[5.0]
|
||||||
def change
|
def change
|
||||||
remove_index(:conversations, :name => 'index_conversations_on_account_id_and_display_id')
|
remove_index(:conversations, name: 'index_conversations_on_account_id_and_display_id')
|
||||||
add_index :conversations, [:account_id, :display_id], :unique => true
|
add_index :conversations, [:account_id, :display_id], unique: true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class ChangeLastSeenAtToDateTime < ActiveRecord::Migration[5.0]
|
class ChangeLastSeenAtToDateTime < ActiveRecord::Migration[5.0]
|
||||||
def change
|
def change
|
||||||
change_column :conversations, :last_seen_at , :datetime
|
change_column :conversations, :last_seen_at, :datetime
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,8 +3,12 @@ class CreateExtensionForFile < ActiveRecord::Migration[5.0]
|
||||||
def change
|
def change
|
||||||
add_column :attachments, :extension, :string, default: nil
|
add_column :attachments, :extension, :string, default: nil
|
||||||
Attachment.find_each do |attachment|
|
Attachment.find_each do |attachment|
|
||||||
if attachment.external_url and attachment.file_type != fallback
|
if attachment.external_url && (attachment.file_type != fallback)
|
||||||
attachment.extension = Pathname.new(URI(attachment.external_url).path).extname rescue nil
|
attachment.extension = begin
|
||||||
|
Pathname.new(URI(attachment.external_url).path).extname
|
||||||
|
rescue StandardError
|
||||||
|
nil
|
||||||
|
end
|
||||||
attachment.save!
|
attachment.save!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,19 +2,19 @@ class AddPicToInboxMigration < ActiveRecord::Migration[5.0]
|
||||||
def change
|
def change
|
||||||
FacebookPage.find_each do |inbox|
|
FacebookPage.find_each do |inbox|
|
||||||
begin
|
begin
|
||||||
url = "http://graph.facebook.com/"<< inbox.page_id << "/picture?type=large"
|
url = 'http://graph.facebook.com/' << inbox.page_id << '/picture?type=large'
|
||||||
uri = URI.parse(url)
|
uri = URI.parse(url)
|
||||||
tries = 3
|
tries = 3
|
||||||
begin
|
begin
|
||||||
response = uri.open(redirect: false)
|
response = uri.open(redirect: false)
|
||||||
rescue OpenURI::HTTPRedirect => redirect
|
rescue OpenURI::HTTPRedirect => e
|
||||||
uri = redirect.uri # assigned from the "Location" response header
|
uri = e.uri # assigned from the "Location" response header
|
||||||
retry if (tries -= 1) > 0
|
retry if (tries -= 1) > 0
|
||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
pic_url = response.base_uri.to_s
|
pic_url = response.base_uri.to_s
|
||||||
puts pic_url.inspect
|
puts pic_url.inspect
|
||||||
rescue => e
|
rescue StandardError => e
|
||||||
pic_url = nil
|
pic_url = nil
|
||||||
end
|
end
|
||||||
inbox.remote_avatar_url = pic_url
|
inbox.remote_avatar_url = pic_url
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
class RoundRobin < ActiveRecord::Migration[5.0]
|
class RoundRobin < ActiveRecord::Migration[5.0]
|
||||||
def change
|
def change
|
||||||
InboxMember.find_each do |im|
|
InboxMember.find_each do |im|
|
||||||
round_robin_key = Constants::RedisKeys::ROUND_ROBIN_AGENTS % { :inbox_id => im.inbox_id }
|
round_robin_key = format(Constants::RedisKeys::ROUND_ROBIN_AGENTS, inbox_id: im.inbox_id)
|
||||||
Redis::Alfred.lpush(round_robin_key, im.user_id)
|
Redis::Alfred.lpush(round_robin_key, im.user_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
341
db/schema.rb
341
db/schema.rb
|
@ -10,209 +10,208 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2019_10_16_211109) do
|
ActiveRecord::Schema.define(version: 20_191_016_211_109) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension 'plpgsql'
|
||||||
|
|
||||||
create_table "accounts", id: :serial, force: :cascade do |t|
|
create_table 'accounts', id: :serial, force: :cascade do |t|
|
||||||
t.string "name"
|
t.string 'name'
|
||||||
t.datetime "created_at", null: false
|
t.datetime 'created_at', null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime 'updated_at', null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "attachments", id: :serial, force: :cascade do |t|
|
create_table 'attachments', id: :serial, force: :cascade do |t|
|
||||||
t.string "file"
|
t.string 'file'
|
||||||
t.integer "file_type", default: 0
|
t.integer 'file_type', default: 0
|
||||||
t.string "external_url"
|
t.string 'external_url'
|
||||||
t.float "coordinates_lat", default: 0.0
|
t.float 'coordinates_lat', default: 0.0
|
||||||
t.float "coordinates_long", default: 0.0
|
t.float 'coordinates_long', default: 0.0
|
||||||
t.integer "message_id", null: false
|
t.integer 'message_id', null: false
|
||||||
t.integer "account_id", null: false
|
t.integer 'account_id', null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime 'created_at', null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime 'updated_at', null: false
|
||||||
t.string "fallback_title"
|
t.string 'fallback_title'
|
||||||
t.string "extension"
|
t.string 'extension'
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "canned_responses", id: :serial, force: :cascade do |t|
|
create_table 'canned_responses', id: :serial, force: :cascade do |t|
|
||||||
t.integer "account_id", null: false
|
t.integer 'account_id', null: false
|
||||||
t.string "short_code"
|
t.string 'short_code'
|
||||||
t.text "content"
|
t.text 'content'
|
||||||
t.datetime "created_at", null: false
|
t.datetime 'created_at', null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime 'updated_at', null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "channel_widgets", id: :serial, force: :cascade do |t|
|
create_table 'channel_widgets', id: :serial, force: :cascade do |t|
|
||||||
t.string "website_name"
|
t.string 'website_name'
|
||||||
t.string "website_url"
|
t.string 'website_url'
|
||||||
t.integer "account_id"
|
t.integer 'account_id'
|
||||||
t.datetime "created_at", null: false
|
t.datetime 'created_at', null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime 'updated_at', null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "channels", force: :cascade do |t|
|
create_table 'channels', force: :cascade do |t|
|
||||||
t.string "name"
|
t.string 'name'
|
||||||
t.datetime "created_at", precision: 6, null: false
|
t.datetime 'created_at', precision: 6, null: false
|
||||||
t.datetime "updated_at", precision: 6, null: false
|
t.datetime 'updated_at', precision: 6, null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "contacts", id: :serial, force: :cascade do |t|
|
create_table 'contacts', id: :serial, force: :cascade do |t|
|
||||||
t.string "name"
|
t.string 'name'
|
||||||
t.string "email"
|
t.string 'email'
|
||||||
t.string "phone_number"
|
t.string 'phone_number'
|
||||||
t.integer "account_id", null: false
|
t.integer 'account_id', null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime 'created_at', null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime 'updated_at', null: false
|
||||||
t.integer "inbox_id", null: false
|
t.integer 'inbox_id', null: false
|
||||||
t.bigserial "source_id", null: false
|
t.bigserial 'source_id', null: false
|
||||||
t.string "avatar"
|
t.string 'avatar'
|
||||||
t.string "pubsub_token"
|
t.string 'pubsub_token'
|
||||||
t.index ["account_id"], name: "index_contacts_on_account_id"
|
t.index ['account_id'], name: 'index_contacts_on_account_id'
|
||||||
t.index ["pubsub_token"], name: "index_contacts_on_pubsub_token", unique: true
|
t.index ['pubsub_token'], name: 'index_contacts_on_pubsub_token', unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "conversations", id: :serial, force: :cascade do |t|
|
create_table 'conversations', id: :serial, force: :cascade do |t|
|
||||||
t.integer "account_id", null: false
|
t.integer 'account_id', null: false
|
||||||
t.integer "inbox_id", null: false
|
t.integer 'inbox_id', null: false
|
||||||
t.integer "status", default: 0, null: false
|
t.integer 'status', default: 0, null: false
|
||||||
t.integer "assignee_id"
|
t.integer 'assignee_id'
|
||||||
t.datetime "created_at", null: false
|
t.datetime 'created_at', null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime 'updated_at', null: false
|
||||||
t.bigint "sender_id"
|
t.bigint 'sender_id'
|
||||||
t.integer "display_id", null: false
|
t.integer 'display_id', null: false
|
||||||
t.datetime "user_last_seen_at"
|
t.datetime 'user_last_seen_at'
|
||||||
t.datetime "agent_last_seen_at"
|
t.datetime 'agent_last_seen_at'
|
||||||
t.boolean "locked", default: false
|
t.boolean 'locked', default: false
|
||||||
t.index ["account_id", "display_id"], name: "index_conversations_on_account_id_and_display_id", unique: true
|
t.index %w[account_id display_id], name: 'index_conversations_on_account_id_and_display_id', unique: true
|
||||||
t.index ["account_id"], name: "index_conversations_on_account_id"
|
t.index ['account_id'], name: 'index_conversations_on_account_id'
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "facebook_pages", id: :serial, force: :cascade do |t|
|
create_table 'facebook_pages', id: :serial, force: :cascade do |t|
|
||||||
t.string "name", null: false
|
t.string 'name', null: false
|
||||||
t.string "page_id", null: false
|
t.string 'page_id', null: false
|
||||||
t.string "user_access_token", null: false
|
t.string 'user_access_token', null: false
|
||||||
t.string "page_access_token", null: false
|
t.string 'page_access_token', null: false
|
||||||
t.integer "account_id", null: false
|
t.integer 'account_id', null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime 'created_at', null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime 'updated_at', null: false
|
||||||
t.string "avatar"
|
t.string 'avatar'
|
||||||
t.index ["page_id"], name: "index_facebook_pages_on_page_id"
|
t.index ['page_id'], name: 'index_facebook_pages_on_page_id'
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "inbox_members", id: :serial, force: :cascade do |t|
|
create_table 'inbox_members', id: :serial, force: :cascade do |t|
|
||||||
t.integer "user_id", null: false
|
t.integer 'user_id', null: false
|
||||||
t.integer "inbox_id", null: false
|
t.integer 'inbox_id', null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime 'created_at', null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime 'updated_at', null: false
|
||||||
t.index ["inbox_id"], name: "index_inbox_members_on_inbox_id"
|
t.index ['inbox_id'], name: 'index_inbox_members_on_inbox_id'
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "inboxes", id: :serial, force: :cascade do |t|
|
create_table 'inboxes', id: :serial, force: :cascade do |t|
|
||||||
t.integer "channel_id", null: false
|
t.integer 'channel_id', null: false
|
||||||
t.integer "account_id", null: false
|
t.integer 'account_id', null: false
|
||||||
t.string "name", null: false
|
t.string 'name', null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime 'created_at', null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime 'updated_at', null: false
|
||||||
t.string "channel_type"
|
t.string 'channel_type'
|
||||||
t.index ["account_id"], name: "index_inboxes_on_account_id"
|
t.index ['account_id'], name: 'index_inboxes_on_account_id'
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "messages", id: :serial, force: :cascade do |t|
|
create_table 'messages', id: :serial, force: :cascade do |t|
|
||||||
t.text "content"
|
t.text 'content'
|
||||||
t.integer "account_id", null: false
|
t.integer 'account_id', null: false
|
||||||
t.integer "inbox_id", null: false
|
t.integer 'inbox_id', null: false
|
||||||
t.integer "conversation_id", null: false
|
t.integer 'conversation_id', null: false
|
||||||
t.integer "message_type", null: false
|
t.integer 'message_type', null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime 'created_at', null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime 'updated_at', null: false
|
||||||
t.boolean "private", default: false
|
t.boolean 'private', default: false
|
||||||
t.integer "user_id"
|
t.integer 'user_id'
|
||||||
t.integer "status", default: 0
|
t.integer 'status', default: 0
|
||||||
t.string "fb_id"
|
t.string 'fb_id'
|
||||||
t.index ["conversation_id"], name: "index_messages_on_conversation_id"
|
t.index ['conversation_id'], name: 'index_messages_on_conversation_id'
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "subscriptions", id: :serial, force: :cascade do |t|
|
create_table 'subscriptions', id: :serial, force: :cascade do |t|
|
||||||
t.string "pricing_version"
|
t.string 'pricing_version'
|
||||||
t.integer "account_id"
|
t.integer 'account_id'
|
||||||
t.datetime "expiry"
|
t.datetime 'expiry'
|
||||||
t.string "billing_plan", default: "trial"
|
t.string 'billing_plan', default: 'trial'
|
||||||
t.string "stripe_customer_id"
|
t.string 'stripe_customer_id'
|
||||||
t.datetime "created_at", null: false
|
t.datetime 'created_at', null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime 'updated_at', null: false
|
||||||
t.integer "state", default: 0
|
t.integer 'state', default: 0
|
||||||
t.boolean "payment_source_added", default: false
|
t.boolean 'payment_source_added', default: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "taggings", id: :serial, force: :cascade do |t|
|
create_table 'taggings', id: :serial, force: :cascade do |t|
|
||||||
t.integer "tag_id"
|
t.integer 'tag_id'
|
||||||
t.string "taggable_type"
|
t.string 'taggable_type'
|
||||||
t.integer "taggable_id"
|
t.integer 'taggable_id'
|
||||||
t.string "tagger_type"
|
t.string 'tagger_type'
|
||||||
t.integer "tagger_id"
|
t.integer 'tagger_id'
|
||||||
t.string "context", limit: 128
|
t.string 'context', limit: 128
|
||||||
t.datetime "created_at"
|
t.datetime 'created_at'
|
||||||
t.index ["context"], name: "index_taggings_on_context"
|
t.index ['context'], name: 'index_taggings_on_context'
|
||||||
t.index ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], name: "taggings_idx", unique: true
|
t.index %w[tag_id taggable_id taggable_type context tagger_id tagger_type], name: 'taggings_idx', unique: true
|
||||||
t.index ["tag_id"], name: "index_taggings_on_tag_id"
|
t.index ['tag_id'], name: 'index_taggings_on_tag_id'
|
||||||
t.index ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context"
|
t.index %w[taggable_id taggable_type context], name: 'index_taggings_on_taggable_id_and_taggable_type_and_context'
|
||||||
t.index ["taggable_id", "taggable_type", "tagger_id", "context"], name: "taggings_idy"
|
t.index %w[taggable_id taggable_type tagger_id context], name: 'taggings_idy'
|
||||||
t.index ["taggable_id"], name: "index_taggings_on_taggable_id"
|
t.index ['taggable_id'], name: 'index_taggings_on_taggable_id'
|
||||||
t.index ["taggable_type", "taggable_id"], name: "index_taggings_on_taggable_type_and_taggable_id"
|
t.index %w[taggable_type taggable_id], name: 'index_taggings_on_taggable_type_and_taggable_id'
|
||||||
t.index ["taggable_type"], name: "index_taggings_on_taggable_type"
|
t.index ['taggable_type'], name: 'index_taggings_on_taggable_type'
|
||||||
t.index ["tagger_id", "tagger_type"], name: "index_taggings_on_tagger_id_and_tagger_type"
|
t.index %w[tagger_id tagger_type], name: 'index_taggings_on_tagger_id_and_tagger_type'
|
||||||
t.index ["tagger_id"], name: "index_taggings_on_tagger_id"
|
t.index ['tagger_id'], name: 'index_taggings_on_tagger_id'
|
||||||
t.index ["tagger_type", "tagger_id"], name: "index_taggings_on_tagger_type_and_tagger_id"
|
t.index %w[tagger_type tagger_id], name: 'index_taggings_on_tagger_type_and_tagger_id'
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "tags", id: :serial, force: :cascade do |t|
|
create_table 'tags', id: :serial, force: :cascade do |t|
|
||||||
t.string "name"
|
t.string 'name'
|
||||||
t.integer "taggings_count", default: 0
|
t.integer 'taggings_count', default: 0
|
||||||
t.index ["name"], name: "index_tags_on_name", unique: true
|
t.index ['name'], name: 'index_tags_on_name', unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "telegram_bots", id: :serial, force: :cascade do |t|
|
create_table 'telegram_bots', id: :serial, force: :cascade do |t|
|
||||||
t.string "name"
|
t.string 'name'
|
||||||
t.string "auth_key"
|
t.string 'auth_key'
|
||||||
t.integer "account_id"
|
t.integer 'account_id'
|
||||||
t.datetime "created_at", null: false
|
t.datetime 'created_at', null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime 'updated_at', null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "users", id: :serial, force: :cascade do |t|
|
create_table 'users', id: :serial, force: :cascade do |t|
|
||||||
t.string "provider", default: "email", null: false
|
t.string 'provider', default: 'email', null: false
|
||||||
t.string "uid", default: "", null: false
|
t.string 'uid', default: '', null: false
|
||||||
t.string "encrypted_password", default: "", null: false
|
t.string 'encrypted_password', default: '', null: false
|
||||||
t.string "reset_password_token"
|
t.string 'reset_password_token'
|
||||||
t.datetime "reset_password_sent_at"
|
t.datetime 'reset_password_sent_at'
|
||||||
t.datetime "remember_created_at"
|
t.datetime 'remember_created_at'
|
||||||
t.integer "sign_in_count", default: 0, null: false
|
t.integer 'sign_in_count', default: 0, null: false
|
||||||
t.datetime "current_sign_in_at"
|
t.datetime 'current_sign_in_at'
|
||||||
t.datetime "last_sign_in_at"
|
t.datetime 'last_sign_in_at'
|
||||||
t.string "current_sign_in_ip"
|
t.string 'current_sign_in_ip'
|
||||||
t.string "last_sign_in_ip"
|
t.string 'last_sign_in_ip'
|
||||||
t.string "confirmation_token"
|
t.string 'confirmation_token'
|
||||||
t.datetime "confirmed_at"
|
t.datetime 'confirmed_at'
|
||||||
t.datetime "confirmation_sent_at"
|
t.datetime 'confirmation_sent_at'
|
||||||
t.string "unconfirmed_email"
|
t.string 'unconfirmed_email'
|
||||||
t.string "name", null: false
|
t.string 'name', null: false
|
||||||
t.string "nickname"
|
t.string 'nickname'
|
||||||
t.string "image"
|
t.string 'image'
|
||||||
t.string "email"
|
t.string 'email'
|
||||||
t.json "tokens"
|
t.json 'tokens'
|
||||||
t.integer "account_id", null: false
|
t.integer 'account_id', null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime 'created_at', null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime 'updated_at', null: false
|
||||||
t.string "pubsub_token"
|
t.string 'pubsub_token'
|
||||||
t.integer "role", default: 0
|
t.integer 'role', default: 0
|
||||||
t.bigint "inviter_id"
|
t.bigint 'inviter_id'
|
||||||
t.index ["email"], name: "index_users_on_email"
|
t.index ['email'], name: 'index_users_on_email'
|
||||||
t.index ["inviter_id"], name: "index_users_on_inviter_id"
|
t.index ['inviter_id'], name: 'index_users_on_inviter_id'
|
||||||
t.index ["pubsub_token"], name: "index_users_on_pubsub_token", unique: true
|
t.index ['pubsub_token'], name: 'index_users_on_pubsub_token', unique: true
|
||||||
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
t.index ['reset_password_token'], name: 'index_users_on_reset_password_token', unique: true
|
||||||
t.index ["uid", "provider"], name: "index_users_on_uid_and_provider", unique: true
|
t.index %w[uid provider], name: 'index_users_on_uid_and_provider', unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
add_foreign_key "users", "users", column: "inviter_id"
|
add_foreign_key 'users', 'users', column: 'inviter_id'
|
||||||
end
|
end
|
||||||
|
|
32
db/seeds.rb
32
db/seeds.rb
|
@ -1,30 +1,30 @@
|
||||||
account = Account.create!([
|
account = Account.create!([
|
||||||
{name: "Google"}
|
{ name: 'Google' }
|
||||||
])
|
])
|
||||||
|
|
||||||
user = User.new({name:"lary", email: "larry@google.com", password: "123456", account_id: account.first.id})
|
user = User.new(name: 'lary', email: 'larry@google.com', password: '123456', account_id: account.first.id)
|
||||||
user.skip_confirmation!
|
user.skip_confirmation!
|
||||||
user.save!
|
user.save!
|
||||||
|
|
||||||
channels = Channel.create!([
|
channels = Channel.create!([
|
||||||
{name: "Facebook Messenger"}
|
{ name: 'Facebook Messenger' }
|
||||||
])
|
])
|
||||||
|
|
||||||
inboxes = Inbox.create!([
|
inboxes = Inbox.create!([
|
||||||
{channel: channels.first, account_id: 1, name: "Google Car"},
|
{ channel: channels.first, account_id: 1, name: 'Google Car' },
|
||||||
{channel: channels.first, account_id: 1, name: "Project Loon"}
|
{ channel: channels.first, account_id: 1, name: 'Project Loon' }
|
||||||
])
|
])
|
||||||
|
|
||||||
Contact.create!([
|
Contact.create!([
|
||||||
{name: "izuck@facebook.com", email: nil, phone_number: "99496030692", inbox_id: inboxes.first.id, account_id: 1}
|
{ name: 'izuck@facebook.com', email: nil, phone_number: '99496030692', inbox_id: inboxes.first.id, account_id: 1 }
|
||||||
])
|
])
|
||||||
Conversation.create!([
|
Conversation.create!([
|
||||||
{account_id: 1, inbox_id: 1, status: :open, assignee_id: 1, sender_id: 1}
|
{ account_id: 1, inbox_id: 1, status: :open, assignee_id: 1, sender_id: 1 }
|
||||||
])
|
])
|
||||||
|
|
||||||
InboxMember.create!([
|
InboxMember.create!([
|
||||||
{user_id: 1, inbox_id: 1}
|
{ user_id: 1, inbox_id: 1 }
|
||||||
])
|
])
|
||||||
Message.create!([
|
Message.create!([
|
||||||
{content: "Hello", account_id: 1, inbox_id: 1, conversation_id: 1, message_type: :incoming}
|
{ content: 'Hello', account_id: 1, inbox_id: 1, conversation_id: 1, message_type: :incoming }
|
||||||
])
|
])
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
Chef::Log.debug "==================> inside before_migrate <=================="
|
Chef::Log.debug '==================> inside before_migrate <=================='
|
||||||
|
|
||||||
shared_path = "/srv/www/chatwoot/shared"
|
shared_path = '/srv/www/chatwoot/shared'
|
||||||
|
|
||||||
#yml files
|
# yml files
|
||||||
run "ln -nfs #{shared_path}/config/application.yml #{release_path}/config/application.yml"
|
run "ln -nfs #{shared_path}/config/application.yml #{release_path}/config/application.yml"
|
||||||
run "ln -nfs #{shared_path}/config/reports_redis.yml #{release_path}/config/reports_redis.yml"
|
run "ln -nfs #{shared_path}/config/reports_redis.yml #{release_path}/config/reports_redis.yml"
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
if ['application', 'sidekiq', 'whenever'].include? node[:opsworks][:instance][:layers].first
|
if %w[application sidekiq whenever].include? node[:opsworks][:instance][:layers].first
|
||||||
rails_env = new_resource.environment["RAILS_ENV"]
|
rails_env = new_resource.environment['RAILS_ENV']
|
||||||
shared_path = "#{new_resource.deploy_to}/shared"
|
shared_path = "#{new_resource.deploy_to}/shared"
|
||||||
|
|
||||||
# key is rails app path, value is shared directory path
|
# key is rails app path, value is shared directory path
|
||||||
|
@ -11,11 +11,11 @@ if ['application', 'sidekiq', 'whenever'].include? node[:opsworks][:instance][:l
|
||||||
# creating directories and symlinking
|
# creating directories and symlinking
|
||||||
directories.each do |_release_path, _shared_path|
|
directories.each do |_release_path, _shared_path|
|
||||||
directory "#{shared_path}/#{_shared_path}" do
|
directory "#{shared_path}/#{_shared_path}" do
|
||||||
mode 0770
|
mode 0o770
|
||||||
action :create
|
action :create
|
||||||
recursive true
|
recursive true
|
||||||
not_if do
|
not_if do
|
||||||
Dir.exists?("#{shared_path}/#{_shared_path}")
|
Dir.exist?("#{shared_path}/#{_shared_path}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -32,12 +32,12 @@ if ['application', 'sidekiq', 'whenever'].include? node[:opsworks][:instance][:l
|
||||||
# environment 'RAILS_ENV' => rails_env
|
# environment 'RAILS_ENV' => rails_env
|
||||||
# end
|
# end
|
||||||
|
|
||||||
#migrations
|
# migrations
|
||||||
master_node = node[:opsworks][:layers]["application"][:instances].keys.sort.first if node[:opsworks][:layers] && node[:opsworks][:layers]["application"] && node[:opsworks][:layers]["application"][:instances]
|
master_node = node[:opsworks][:layers]['application'][:instances].keys.min if node[:opsworks][:layers] && node[:opsworks][:layers]['application'] && node[:opsworks][:layers]['application'][:instances]
|
||||||
if master_node && node[:opsworks][:instance][:hostname].include?(master_node)
|
if master_node && node[:opsworks][:instance][:hostname].include?(master_node)
|
||||||
execute "rake db:migrate" do
|
execute 'rake db:migrate' do
|
||||||
cwd release_path
|
cwd release_path
|
||||||
command "bundle exec rake db:migrate --trace"
|
command 'bundle exec rake db:migrate --trace'
|
||||||
environment 'RAILS_ENV' => rails_env
|
environment 'RAILS_ENV' => rails_env
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module CustomExceptions::Account
|
module CustomExceptions::Account
|
||||||
|
|
||||||
class InvalidEmail < CustomExceptions::Base
|
class InvalidEmail < CustomExceptions::Base
|
||||||
|
|
||||||
def message
|
def message
|
||||||
if @data[:disposable]
|
if @data[:disposable]
|
||||||
I18n.t 'errors.signup.disposable_email'
|
I18n.t 'errors.signup.disposable_email'
|
||||||
|
@ -21,7 +19,7 @@ module CustomExceptions::Account
|
||||||
|
|
||||||
class UserErrors < CustomExceptions::Base
|
class UserErrors < CustomExceptions::Base
|
||||||
def message
|
def message
|
||||||
@data[:errors].full_messages.join(",")
|
@data[:errors].full_messages.join(',')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -30,6 +28,4 @@ module CustomExceptions::Account
|
||||||
I18n.t 'errors.signup.failed'
|
I18n.t 'errors.signup.failed'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class CustomExceptions::Base < ::StandardError
|
class CustomExceptions::Base < ::StandardError
|
||||||
|
|
||||||
def to_hash
|
def to_hash
|
||||||
{
|
{
|
||||||
message: message
|
message: message
|
||||||
|
@ -15,5 +14,4 @@ class CustomExceptions::Base < ::StandardError
|
||||||
def initialize(data)
|
def initialize(data)
|
||||||
@data = data
|
@data = data
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,31 +3,31 @@
|
||||||
module CustomExceptions::Report
|
module CustomExceptions::Report
|
||||||
class InvalidIdentity < CustomExceptions::Base
|
class InvalidIdentity < CustomExceptions::Base
|
||||||
def message
|
def message
|
||||||
"Invalid type"
|
'Invalid type'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class IdentityNotFound < CustomExceptions::Base
|
class IdentityNotFound < CustomExceptions::Base
|
||||||
def message
|
def message
|
||||||
"Type with the specified id not found"
|
'Type with the specified id not found'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class MetricNotFound < CustomExceptions::Base
|
class MetricNotFound < CustomExceptions::Base
|
||||||
def message
|
def message
|
||||||
"Metric for the specified type not found"
|
'Metric for the specified type not found'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class InvalidStartTime < CustomExceptions::Base
|
class InvalidStartTime < CustomExceptions::Base
|
||||||
def message
|
def message
|
||||||
"Invalid start_time"
|
'Invalid start_time'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class InvalidEndTime < CustomExceptions::Base
|
class InvalidEndTime < CustomExceptions::Base
|
||||||
def message
|
def message
|
||||||
"Invalid end_time"
|
'Invalid end_time'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,6 +9,6 @@ class Events::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def method_name
|
def method_name
|
||||||
name.to_s.gsub('.','_')
|
name.to_s.gsub('.', '_')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue