diff --git a/Gemfile b/Gemfile index 6b6813846..718e90979 100644 --- a/Gemfile +++ b/Gemfile @@ -75,8 +75,8 @@ gem 'jwt' gem 'pundit' # super admin gem 'administrate', '>= 0.19.0' -gem 'administrate-field-active_storage', '>= 1.0.0' -gem 'administrate-field-belongs_to_search' +gem 'administrate-field-active_storage', '>= 1.0.1' +gem 'administrate-field-belongs_to_search', '>= 0.9.0' ##--- gems for pubsub service ---## # https://karolgalanciak.com/blog/2019/11/30/from-activerecord-callbacks-to-publish-slash-subscribe-pattern-and-event-driven-design/ @@ -162,7 +162,7 @@ gem 'omniauth-oauth2' gem 'audited', '~> 5.4', '>= 5.4.1' # need for google auth -gem 'omniauth' +gem 'omniauth', '>= 2.1.2' gem 'omniauth-google-oauth2' gem 'omniauth-rails_csrf_protection', '~> 1.0' @@ -224,7 +224,7 @@ group :development, :test do gem 'byebug', platform: :mri gem 'climate_control' gem 'debug', '~> 1.8' - gem 'factory_bot_rails', '>= 6.4.2' + gem 'factory_bot_rails', '>= 6.4.3' gem 'listen' gem 'mock_redis' gem 'pry-rails' diff --git a/Gemfile.lock b/Gemfile.lock index b224d09aa..8d8714fd8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -113,13 +113,13 @@ GEM kaminari (>= 1.0) sassc-rails (~> 2.1) selectize-rails (~> 0.6) - administrate-field-active_storage (1.0.0) + administrate-field-active_storage (1.0.1) administrate (>= 0.2.2) rails (>= 7.0) - administrate-field-belongs_to_search (0.8.0) + administrate-field-belongs_to_search (0.9.0) administrate (>= 0.3, < 1.0) jbuilder (~> 2) - rails (>= 4.2, < 7.1) + rails (>= 4.2, < 7.2) selectize-rails (~> 0.6) annotate (3.2.0) activerecord (>= 3.2, < 8.0) @@ -230,9 +230,9 @@ GEM facebook-messenger (2.0.1) httparty (~> 0.13, >= 0.13.7) rack (>= 1.4.5) - factory_bot (6.4.2) + factory_bot (6.4.5) activesupport (>= 5.0.0) - factory_bot_rails (6.4.2) + factory_bot_rails (6.4.3) factory_bot (~> 6.4) railties (>= 5.0.0) faker (3.2.0) @@ -472,7 +472,7 @@ GEM activerecord (>= 5.2) net-http-persistent (4.0.2) connection_pool (~> 2.2) - net-imap (0.4.5) + net-imap (0.4.9) date net-protocol net-pop (0.1.2) @@ -487,15 +487,15 @@ GEM sidekiq newrelic_rpm (9.6.0) base64 - nio4r (2.6.0) - nokogiri (1.15.5) + nio4r (2.7.0) + nokogiri (1.16.0) mini_portile2 (~> 2.8.2) racc (~> 1.4) - nokogiri (1.15.5-arm64-darwin) + nokogiri (1.16.0-arm64-darwin) racc (~> 1.4) - nokogiri (1.15.5-x86_64-darwin) + nokogiri (1.16.0-x86_64-darwin) racc (~> 1.4) - nokogiri (1.15.5-x86_64-linux) + nokogiri (1.16.0-x86_64-linux) racc (~> 1.4) numo-narray (0.9.2.1) oauth (1.1.0) @@ -511,7 +511,7 @@ GEM rack (>= 1.2, < 4) snaky_hash (~> 2.0) version_gem (~> 1.1) - omniauth (2.1.1) + omniauth (2.1.2) hashie (>= 3.4.6) rack (>= 2.2.3) rack-protection @@ -553,7 +553,7 @@ GEM pry-rails (0.3.9) pry (>= 0.10.4) public_suffix (5.0.1) - puma (6.3.1) + puma (6.4.2) nio4r (~> 2.0) pundit (2.3.0) activesupport (>= 3.0.0) @@ -568,8 +568,8 @@ GEM rack (>= 2.0.0) rack-mini-profiler (3.2.0) rack (>= 1.2.0) - rack-protection (3.0.6) - rack + rack-protection (3.1.0) + rack (~> 2.2, >= 2.2.4) rack-proxy (0.7.6) rack rack-test (2.1.0) @@ -841,8 +841,8 @@ DEPENDENCIES activerecord-import acts-as-taggable-on administrate (>= 0.19.0) - administrate-field-active_storage (>= 1.0.0) - administrate-field-belongs_to_search + administrate-field-active_storage (>= 1.0.1) + administrate-field-belongs_to_search (>= 0.9.0) annotate attr_extras audited (~> 5.4, >= 5.4.1) @@ -870,7 +870,7 @@ DEPENDENCIES elastic-apm email_reply_trimmer facebook-messenger - factory_bot_rails (>= 6.4.2) + factory_bot_rails (>= 6.4.3) faker fcm flag_shih_tzu @@ -905,7 +905,7 @@ DEPENDENCIES neighbor newrelic-sidekiq-metrics (>= 1.6.2) newrelic_rpm - omniauth + omniauth (>= 2.1.2) omniauth-google-oauth2 omniauth-oauth2 omniauth-rails_csrf_protection (~> 1.0) diff --git a/README.md b/README.md index 11ac5dc2c..17d4e7f5e 100644 --- a/README.md +++ b/README.md @@ -118,4 +118,4 @@ Thanks goes to all these [wonderful people](https://www.chatwoot.com/docs/contri -*Chatwoot* © 2017-2023, Chatwoot Inc - Released under the MIT License. +*Chatwoot* © 2017-2024, Chatwoot Inc - Released under the MIT License. diff --git a/app/builders/messages/instagram/message_builder.rb b/app/builders/messages/instagram/message_builder.rb index 5610e0671..e9debb767 100644 --- a/app/builders/messages/instagram/message_builder.rb +++ b/app/builders/messages/instagram/message_builder.rb @@ -48,6 +48,10 @@ class Messages::Instagram::MessageBuilder < Messages::Messenger::MessageBuilder @outgoing_echo ? recipient_id : sender_id end + def message_is_unsupported? + message[:is_unsupported].present? && @messaging[:message][:is_unsupported] == true + end + def sender_id @messaging[:sender][:id] end @@ -118,7 +122,7 @@ class Messages::Instagram::MessageBuilder < Messages::Messenger::MessageBuilder end def message_params - { + params = { account_id: conversation.account_id, inbox_id: conversation.inbox_id, message_type: message_type, @@ -129,6 +133,9 @@ class Messages::Instagram::MessageBuilder < Messages::Messenger::MessageBuilder in_reply_to_external_id: message_reply_attributes } } + + params[:content_attributes][:is_unsupported] = true if message_is_unsupported? + params end def already_sent_from_chatwoot? diff --git a/app/controllers/api/v1/accounts/conversations_controller.rb b/app/controllers/api/v1/accounts/conversations_controller.rb index a3d3ad645..281ff95de 100644 --- a/app/controllers/api/v1/accounts/conversations_controller.rb +++ b/app/controllers/api/v1/accounts/conversations_controller.rb @@ -60,13 +60,26 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro end def toggle_status - if params[:status].present? + # FIXME: move this logic into a service object + if pending_to_open_by_bot? + @conversation.bot_handoff! + elsif params[:status].present? set_conversation_status @status = @conversation.save! else @status = @conversation.toggle_status end - assign_conversation if @conversation.status == 'open' && Current.user.is_a?(User) && Current.user&.agent? + assign_conversation if should_assign_conversation? + end + + def pending_to_open_by_bot? + return false unless Current.user.is_a?(AgentBot) + + @conversation.status == 'pending' && params[:status] == 'open' + end + + def should_assign_conversation? + @conversation.status == 'open' && Current.user.is_a?(User) && Current.user&.agent? end def toggle_priority diff --git a/app/controllers/concerns/access_token_auth_helper.rb b/app/controllers/concerns/access_token_auth_helper.rb index 2f4dc4337..c35a28d7d 100644 --- a/app/controllers/concerns/access_token_auth_helper.rb +++ b/app/controllers/concerns/access_token_auth_helper.rb @@ -14,7 +14,7 @@ module AccessTokenAuthHelper render_unauthorized('Invalid Access Token') && return if @access_token.blank? @resource = @access_token.owner - Current.user = @resource if current_user.is_a?(User) + Current.user = @resource if [User, AgentBot].include?(@resource.class) end def validate_bot_access_token! diff --git a/app/controllers/super_admin/app_configs_controller.rb b/app/controllers/super_admin/app_configs_controller.rb index ce06879c5..97caad42c 100644 --- a/app/controllers/super_admin/app_configs_controller.rb +++ b/app/controllers/super_admin/app_configs_controller.rb @@ -9,6 +9,9 @@ class SuperAdmin::AppConfigsController < SuperAdmin::ApplicationController .map { |name, serialized_value| [name, serialized_value['value']] } .to_h # rubocop:enable Style/HashTransformValues + @installation_configs = ConfigLoader.new.general_configs.each_with_object({}) do |config_hash, result| + result[config_hash['name']] = config_hash.except('name') + end end def create diff --git a/app/javascript/dashboard/assets/scss/widgets/_conversation-view.scss b/app/javascript/dashboard/assets/scss/widgets/_conversation-view.scss index e538299aa..5cc3caa27 100644 --- a/app/javascript/dashboard/assets/scss/widgets/_conversation-view.scss +++ b/app/javascript/dashboard/assets/scss/widgets/_conversation-view.scss @@ -76,7 +76,11 @@ &.left { .bubble { - @apply border border-slate-50 dark:border-slate-700 bg-white dark:bg-slate-700 text-black-900 dark:text-slate-50 rounded-r-lg rounded-l mr-auto break-words; + @apply rounded-r-lg rounded-l mr-auto break-words; + + &:not(.is-unsupported) { + @apply border border-slate-50 dark:border-slate-700 bg-white dark:bg-slate-700 text-black-900 dark:text-slate-50 + } &.is-image { @apply rounded-lg; diff --git a/app/javascript/dashboard/components/NetworkNotification.vue b/app/javascript/dashboard/components/NetworkNotification.vue index 6d142b1cd..2f3b02826 100644 --- a/app/javascript/dashboard/components/NetworkNotification.vue +++ b/app/javascript/dashboard/components/NetworkNotification.vue @@ -1,24 +1,33 @@