chore: General fixes and clean up (#1169)
This commit is contained in:
parent
124e43b477
commit
2193de9853
23 changed files with 111 additions and 121 deletions
|
@ -50,6 +50,8 @@ class Messages::Facebook::MessageBuilder
|
|||
def attach_file(attachment, file_url)
|
||||
file_resource = LocalResource.new(file_url)
|
||||
attachment.file.attach(io: file_resource.file, filename: file_resource.tmp_filename, content_type: file_resource.encoding)
|
||||
rescue Errno::ETIMEDOUT, Errno::ECONNREFUSED => e
|
||||
Rails.logger.info "invalid url #{file_url} : #{e.message}"
|
||||
end
|
||||
|
||||
def conversation
|
||||
|
|
|
@ -81,6 +81,8 @@ class Api::V1::Accounts::CallbacksController < Api::V1::Accounts::BaseController
|
|||
|
||||
avatar_resource = LocalResource.new(uri)
|
||||
facebook_inbox.avatar.attach(io: avatar_resource.file, filename: avatar_resource.tmp_filename, content_type: avatar_resource.encoding)
|
||||
rescue Errno::ETIMEDOUT, Errno::ECONNREFUSED => e
|
||||
Rails.logger.info "invalid url #{file_url} : #{e.message}"
|
||||
end
|
||||
|
||||
def get_avatar_url(page_id)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseController
|
||||
include Events::Types
|
||||
|
||||
before_action :conversation, except: [:index]
|
||||
before_action :contact_inbox, only: [:create]
|
||||
|
||||
|
|
|
@ -9,7 +9,11 @@ class AsyncDispatcher < BaseDispatcher
|
|||
end
|
||||
|
||||
def listeners
|
||||
listeners = [EventListener.instance, WebhookListener.instance, HookListener.instance]
|
||||
listeners = [
|
||||
EventListener.instance,
|
||||
WebhookListener.instance,
|
||||
InstallationWebhookListener.instance, HookListener.instance
|
||||
]
|
||||
listeners
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,5 +4,7 @@ class ContactAvatarJob < ApplicationJob
|
|||
def perform(contact, avatar_url)
|
||||
avatar_resource = LocalResource.new(avatar_url)
|
||||
contact.avatar.attach(io: avatar_resource.file, filename: avatar_resource.tmp_filename, content_type: avatar_resource.encoding)
|
||||
rescue Errno::ETIMEDOUT, Errno::ECONNREFUSED => e
|
||||
Rails.logger.info "invalid url #{file_url} : #{e.message}"
|
||||
end
|
||||
end
|
||||
|
|
19
app/listeners/installation_webhook_listener.rb
Normal file
19
app/listeners/installation_webhook_listener.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
class InstallationWebhookListener < BaseListener
|
||||
def account_created(event)
|
||||
payload = event.data[:account].webhook_data.merge(event: __method__.to_s)
|
||||
deliver_webhook_payloads(payload)
|
||||
end
|
||||
|
||||
def account_destroyed(event)
|
||||
payload = event.data[:account].webhook_data.merge(event: __method__.to_s)
|
||||
deliver_webhook_payloads(payload)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def deliver_webhook_payloads(payload)
|
||||
# Deliver the installation event
|
||||
webhook_url = InstallationConfig.find_by(name: 'INSTALLATION_EVENTS_WEBHOOK_URL')&.value
|
||||
WebhookJob.perform_later(webhook_url, payload) if webhook_url
|
||||
end
|
||||
end
|
|
@ -16,8 +16,6 @@
|
|||
class Account < ApplicationRecord
|
||||
# used for single column multi flags
|
||||
include FlagShihTzu
|
||||
|
||||
include Events::Types
|
||||
include Reportable
|
||||
include Featurable
|
||||
|
||||
|
@ -54,7 +52,7 @@ class Account < ApplicationRecord
|
|||
|
||||
enum locale: LANGUAGES_CONFIG.map { |key, val| [val[:iso_639_1_code], key] }.to_h
|
||||
|
||||
after_create :notify_creation
|
||||
after_create_commit :notify_creation
|
||||
after_destroy :notify_deletion
|
||||
|
||||
def agents
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
#
|
||||
|
||||
class AccountUser < ApplicationRecord
|
||||
include Events::Types
|
||||
|
||||
belongs_to :account
|
||||
belongs_to :user
|
||||
belongs_to :inviter, class_name: 'User', optional: true
|
||||
|
@ -33,7 +31,7 @@ class AccountUser < ApplicationRecord
|
|||
enum role: { agent: 0, administrator: 1 }
|
||||
accepts_nested_attributes_for :account
|
||||
|
||||
after_create :notify_creation, :create_notification_setting
|
||||
after_create_commit :notify_creation, :create_notification_setting
|
||||
after_destroy :notify_deletion, :destroy_notification_setting
|
||||
|
||||
validates :user_id, uniqueness: { scope: :account_id }
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
class ApplicationRecord < ActiveRecord::Base
|
||||
include Events::Types
|
||||
self.abstract_class = true
|
||||
|
||||
# the models that exposed in email templates through liquid
|
||||
DROPPABLES = %w[Account Channel Conversation Inbox User].freeze
|
||||
|
||||
# ModelDrop class should exist in app/drops
|
||||
def to_drop
|
||||
return unless DROPPABLES.include?(self.class.name)
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ class Contact < ApplicationRecord
|
|||
include Pubsubable
|
||||
include Avatarable
|
||||
include AvailabilityStatusable
|
||||
include Events::Types
|
||||
|
||||
validates :account_id, presence: true
|
||||
validates :email, allow_blank: true, uniqueness: { scope: [:account_id], case_sensitive: false }
|
||||
|
|
|
@ -31,8 +31,6 @@
|
|||
#
|
||||
|
||||
class Conversation < ApplicationRecord
|
||||
include Events::Types
|
||||
|
||||
validates :account_id, presence: true
|
||||
validates :inbox_id, presence: true
|
||||
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
#
|
||||
|
||||
class Message < ApplicationRecord
|
||||
include Events::Types
|
||||
|
||||
NUMBER_OF_PERMITTED_ATTACHMENTS = 15
|
||||
|
||||
validates :account_id, presence: true
|
||||
|
@ -105,6 +103,7 @@ class Message < ApplicationRecord
|
|||
created_at: created_at,
|
||||
message_type: message_type,
|
||||
content_type: content_type,
|
||||
private: private,
|
||||
content_attributes: content_attributes,
|
||||
source_id: source_id,
|
||||
sender: sender.try(:webhook_data),
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
class Plan
|
||||
attr_accessor :key, :attributes
|
||||
|
||||
def initialize(key, attributes = {})
|
||||
@key = key.to_sym
|
||||
@attributes = attributes
|
||||
end
|
||||
|
||||
def name
|
||||
attributes[:name]
|
||||
end
|
||||
|
||||
def id
|
||||
attributes[:id]
|
||||
end
|
||||
|
||||
def price
|
||||
attributes[:price]
|
||||
end
|
||||
|
||||
def active
|
||||
attributes[:active]
|
||||
end
|
||||
|
||||
def version
|
||||
attributes[:version]
|
||||
end
|
||||
|
||||
class << self
|
||||
def config
|
||||
Hashie::Mash.new(PLAN_CONFIG)
|
||||
end
|
||||
|
||||
def default_trial_period
|
||||
(config['trial_period'] || 14).days
|
||||
end
|
||||
|
||||
def default_pricing_version
|
||||
config['default_pricing_version']
|
||||
end
|
||||
|
||||
def default_plans
|
||||
load_active_plans + load_inactive_plans
|
||||
end
|
||||
|
||||
def all_plans
|
||||
default_plans
|
||||
end
|
||||
|
||||
def active_plans
|
||||
all_plans.select(&:active)
|
||||
end
|
||||
|
||||
def paid_plan
|
||||
active_plans.first
|
||||
end
|
||||
|
||||
def inactive_plans
|
||||
all_plans.reject(&:active)
|
||||
end
|
||||
|
||||
def trial_plan
|
||||
all_plans.detect { |plan| plan.key == :trial }
|
||||
end
|
||||
|
||||
def plans_of_version(version)
|
||||
all_plans.select { |plan| plan.version == version }
|
||||
end
|
||||
|
||||
def find_by_key(key)
|
||||
key = key.to_sym
|
||||
all_plans.detect { |plan| plan.key == key }.dup
|
||||
end
|
||||
|
||||
# #helpers
|
||||
|
||||
def load_active_plans
|
||||
result = []
|
||||
Plan.config.active.each_pair do |version, plans|
|
||||
plans.each_pair do |key, attributes|
|
||||
result << Plan.new(key, attributes.merge(active: true, version: version))
|
||||
end
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def load_inactive_plans
|
||||
result = []
|
||||
Plan.config.inactive.each_pair do |version, plans|
|
||||
plans.each_pair do |key, attributes|
|
||||
result << Plan.new(key, attributes.merge(active: false, version: version))
|
||||
end
|
||||
end
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
|
@ -41,7 +41,6 @@ class User < ApplicationRecord
|
|||
include Avatarable
|
||||
# Include default devise modules.
|
||||
include DeviseTokenAuth::Concerns::User
|
||||
include Events::Types
|
||||
include Pubsubable
|
||||
include Rails.application.routes.url_helpers
|
||||
include Reportable
|
||||
|
@ -78,7 +77,7 @@ class User < ApplicationRecord
|
|||
|
||||
before_validation :set_password_and_uid, on: :create
|
||||
|
||||
after_create :create_access_token
|
||||
after_create_commit :create_access_token
|
||||
after_save :update_presence_in_redis, if: :saved_change_to_availability?
|
||||
|
||||
scope :order_by_full_name, -> { order('lower(name) ASC') }
|
||||
|
|
|
@ -107,5 +107,7 @@ class Twilio::IncomingMessageService
|
|||
)
|
||||
|
||||
@message.save!
|
||||
rescue Errno::ETIMEDOUT, Errno::ECONNREFUSED => e
|
||||
Rails.logger.info "invalid url #{file_url} : #{e.message}"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -22,3 +22,5 @@
|
|||
value: false
|
||||
- name: BRAND_NAME
|
||||
value: 'Chatwoot'
|
||||
- name: 'INSTALLATION_EVENTS_WEBHOOK_URL'
|
||||
value:
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Events::Types
|
||||
### Installation Events ###
|
||||
# account events
|
||||
ACCOUNT_CREATED = 'account.created'
|
||||
ACCOUNT_DESTROYED = 'account.destroyed'
|
||||
|
||||
#### Account Events ###
|
||||
# channel events
|
||||
WEBWIDGET_TRIGGERED = 'webwidget.triggered'
|
||||
|
||||
|
@ -28,10 +30,7 @@ module Events::Types
|
|||
CONTACT_CREATED = 'contact.created'
|
||||
CONTACT_UPDATED = 'contact.updated'
|
||||
|
||||
# subscription events
|
||||
# agent events
|
||||
AGENT_ADDED = 'agent.added'
|
||||
AGENT_REMOVED = 'agent.removed'
|
||||
SUBSCRIPTION_CREATED = 'subscription.created'
|
||||
SUBSCRIPTION_REACTIVATED = 'subscription.reactivated'
|
||||
SUBSCRIPTION_DEACTIVATED = 'subscription.deactivated'
|
||||
end
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
class Webhooks::Trigger
|
||||
def self.execute(url, payload)
|
||||
RestClient.post(url, payload.to_json, { content_type: :json, accept: :json })
|
||||
rescue RestClient::NotFound => e
|
||||
Rails.logger.info "invalid url #{url} : #{e.message}"
|
||||
rescue StandardError => e
|
||||
Raven.capture_exception(e)
|
||||
end
|
||||
|
|
6
spec/factories/installation_config.rb
Normal file
6
spec/factories/installation_config.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
FactoryBot.define do
|
||||
factory :installation_config do
|
||||
name { 'xyc' }
|
||||
value { 1.5 }
|
||||
end
|
||||
end
|
44
spec/listeners/installation_webhook_listener_spec.rb
Normal file
44
spec/listeners/installation_webhook_listener_spec.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
require 'rails_helper'
|
||||
describe InstallationWebhookListener do
|
||||
let(:listener) { described_class.instance }
|
||||
let!(:account) { create(:account) }
|
||||
let!(:event) { Events::Base.new(event_name, Time.zone.now, account: account) }
|
||||
|
||||
describe '#account_created' do
|
||||
let(:event_name) { :'account.created' }
|
||||
|
||||
context 'when installation config is not configured' do
|
||||
it 'does not trigger webhook' do
|
||||
expect(WebhookJob).to receive(:perform_later).exactly(0).times
|
||||
listener.account_created(event)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when installation config is configured' do
|
||||
it 'triggers webhook' do
|
||||
create(:installation_config, name: 'INSTALLATION_EVENTS_WEBHOOK_URL', value: 'https://test.com')
|
||||
expect(WebhookJob).to receive(:perform_later).with('https://test.com', account.webhook_data.merge(event: 'account_created')).once
|
||||
listener.account_created(event)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#account_destroyed' do
|
||||
let(:event_name) { :'account.destroyed' }
|
||||
|
||||
context 'when installation config is not configured' do
|
||||
it 'does not trigger webhook' do
|
||||
expect(WebhookJob).to receive(:perform_later).exactly(0).times
|
||||
listener.account_destroyed(event)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when installation config is configured' do
|
||||
it 'triggers webhook' do
|
||||
create(:installation_config, name: 'INSTALLATION_EVENTS_WEBHOOK_URL', value: 'https://test.com')
|
||||
expect(WebhookJob).to receive(:perform_later).with('https://test.com', account.webhook_data.merge(event: 'account_destroyed')).once
|
||||
listener.account_destroyed(event)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -17,7 +17,7 @@ describe WebhookListener do
|
|||
|
||||
context 'when webhook is not configured' do
|
||||
it 'does not trigger webhook' do
|
||||
expect(RestClient).to receive(:post).exactly(0).times
|
||||
expect(WebhookJob).to receive(:perform_later).exactly(0).times
|
||||
listener.message_created(event)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,7 +12,10 @@ properties:
|
|||
description: Flag to identify if it is a private note
|
||||
content_type:
|
||||
type: string
|
||||
enum: ['input_select', 'form', 'cards']
|
||||
enum: ['input_email', 'cards', 'input_select', 'form' , 'article']
|
||||
example: 'cards'
|
||||
description: 'if you want to create custom message types'
|
||||
content_attributes:
|
||||
type: object
|
||||
description: options/form object
|
||||
description: attributes based on your content type
|
||||
|
||||
|
|
|
@ -1641,14 +1641,18 @@
|
|||
"content_type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"input_email",
|
||||
"cards",
|
||||
"input_select",
|
||||
"form",
|
||||
"cards"
|
||||
]
|
||||
"article"
|
||||
],
|
||||
"example": "cards",
|
||||
"description": "if you want to create custom message types"
|
||||
},
|
||||
"content_attributes": {
|
||||
"type": "object",
|
||||
"description": "options/form object"
|
||||
"description": "attributes based on your content type"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue