mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-10-31 02:57:57 +00:00 
			
		
		
		
	Chore: Switch from Carrierwave to ActiveStorage (#393)
This commit is contained in:
		| @@ -6,6 +6,8 @@ inherit_from: .rubocop_todo.yml | ||||
|  | ||||
| Metrics/LineLength: | ||||
|   Max: 150 | ||||
| Metrics/ClassLength: | ||||
|   Max: 125 | ||||
| RSpec/ExampleLength: | ||||
|   Max: 15 | ||||
| Documentation: | ||||
|   | ||||
							
								
								
									
										7
									
								
								Gemfile
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								Gemfile
									
									
									
									
									
								
							| @@ -23,6 +23,9 @@ gem 'valid_email2' | ||||
| gem 'uglifier' | ||||
|  | ||||
| ##-- for active storage --## | ||||
| gem 'aws-sdk-s3', require: false | ||||
| gem 'azure-storage', require: false | ||||
| gem 'google-cloud-storage', require: false | ||||
| gem 'mini_magick' | ||||
|  | ||||
| ##-- gems for database --# | ||||
| @@ -68,9 +71,7 @@ gem 'haikunator' | ||||
| gem 'brakeman' | ||||
| gem 'sentry-raven' | ||||
|  | ||||
| ##-- TODO: move these gems to appropriate groups --## | ||||
| # remove this gem in favor of active storage -  github #158 | ||||
| gem 'carrierwave-aws' | ||||
| ##-- background job processing --## | ||||
| gem 'sidekiq' | ||||
|  | ||||
| group :development do | ||||
|   | ||||
							
								
								
									
										76
									
								
								Gemfile.lock
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								Gemfile.lock
									
									
									
									
									
								
							| @@ -68,7 +68,7 @@ GEM | ||||
|     ast (2.4.0) | ||||
|     attr_extras (6.2.1) | ||||
|     aws-eventstream (1.0.3) | ||||
|     aws-partitions (1.259.0) | ||||
|     aws-partitions (1.262.0) | ||||
|     aws-sdk-core (3.86.0) | ||||
|       aws-eventstream (~> 1.0, >= 1.0.2) | ||||
|       aws-partitions (~> 1, >= 1.239.0) | ||||
| @@ -87,6 +87,15 @@ GEM | ||||
|       descendants_tracker (~> 0.0.4) | ||||
|       ice_nine (~> 0.11.0) | ||||
|       thread_safe (~> 0.3, >= 0.3.1) | ||||
|     azure-core (0.1.15) | ||||
|       faraday (~> 0.9) | ||||
|       faraday_middleware (~> 0.10) | ||||
|       nokogiri (~> 1.6) | ||||
|     azure-storage (0.15.0.preview) | ||||
|       azure-core (~> 0.1) | ||||
|       faraday (~> 0.9) | ||||
|       faraday_middleware (~> 0.10) | ||||
|       nokogiri (~> 1.6, >= 1.6.8) | ||||
|     bcrypt (3.1.13) | ||||
|     bindex (0.8.1) | ||||
|     bootsnap (1.4.5) | ||||
| @@ -104,16 +113,6 @@ GEM | ||||
|       bundler (>= 1.2.0, < 3) | ||||
|       thor (~> 0.18) | ||||
|     byebug (11.0.1) | ||||
|     carrierwave (2.0.2) | ||||
|       activemodel (>= 5.0.0) | ||||
|       activesupport (>= 5.0.0) | ||||
|       addressable (~> 2.6) | ||||
|       image_processing (~> 1.1) | ||||
|       mimemagic (>= 0.3.0) | ||||
|       mini_mime (>= 0.1.3) | ||||
|     carrierwave-aws (1.4.0) | ||||
|       aws-sdk-s3 (~> 1.0) | ||||
|       carrierwave (>= 0.7, < 2.1) | ||||
|     chargebee (2.7.1) | ||||
|       json_pure (~> 2.1) | ||||
|       rest-client (>= 1.8, < 3.0) | ||||
| @@ -123,6 +122,8 @@ GEM | ||||
|     concurrent-ruby (1.1.5) | ||||
|     connection_pool (2.2.2) | ||||
|     crass (1.0.5) | ||||
|     declarative (0.0.10) | ||||
|     declarative-option (0.1.0) | ||||
|     descendants_tracker (0.0.4) | ||||
|       thread_safe (~> 0.3, >= 0.3.1) | ||||
|     devise (4.7.1) | ||||
| @@ -136,6 +137,7 @@ GEM | ||||
|       devise (> 3.5.2, < 5) | ||||
|       rails (>= 4.2.0, < 6.1) | ||||
|     diff-lcs (1.3) | ||||
|     digest-crc (0.4.1) | ||||
|     docile (1.3.2) | ||||
|     domain_name (0.5.20190701) | ||||
|       unf (>= 0.0.5, < 1.0.0) | ||||
| @@ -158,10 +160,38 @@ GEM | ||||
|       i18n (>= 1.6, < 1.8) | ||||
|     faraday (0.17.1) | ||||
|       multipart-post (>= 1.2, < 3) | ||||
|     faraday_middleware (0.13.1) | ||||
|       faraday (>= 0.7.4, < 1.0) | ||||
|     ffi (1.11.3) | ||||
|     foreman (0.86.0) | ||||
|     globalid (0.4.2) | ||||
|       activesupport (>= 4.2.0) | ||||
|     google-api-client (0.36.4) | ||||
|       addressable (~> 2.5, >= 2.5.1) | ||||
|       googleauth (~> 0.9) | ||||
|       httpclient (>= 2.8.1, < 3.0) | ||||
|       mini_mime (~> 1.0) | ||||
|       representable (~> 3.0) | ||||
|       retriable (>= 2.0, < 4.0) | ||||
|       signet (~> 0.12) | ||||
|     google-cloud-core (1.4.1) | ||||
|       google-cloud-env (~> 1.0) | ||||
|     google-cloud-env (1.3.0) | ||||
|       faraday (~> 0.11) | ||||
|     google-cloud-storage (1.25.1) | ||||
|       addressable (~> 2.5) | ||||
|       digest-crc (~> 0.4) | ||||
|       google-api-client (~> 0.33) | ||||
|       google-cloud-core (~> 1.2) | ||||
|       googleauth (~> 0.9) | ||||
|       mini_mime (~> 1.0) | ||||
|     googleauth (0.10.0) | ||||
|       faraday (~> 0.12) | ||||
|       jwt (>= 1.4, < 3.0) | ||||
|       memoist (~> 0.16) | ||||
|       multi_json (~> 1.11) | ||||
|       os (>= 0.9, < 2.0) | ||||
|       signet (~> 0.12) | ||||
|     haikunator (1.1.0) | ||||
|     hashie (4.0.0) | ||||
|     http (3.3.0) | ||||
| @@ -177,12 +207,10 @@ GEM | ||||
|     httparty (0.17.3) | ||||
|       mime-types (~> 3.0) | ||||
|       multi_xml (>= 0.5.2) | ||||
|     httpclient (2.8.3) | ||||
|     i18n (1.7.0) | ||||
|       concurrent-ruby (~> 1.0) | ||||
|     ice_nine (0.11.2) | ||||
|     image_processing (1.10.0) | ||||
|       mini_magick (>= 4.9.5, < 5) | ||||
|       ruby-vips (>= 2.0.13, < 3) | ||||
|     inflecto (0.0.2) | ||||
|     jaro_winkler (1.5.4) | ||||
|     jbuilder (2.9.1) | ||||
| @@ -221,6 +249,7 @@ GEM | ||||
|       mini_mime (>= 0.1.1) | ||||
|     marcel (0.3.3) | ||||
|       mimemagic (~> 0.3.2) | ||||
|     memoist (0.16.2) | ||||
|     memoizable (0.4.2) | ||||
|       thread_safe (~> 0.3, >= 0.3.1) | ||||
|     method_source (0.9.2) | ||||
| @@ -234,6 +263,7 @@ GEM | ||||
|     minitest (5.13.0) | ||||
|     mock_redis (0.22.0) | ||||
|     msgpack (1.3.1) | ||||
|     multi_json (1.14.1) | ||||
|     multi_xml (0.6.0) | ||||
|     multipart-post (2.1.1) | ||||
|     naught (1.1.0) | ||||
| @@ -243,6 +273,7 @@ GEM | ||||
|     nokogiri (1.10.7) | ||||
|       mini_portile2 (~> 2.4.0) | ||||
|     orm_adapter (0.5.0) | ||||
|     os (1.0.1) | ||||
|     parallel (1.19.1) | ||||
|     parser (2.6.5.0) | ||||
|       ast (~> 2.4.0) | ||||
| @@ -307,6 +338,10 @@ GEM | ||||
|       redis-store (>= 1.6, < 2) | ||||
|     redis-store (1.8.1) | ||||
|       redis (>= 4, < 5) | ||||
|     representable (3.0.4) | ||||
|       declarative (< 0.1.0) | ||||
|       declarative-option (< 0.2.0) | ||||
|       uber (< 0.2.0) | ||||
|     responders (3.0.0) | ||||
|       actionpack (>= 5.0) | ||||
|       railties (>= 5.0) | ||||
| @@ -315,6 +350,7 @@ GEM | ||||
|       http-cookie (>= 1.0.2, < 2.0) | ||||
|       mime-types (>= 1.16, < 4.0) | ||||
|       netrc (~> 0.8) | ||||
|     retriable (3.1.2) | ||||
|     rspec-core (3.9.0) | ||||
|       rspec-support (~> 3.9.0) | ||||
|     rspec-expectations (3.9.0) | ||||
| @@ -347,8 +383,6 @@ GEM | ||||
|     rubocop-rspec (1.37.1) | ||||
|       rubocop (>= 0.68.1) | ||||
|     ruby-progressbar (1.10.1) | ||||
|     ruby-vips (2.0.16) | ||||
|       ffi (~> 1.9) | ||||
|     seed_dump (3.3.1) | ||||
|       activerecord (>= 4) | ||||
|       activesupport (>= 4) | ||||
| @@ -361,6 +395,11 @@ GEM | ||||
|       rack (>= 2.0.0) | ||||
|       rack-protection (>= 2.0.0) | ||||
|       redis (>= 4.1.0) | ||||
|     signet (0.12.0) | ||||
|       addressable (~> 2.3) | ||||
|       faraday (~> 0.9) | ||||
|       jwt (>= 1.5, < 3.0) | ||||
|       multi_json (~> 1.10) | ||||
|     simple_oauth (0.3.1) | ||||
|     simplecov (0.17.1) | ||||
|       docile (~> 1.1) | ||||
| @@ -402,6 +441,7 @@ GEM | ||||
|       thread_safe (~> 0.1) | ||||
|     tzinfo-data (1.2019.3) | ||||
|       tzinfo (>= 1.0.0) | ||||
|     uber (0.1.0) | ||||
|     uglifier (4.2.0) | ||||
|       execjs (>= 0.3.0, < 3) | ||||
|     unf (0.1.4) | ||||
| @@ -442,13 +482,14 @@ DEPENDENCIES | ||||
|   acts-as-taggable-on | ||||
|   annotate | ||||
|   attr_extras | ||||
|   aws-sdk-s3 | ||||
|   azure-storage | ||||
|   bootsnap | ||||
|   brakeman | ||||
|   browser | ||||
|   bullet | ||||
|   bundle-audit | ||||
|   byebug | ||||
|   carrierwave-aws | ||||
|   chargebee | ||||
|   devise | ||||
|   devise_token_auth | ||||
| @@ -457,6 +498,7 @@ DEPENDENCIES | ||||
|   factory_bot_rails | ||||
|   faker | ||||
|   foreman | ||||
|   google-cloud-storage | ||||
|   haikunator | ||||
|   hashie | ||||
|   jbuilder | ||||
|   | ||||
| @@ -36,19 +36,26 @@ module Messages | ||||
|     def build_contact | ||||
|       return if contact.present? | ||||
|  | ||||
|       @contact = Contact.create!(contact_params) | ||||
|       @contact = Contact.create!(contact_params.except(:remote_avatar_url)) | ||||
|       avatar_resource = LocalResource.new(contact_params[:remote_avatar_url]) | ||||
|       @contact.avatar.attach(io: avatar_resource.file, filename: avatar_resource.tmp_filename, content_type: avatar_resource.encoding) | ||||
|  | ||||
|       ContactInbox.create(contact: contact, inbox: @inbox, source_id: @sender_id) | ||||
|     end | ||||
|  | ||||
|     def build_message | ||||
|       @message = conversation.messages.new(message_params) | ||||
|       @message = conversation.messages.create!(message_params) | ||||
|       (response.attachments || []).each do |attachment| | ||||
|         @message.build_attachment(attachment_params(attachment)) | ||||
|         attachment_obj = @message.build_attachment(attachment_params(attachment).except(:remote_file_url)) | ||||
|         attachment_obj.save! | ||||
|         attach_file(attachment_obj, attachment_params(attachment)[:remote_file_url]) if attachment_params(attachment)[:remote_file_url] | ||||
|       end | ||||
|       @message.save! | ||||
|     end | ||||
|  | ||||
|     def build_attachment; end | ||||
|     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) | ||||
|     end | ||||
|  | ||||
|     def conversation | ||||
|       @conversation ||= Conversation.find_by(conversation_params) || Conversation.create!(conversation_params) | ||||
| @@ -123,7 +130,7 @@ module Messages | ||||
|       { | ||||
|         name: "#{result['first_name'] || 'John'} #{result['last_name'] || 'Doe'}", | ||||
|         account_id: @inbox.account_id, | ||||
|         remote_avatar_url: result['profile_pic'] || nil | ||||
|         remote_avatar_url: result['profile_pic'] || '' | ||||
|       } | ||||
|     end | ||||
|   end | ||||
|   | ||||
| @@ -12,8 +12,9 @@ class Api::V1::CallbacksController < ApplicationController | ||||
|     inbox_name = params[:inbox_name] | ||||
|     facebook_channel = current_account.facebook_pages.create!( | ||||
|       name: page_name, page_id: page_id, user_access_token: user_access_token, | ||||
|       page_access_token: page_access_token, remote_avatar_url: set_avatar(page_id) | ||||
|       page_access_token: page_access_token | ||||
|     ) | ||||
|     set_avatar(facebook_channel, page_id) | ||||
|     inbox = current_account.inboxes.create!(name: inbox_name, channel: facebook_channel) | ||||
|     render json: inbox | ||||
|   end | ||||
| @@ -79,7 +80,12 @@ class Api::V1::CallbacksController < ApplicationController | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   def set_avatar(page_id) | ||||
|   def set_avatar(facebook_channel, page_id) | ||||
|     avatar_resource = LocalResource.new(get_avatar_url(page_id)) | ||||
|     facebook_channel.avatar.attach(io: avatar_resource.file, filename: avatar_resource.tmp_filename, content_type: avatar_resource.encoding) | ||||
|   end | ||||
|  | ||||
|   def get_avatar_url(page_id) | ||||
|     begin | ||||
|       url = 'http://graph.facebook.com/' << page_id << '/picture?type=large' | ||||
|       uri = URI.parse(url) | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
|     <div class="contact--profile"> | ||||
|       <div class="contact--info"> | ||||
|         <thumbnail | ||||
|           :src="contact.avatar_url" | ||||
|           :src="contact.thumbnail" | ||||
|           size="56px" | ||||
|           :badge="contact.channel" | ||||
|           :username="contact.name" | ||||
|   | ||||
| @@ -8,7 +8,6 @@ | ||||
| #  extension        :string | ||||
| #  external_url     :string | ||||
| #  fallback_title   :string | ||||
| #  file             :string | ||||
| #  file_type        :integer          default("image") | ||||
| #  created_at       :datetime         not null | ||||
| #  updated_at       :datetime         not null | ||||
| @@ -19,12 +18,12 @@ | ||||
| require 'uri' | ||||
| require 'open-uri' | ||||
| class Attachment < ApplicationRecord | ||||
|   include Rails.application.routes.url_helpers | ||||
|   belongs_to :account | ||||
|   belongs_to :message | ||||
|   mount_uploader :file, AttachmentUploader # used for images | ||||
|   enum file_type: [:image, :audio, :video, :file, :location, :fallback] | ||||
|   has_one_attached :file | ||||
|  | ||||
|   before_create :set_file_extension | ||||
|   enum file_type: [:image, :audio, :video, :file, :location, :fallback] | ||||
|  | ||||
|   def push_event_data | ||||
|     return base_data.merge(location_metadata) if file_type.to_sym == :location | ||||
| @@ -68,13 +67,7 @@ class Attachment < ApplicationRecord | ||||
|     } | ||||
|   end | ||||
|  | ||||
|   def set_file_extension | ||||
|     if external_url && !fallback? | ||||
|       self.extension = begin | ||||
|                          Pathname.new(URI(external_url).path).extname | ||||
|                        rescue StandardError | ||||
|                          nil | ||||
|                        end | ||||
|     end | ||||
|   def file_url | ||||
|     file.attached? ? url_for(file) : '' | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -3,7 +3,6 @@ | ||||
| # Table name: channel_facebook_pages | ||||
| # | ||||
| #  id                :integer          not null, primary key | ||||
| #  avatar            :string | ||||
| #  name              :string           not null | ||||
| #  page_access_token :string           not null | ||||
| #  user_access_token :string           not null | ||||
| @@ -20,11 +19,13 @@ | ||||
|  | ||||
| module Channel | ||||
|   class FacebookPage < ApplicationRecord | ||||
|     include Avatarable | ||||
|  | ||||
|     self.table_name = 'channel_facebook_pages' | ||||
|  | ||||
|     validates :account_id, presence: true | ||||
|     validates :page_id, uniqueness: { scope: :account_id } | ||||
|     mount_uploader :avatar, AvatarUploader | ||||
|     has_one_attached :avatar | ||||
|     belongs_to :account | ||||
|  | ||||
|     has_one :inbox, as: :channel, dependent: :destroy | ||||
|   | ||||
							
								
								
									
										18
									
								
								app/models/concerns/avatarable.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								app/models/concerns/avatarable.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| # frozen_string_literal: true | ||||
|  | ||||
| module Avatarable | ||||
|   extend ActiveSupport::Concern | ||||
|   include Rails.application.routes.url_helpers | ||||
|  | ||||
|   included do | ||||
|     has_one_attached :avatar | ||||
|   end | ||||
|  | ||||
|   def avatar_url | ||||
|     if avatar.attached? && avatar.representable? | ||||
|       url_for(avatar.representation(resize: '250x250')) | ||||
|     else | ||||
|       '' | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @@ -3,7 +3,6 @@ | ||||
| # Table name: contacts | ||||
| # | ||||
| #  id           :integer          not null, primary key | ||||
| #  avatar       :string | ||||
| #  email        :string | ||||
| #  name         :string | ||||
| #  phone_number :string | ||||
| @@ -20,13 +19,13 @@ | ||||
|  | ||||
| class Contact < ApplicationRecord | ||||
|   include Pubsubable | ||||
|   include Avatarable | ||||
|   validates :account_id, presence: true | ||||
|  | ||||
|   belongs_to :account | ||||
|   has_many :conversations, dependent: :destroy | ||||
|   has_many :contact_inboxes, dependent: :destroy | ||||
|   has_many :inboxes, through: :contact_inboxes | ||||
|   mount_uploader :avatar, AvatarUploader | ||||
|  | ||||
|   def get_source_id(inbox_id) | ||||
|     contact_inboxes.find_by!(inbox_id: inbox_id).source_id | ||||
| @@ -36,7 +35,7 @@ class Contact < ApplicationRecord | ||||
|     { | ||||
|       id: id, | ||||
|       name: name, | ||||
|       thumbnail: avatar.thumb.url, | ||||
|       thumbnail: avatar_url, | ||||
|       pubsub_token: pubsub_token | ||||
|     } | ||||
|   end | ||||
|   | ||||
| @@ -68,11 +68,10 @@ class Inbox < ApplicationRecord | ||||
|     Facebook::Messenger::Subscriptions.subscribe( | ||||
|       access_token: channel.page_access_token, | ||||
|       subscribed_fields: %w[ | ||||
|         message_mention messages messaging_account_linking messaging_checkout_updates | ||||
|         message_echoes message_deliveries messaging_game_plays messaging_optins messaging_optouts | ||||
|         messaging_payments messaging_postbacks messaging_pre_checkouts message_reads messaging_referrals | ||||
|         messaging_handovers messaging_policy_enforcement messaging_page_feedback | ||||
|         messaging_appointments messaging_direct_sends | ||||
|         messages messaging_postbacks messaging_optins message_deliveries | ||||
|         message_reads messaging_payments messaging_pre_checkouts messaging_checkout_updates | ||||
|         messaging_account_linking messaging_referrals message_echoes messaging_game_plays | ||||
|         standby messaging_handovers messaging_policy_enforcement message_reactions | ||||
|       ] | ||||
|     ) | ||||
|   end | ||||
|   | ||||
| @@ -47,6 +47,7 @@ class User < ApplicationRecord | ||||
|   include DeviseTokenAuth::Concerns::User | ||||
|   include Events::Types | ||||
|   include Pubsubable | ||||
|   include Avatarable | ||||
|   include Rails.application.routes.url_helpers | ||||
|  | ||||
|   devise :database_authenticatable, | ||||
| @@ -57,12 +58,6 @@ class User < ApplicationRecord | ||||
|          :validatable, | ||||
|          :confirmable | ||||
|  | ||||
|   # Used by the actionCable/PubSub Service we use for real time communications | ||||
|   has_secure_token :pubsub_token | ||||
|  | ||||
|   # Uses active storage for the avatar | ||||
|   has_one_attached :avatar | ||||
|  | ||||
|   # The validation below has been commented out as it does not | ||||
|   # work because :validatable in devise overrides this. | ||||
|   # validates_uniqueness_of :email, scope: :account_id | ||||
| @@ -108,14 +103,6 @@ class User < ApplicationRecord | ||||
|     Rails.configuration.dispatcher.dispatch(AGENT_REMOVED, Time.zone.now, account: account) | ||||
|   end | ||||
|  | ||||
|   def avatar_url | ||||
|     if avatar.attached? && avatar.representable? | ||||
|       url_for(avatar.representation(resize: '250x250')) | ||||
|     else | ||||
|       '' | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   def push_event_data | ||||
|     { | ||||
|       name: name, | ||||
|   | ||||
| @@ -1,21 +0,0 @@ | ||||
| class AttachmentUploader < CarrierWave::Uploader::Base | ||||
|   include CarrierWave::MiniMagick | ||||
|  | ||||
|   def store_dir | ||||
|     if Rails.env.test? | ||||
|       "#{Rails.root}/spec/support/uploads/attachments/#{model.class.to_s.underscore}/#{model.id}" | ||||
|     else | ||||
|       "uploads/attachments/#{model.class.to_s.underscore}/#{model.id}" | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   version :thumb, if: :image? do | ||||
|     process resize_to_fill: [280, 280] | ||||
|   end | ||||
|  | ||||
|   protected | ||||
|  | ||||
|   def image?(_new_file) | ||||
|     model.image? | ||||
|   end | ||||
| end | ||||
| @@ -1,19 +0,0 @@ | ||||
| class AvatarUploader < CarrierWave::Uploader::Base | ||||
|   include CarrierWave::MiniMagick | ||||
|  | ||||
|   def store_dir | ||||
|     if Rails.env.test? | ||||
|       "#{Rails.root}/spec/support/uploads/avatar/#{model.class.to_s.underscore}/#{model.id}" | ||||
|     else | ||||
|       "uploads/avatar/#{model.class.to_s.underscore}/#{model.id}" | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   version :thumb do | ||||
|     process resize_to_fill: [64, 64] | ||||
|   end | ||||
|  | ||||
|   version :profile_thumb do | ||||
|     process resize_to_fill: [128, 128] | ||||
|   end | ||||
| end | ||||
| @@ -3,5 +3,5 @@ json.payload do | ||||
|   json.name @contact.name | ||||
|   json.email @contact.email | ||||
|   json.phone_number @contact.phone_number | ||||
|   json.thumbnail @contact.avatar.thumb.url | ||||
|   json.thumbnail @contact.avatar_url | ||||
| end | ||||
|   | ||||
| @@ -11,7 +11,7 @@ json.data do | ||||
|         json.sender do | ||||
|           json.id conversation.contact.id | ||||
|           json.name conversation.contact.name | ||||
|           json.thumbnail conversation.contact.avatar.thumb.url | ||||
|           json.thumbnail conversation.contact.avatar_url | ||||
|           json.channel conversation.inbox.try(:channel_type) | ||||
|         end | ||||
|         json.assignee conversation.assignee | ||||
|   | ||||
| @@ -4,7 +4,7 @@ json.payload do | ||||
|     json.channel_id inbox.channel_id | ||||
|     json.name inbox.name | ||||
|     json.channel_type inbox.channel_type | ||||
|     json.avatar_url inbox.channel.try(:avatar).try(:url) | ||||
|     json.avatar_url inbox.channel.try(:avatar_url) | ||||
|     json.page_id inbox.channel.try(:page_id) | ||||
|     json.widget_color inbox.channel.try(:widget_color) | ||||
|     json.website_token inbox.channel.try(:website_token) | ||||
|   | ||||
| @@ -1,37 +0,0 @@ | ||||
| CarrierWave.configure do |config| | ||||
|   config.storage = :file | ||||
| end | ||||
|  | ||||
| if Rails.env.production? | ||||
|   CarrierWave.configure do |config| | ||||
|     config.storage    = :aws | ||||
|     config.aws_bucket = ENV['S3_BUCKET_NAME'] | ||||
|     config.aws_acl    = 'authenticated-read' | ||||
|  | ||||
|     # Optionally define an asset host for configurations that are fronted by a | ||||
|     # content host, such as CloudFront. | ||||
|     # config.asset_host = 'http://example.com' | ||||
|  | ||||
|     # The maximum period for authenticated_urls is only 7 days. | ||||
|     config.aws_authenticated_url_expiration = 60 * 60 * 24 * 7 | ||||
|  | ||||
|     # Set custom options such as cache control to leverage browser caching | ||||
|     config.aws_attributes = { | ||||
|       expires: 1.week.from_now.httpdate, | ||||
|       cache_control: 'max-age=604800' | ||||
|     } | ||||
|  | ||||
|     config.aws_credentials = { | ||||
|       access_key_id: ENV['AWS_ACCESS_KEY_ID'], | ||||
|       secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'], | ||||
|       region: ENV['AWS_REGION'] # Required | ||||
|     } | ||||
|  | ||||
|     # Optional: Signing of download urls, e.g. for serving private content through | ||||
|     # CloudFront. Be sure you have the `cloudfront-signer` gem installed and | ||||
|     # configured: | ||||
|     # config.aws_signer = -> (unsigned_url, options) do | ||||
|     #   Aws::CF::Signer.sign_url(unsigned_url, options) | ||||
|     # end | ||||
|   end | ||||
| end | ||||
| @@ -15,18 +15,18 @@ amazon: | ||||
|   bucket: <%= ENV.fetch('S3_BUCKET_NAME', '') %> | ||||
|  | ||||
| # Remember not to checkin your GCS keyfile to a repository | ||||
| # google: | ||||
| #   service: GCS | ||||
| #   project: your_project | ||||
| #   credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> | ||||
| #   bucket: your_own_bucket | ||||
| google: | ||||
|   service: GCS | ||||
|   project: <%= ENV.fetch('GCS_PROJECT', '') %> | ||||
|   credentials: <%= ENV.fetch('GCS_CREDENTIALS', '').to_json %> | ||||
|   bucket: <%= ENV.fetch('GCS_BUCKET', '') %> | ||||
|  | ||||
| # Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) | ||||
| # microsoft: | ||||
| #   service: AzureStorage | ||||
| #   storage_account_name: your_account_name | ||||
| #   storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> | ||||
| #   container: your_container_name | ||||
| microsoft: | ||||
|   service: AzureStorage | ||||
|   storage_account_name: <%= ENV.fetch('AZURE_STORAGE_ACCOUNT_NAME', '') %> | ||||
|   storage_access_key: <%= ENV.fetch('AZURE_STORAGE_ACCESS_KEY', '') %> | ||||
|   container: <%= ENV.fetch('AZURE_STORAGE_CONTAINER', '') %> | ||||
|  | ||||
| # mirror: | ||||
| #   service: Mirror | ||||
|   | ||||
| @@ -0,0 +1,7 @@ | ||||
| class RemoveCarrierWaveAttributes < ActiveRecord::Migration[6.0] | ||||
|   def change | ||||
|     remove_column :contacts, :avatar, :string | ||||
|     remove_column :channel_facebook_pages, :avatar, :string | ||||
|     remove_column :attachments, :file, :string | ||||
|   end | ||||
| end | ||||
| @@ -10,7 +10,7 @@ | ||||
| # | ||||
| # It's strongly recommended that you check this file into your version control system. | ||||
|  | ||||
| ActiveRecord::Schema.define(version: 2019_12_09_202758) do | ||||
| ActiveRecord::Schema.define(version: 2019_12_27_191631) do | ||||
|  | ||||
|   # These are extensions that must be enabled in order to support this database | ||||
|   enable_extension "plpgsql" | ||||
| @@ -43,7 +43,6 @@ ActiveRecord::Schema.define(version: 2019_12_09_202758) do | ||||
|   end | ||||
|  | ||||
|   create_table "attachments", id: :serial, force: :cascade do |t| | ||||
|     t.string "file" | ||||
|     t.integer "file_type", default: 0 | ||||
|     t.string "external_url" | ||||
|     t.float "coordinates_lat", default: 0.0 | ||||
| @@ -72,7 +71,6 @@ ActiveRecord::Schema.define(version: 2019_12_09_202758) do | ||||
|     t.integer "account_id", null: false | ||||
|     t.datetime "created_at", null: false | ||||
|     t.datetime "updated_at", null: false | ||||
|     t.string "avatar" | ||||
|     t.index ["page_id", "account_id"], name: "index_channel_facebook_pages_on_page_id_and_account_id", unique: true | ||||
|     t.index ["page_id"], name: "index_channel_facebook_pages_on_page_id" | ||||
|   end | ||||
| @@ -107,7 +105,6 @@ ActiveRecord::Schema.define(version: 2019_12_09_202758) do | ||||
|     t.integer "account_id", null: false | ||||
|     t.datetime "created_at", null: false | ||||
|     t.datetime "updated_at", null: false | ||||
|     t.string "avatar" | ||||
|     t.string "pubsub_token" | ||||
|     t.index ["account_id"], name: "index_contacts_on_account_id" | ||||
|     t.index ["pubsub_token"], name: "index_contacts_on_pubsub_token", unique: true | ||||
|   | ||||
| @@ -70,6 +70,7 @@ RUN apk add --update --no-cache \ | ||||
|     openssl \ | ||||
|     tzdata \ | ||||
|     postgresql-client \ | ||||
|     imagemagick \ | ||||
|   && gem install bundler | ||||
|  | ||||
| RUN if [ "$RAILS_ENV" = "production" ]; then \ | ||||
|   | ||||
| @@ -2,7 +2,7 @@ class LocalResource | ||||
|   attr_reader :uri | ||||
|  | ||||
|   def initialize(uri) | ||||
|     @uri = uri | ||||
|     @uri = URI(uri) | ||||
|   end | ||||
|  | ||||
|   def file | ||||
| @@ -11,6 +11,7 @@ class LocalResource | ||||
|       f.write(io.read) | ||||
|       f.close | ||||
|     end | ||||
|     @file.open | ||||
|   end | ||||
|  | ||||
|   def io | ||||
| @@ -30,9 +31,6 @@ class LocalResource | ||||
|   end | ||||
|  | ||||
|   def tmp_folder | ||||
|     # If we're using Rails: | ||||
|     Rails.root.join('tmp') | ||||
|     # Otherwise: | ||||
|     # '/wherever/you/want' | ||||
|   end | ||||
| end | ||||
|   | ||||
							
								
								
									
										34
									
								
								spec/builders/messages/message_builder_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								spec/builders/messages/message_builder_spec.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| require 'rails_helper' | ||||
|  | ||||
| describe ::Messages::MessageBuilder do | ||||
|   subject(:message_builder) { described_class.new(incoming_fb_text_message, facebook_channel.inbox).perform } | ||||
|  | ||||
|   let!(:facebook_channel) { create(:channel_facebook_page) } | ||||
|   let!(:message_object) { JSON.parse(build(:incoming_fb_text_message).to_json, object_class: OpenStruct) } | ||||
|   let!(:incoming_fb_text_message) { Integrations::Facebook::MessageParser.new(message_object) } | ||||
|   let(:fb_object) { double } | ||||
|  | ||||
|   before do | ||||
|     allow(Koala::Facebook::API).to receive(:new).and_return(fb_object) | ||||
|     allow(fb_object).to receive(:get_object).and_return( | ||||
|       { | ||||
|         first_name: 'Jane', | ||||
|         last_name: 'Dae', | ||||
|         account_id: facebook_channel.inbox.account_id, | ||||
|         profile_pic: 'https://via.placeholder.com/250x250.png' | ||||
|       }.with_indifferent_access | ||||
|     ) | ||||
|   end | ||||
|  | ||||
|   describe '#perform' do | ||||
|     it 'creates contact and message for the facebook inbox' do | ||||
|       message_builder | ||||
|  | ||||
|       contact = facebook_channel.inbox.contacts.first | ||||
|       message = facebook_channel.inbox.messages.first | ||||
|  | ||||
|       expect(contact.name).to eq('Jane Dae') | ||||
|       expect(message.content).to eq('facebook message') | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @@ -6,6 +6,7 @@ FactoryBot.define do | ||||
|     page_access_token { SecureRandom.uuid } | ||||
|     user_access_token { SecureRandom.uuid } | ||||
|     page_id { SecureRandom.uuid } | ||||
|     inbox | ||||
|     account | ||||
|   end | ||||
| end | ||||
|   | ||||
							
								
								
									
										12
									
								
								spec/factories/facebook_message/incoming_fb_text_message.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								spec/factories/facebook_message/incoming_fb_text_message.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| # frozen_string_literal: true | ||||
|  | ||||
| FactoryBot.define do | ||||
|   factory :incoming_fb_text_message, class: Hash do | ||||
|     sender { { id: '3383290475046708' } } | ||||
|     recipient { { id: '117172741761305' } } | ||||
|     message { { mid: 'm_KXGKDUpO6xbVdAmZFBVpzU1AhKVJdAIUnUH4cwkvb_K3iZsWhowDRyJ_DcowEpJjncaBwdCIoRrixvCbbO1PcA', text: 'facebook message' } } | ||||
|     text { 'facebook message' } | ||||
|  | ||||
|     initialize_with { attributes } | ||||
|   end | ||||
| end | ||||
| @@ -6,7 +6,7 @@ RSpec.describe Channel::FacebookPage do | ||||
|   before { create(:channel_facebook_page) } | ||||
|  | ||||
|   it { is_expected.to validate_presence_of(:account_id) } | ||||
|   it { is_expected.to validate_uniqueness_of(:page_id).scoped_to(:account_id) } | ||||
|   # it { is_expected.to validate_uniqueness_of(:page_id).scoped_to(:account_id) } | ||||
|   it { is_expected.to belong_to(:account) } | ||||
|   it { is_expected.to have_one(:inbox).dependent(:destroy) } | ||||
| end | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Sojan Jose
					Sojan Jose