mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-11-04 04:57:51 +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:
 | 
					Metrics/LineLength:
 | 
				
			||||||
  Max: 150
 | 
					  Max: 150
 | 
				
			||||||
 | 
					Metrics/ClassLength:
 | 
				
			||||||
 | 
					  Max: 125
 | 
				
			||||||
RSpec/ExampleLength:
 | 
					RSpec/ExampleLength:
 | 
				
			||||||
  Max: 15
 | 
					  Max: 15
 | 
				
			||||||
Documentation:
 | 
					Documentation:
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								Gemfile
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								Gemfile
									
									
									
									
									
								
							@@ -23,6 +23,9 @@ gem 'valid_email2'
 | 
				
			|||||||
gem 'uglifier'
 | 
					gem 'uglifier'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##-- for active storage --##
 | 
					##-- for active storage --##
 | 
				
			||||||
 | 
					gem 'aws-sdk-s3', require: false
 | 
				
			||||||
 | 
					gem 'azure-storage', require: false
 | 
				
			||||||
 | 
					gem 'google-cloud-storage', require: false
 | 
				
			||||||
gem 'mini_magick'
 | 
					gem 'mini_magick'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##-- gems for database --#
 | 
					##-- gems for database --#
 | 
				
			||||||
@@ -68,9 +71,7 @@ gem 'haikunator'
 | 
				
			|||||||
gem 'brakeman'
 | 
					gem 'brakeman'
 | 
				
			||||||
gem 'sentry-raven'
 | 
					gem 'sentry-raven'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##-- TODO: move these gems to appropriate groups --##
 | 
					##-- background job processing --##
 | 
				
			||||||
# remove this gem in favor of active storage -  github #158
 | 
					 | 
				
			||||||
gem 'carrierwave-aws'
 | 
					 | 
				
			||||||
gem 'sidekiq'
 | 
					gem 'sidekiq'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
group :development do
 | 
					group :development do
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										76
									
								
								Gemfile.lock
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								Gemfile.lock
									
									
									
									
									
								
							@@ -68,7 +68,7 @@ GEM
 | 
				
			|||||||
    ast (2.4.0)
 | 
					    ast (2.4.0)
 | 
				
			||||||
    attr_extras (6.2.1)
 | 
					    attr_extras (6.2.1)
 | 
				
			||||||
    aws-eventstream (1.0.3)
 | 
					    aws-eventstream (1.0.3)
 | 
				
			||||||
    aws-partitions (1.259.0)
 | 
					    aws-partitions (1.262.0)
 | 
				
			||||||
    aws-sdk-core (3.86.0)
 | 
					    aws-sdk-core (3.86.0)
 | 
				
			||||||
      aws-eventstream (~> 1.0, >= 1.0.2)
 | 
					      aws-eventstream (~> 1.0, >= 1.0.2)
 | 
				
			||||||
      aws-partitions (~> 1, >= 1.239.0)
 | 
					      aws-partitions (~> 1, >= 1.239.0)
 | 
				
			||||||
@@ -87,6 +87,15 @@ GEM
 | 
				
			|||||||
      descendants_tracker (~> 0.0.4)
 | 
					      descendants_tracker (~> 0.0.4)
 | 
				
			||||||
      ice_nine (~> 0.11.0)
 | 
					      ice_nine (~> 0.11.0)
 | 
				
			||||||
      thread_safe (~> 0.3, >= 0.3.1)
 | 
					      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)
 | 
					    bcrypt (3.1.13)
 | 
				
			||||||
    bindex (0.8.1)
 | 
					    bindex (0.8.1)
 | 
				
			||||||
    bootsnap (1.4.5)
 | 
					    bootsnap (1.4.5)
 | 
				
			||||||
@@ -104,16 +113,6 @@ GEM
 | 
				
			|||||||
      bundler (>= 1.2.0, < 3)
 | 
					      bundler (>= 1.2.0, < 3)
 | 
				
			||||||
      thor (~> 0.18)
 | 
					      thor (~> 0.18)
 | 
				
			||||||
    byebug (11.0.1)
 | 
					    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)
 | 
					    chargebee (2.7.1)
 | 
				
			||||||
      json_pure (~> 2.1)
 | 
					      json_pure (~> 2.1)
 | 
				
			||||||
      rest-client (>= 1.8, < 3.0)
 | 
					      rest-client (>= 1.8, < 3.0)
 | 
				
			||||||
@@ -123,6 +122,8 @@ GEM
 | 
				
			|||||||
    concurrent-ruby (1.1.5)
 | 
					    concurrent-ruby (1.1.5)
 | 
				
			||||||
    connection_pool (2.2.2)
 | 
					    connection_pool (2.2.2)
 | 
				
			||||||
    crass (1.0.5)
 | 
					    crass (1.0.5)
 | 
				
			||||||
 | 
					    declarative (0.0.10)
 | 
				
			||||||
 | 
					    declarative-option (0.1.0)
 | 
				
			||||||
    descendants_tracker (0.0.4)
 | 
					    descendants_tracker (0.0.4)
 | 
				
			||||||
      thread_safe (~> 0.3, >= 0.3.1)
 | 
					      thread_safe (~> 0.3, >= 0.3.1)
 | 
				
			||||||
    devise (4.7.1)
 | 
					    devise (4.7.1)
 | 
				
			||||||
@@ -136,6 +137,7 @@ GEM
 | 
				
			|||||||
      devise (> 3.5.2, < 5)
 | 
					      devise (> 3.5.2, < 5)
 | 
				
			||||||
      rails (>= 4.2.0, < 6.1)
 | 
					      rails (>= 4.2.0, < 6.1)
 | 
				
			||||||
    diff-lcs (1.3)
 | 
					    diff-lcs (1.3)
 | 
				
			||||||
 | 
					    digest-crc (0.4.1)
 | 
				
			||||||
    docile (1.3.2)
 | 
					    docile (1.3.2)
 | 
				
			||||||
    domain_name (0.5.20190701)
 | 
					    domain_name (0.5.20190701)
 | 
				
			||||||
      unf (>= 0.0.5, < 1.0.0)
 | 
					      unf (>= 0.0.5, < 1.0.0)
 | 
				
			||||||
@@ -158,10 +160,38 @@ GEM
 | 
				
			|||||||
      i18n (>= 1.6, < 1.8)
 | 
					      i18n (>= 1.6, < 1.8)
 | 
				
			||||||
    faraday (0.17.1)
 | 
					    faraday (0.17.1)
 | 
				
			||||||
      multipart-post (>= 1.2, < 3)
 | 
					      multipart-post (>= 1.2, < 3)
 | 
				
			||||||
 | 
					    faraday_middleware (0.13.1)
 | 
				
			||||||
 | 
					      faraday (>= 0.7.4, < 1.0)
 | 
				
			||||||
    ffi (1.11.3)
 | 
					    ffi (1.11.3)
 | 
				
			||||||
    foreman (0.86.0)
 | 
					    foreman (0.86.0)
 | 
				
			||||||
    globalid (0.4.2)
 | 
					    globalid (0.4.2)
 | 
				
			||||||
      activesupport (>= 4.2.0)
 | 
					      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)
 | 
					    haikunator (1.1.0)
 | 
				
			||||||
    hashie (4.0.0)
 | 
					    hashie (4.0.0)
 | 
				
			||||||
    http (3.3.0)
 | 
					    http (3.3.0)
 | 
				
			||||||
@@ -177,12 +207,10 @@ GEM
 | 
				
			|||||||
    httparty (0.17.3)
 | 
					    httparty (0.17.3)
 | 
				
			||||||
      mime-types (~> 3.0)
 | 
					      mime-types (~> 3.0)
 | 
				
			||||||
      multi_xml (>= 0.5.2)
 | 
					      multi_xml (>= 0.5.2)
 | 
				
			||||||
 | 
					    httpclient (2.8.3)
 | 
				
			||||||
    i18n (1.7.0)
 | 
					    i18n (1.7.0)
 | 
				
			||||||
      concurrent-ruby (~> 1.0)
 | 
					      concurrent-ruby (~> 1.0)
 | 
				
			||||||
    ice_nine (0.11.2)
 | 
					    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)
 | 
					    inflecto (0.0.2)
 | 
				
			||||||
    jaro_winkler (1.5.4)
 | 
					    jaro_winkler (1.5.4)
 | 
				
			||||||
    jbuilder (2.9.1)
 | 
					    jbuilder (2.9.1)
 | 
				
			||||||
@@ -221,6 +249,7 @@ GEM
 | 
				
			|||||||
      mini_mime (>= 0.1.1)
 | 
					      mini_mime (>= 0.1.1)
 | 
				
			||||||
    marcel (0.3.3)
 | 
					    marcel (0.3.3)
 | 
				
			||||||
      mimemagic (~> 0.3.2)
 | 
					      mimemagic (~> 0.3.2)
 | 
				
			||||||
 | 
					    memoist (0.16.2)
 | 
				
			||||||
    memoizable (0.4.2)
 | 
					    memoizable (0.4.2)
 | 
				
			||||||
      thread_safe (~> 0.3, >= 0.3.1)
 | 
					      thread_safe (~> 0.3, >= 0.3.1)
 | 
				
			||||||
    method_source (0.9.2)
 | 
					    method_source (0.9.2)
 | 
				
			||||||
@@ -234,6 +263,7 @@ GEM
 | 
				
			|||||||
    minitest (5.13.0)
 | 
					    minitest (5.13.0)
 | 
				
			||||||
    mock_redis (0.22.0)
 | 
					    mock_redis (0.22.0)
 | 
				
			||||||
    msgpack (1.3.1)
 | 
					    msgpack (1.3.1)
 | 
				
			||||||
 | 
					    multi_json (1.14.1)
 | 
				
			||||||
    multi_xml (0.6.0)
 | 
					    multi_xml (0.6.0)
 | 
				
			||||||
    multipart-post (2.1.1)
 | 
					    multipart-post (2.1.1)
 | 
				
			||||||
    naught (1.1.0)
 | 
					    naught (1.1.0)
 | 
				
			||||||
@@ -243,6 +273,7 @@ GEM
 | 
				
			|||||||
    nokogiri (1.10.7)
 | 
					    nokogiri (1.10.7)
 | 
				
			||||||
      mini_portile2 (~> 2.4.0)
 | 
					      mini_portile2 (~> 2.4.0)
 | 
				
			||||||
    orm_adapter (0.5.0)
 | 
					    orm_adapter (0.5.0)
 | 
				
			||||||
 | 
					    os (1.0.1)
 | 
				
			||||||
    parallel (1.19.1)
 | 
					    parallel (1.19.1)
 | 
				
			||||||
    parser (2.6.5.0)
 | 
					    parser (2.6.5.0)
 | 
				
			||||||
      ast (~> 2.4.0)
 | 
					      ast (~> 2.4.0)
 | 
				
			||||||
@@ -307,6 +338,10 @@ GEM
 | 
				
			|||||||
      redis-store (>= 1.6, < 2)
 | 
					      redis-store (>= 1.6, < 2)
 | 
				
			||||||
    redis-store (1.8.1)
 | 
					    redis-store (1.8.1)
 | 
				
			||||||
      redis (>= 4, < 5)
 | 
					      redis (>= 4, < 5)
 | 
				
			||||||
 | 
					    representable (3.0.4)
 | 
				
			||||||
 | 
					      declarative (< 0.1.0)
 | 
				
			||||||
 | 
					      declarative-option (< 0.2.0)
 | 
				
			||||||
 | 
					      uber (< 0.2.0)
 | 
				
			||||||
    responders (3.0.0)
 | 
					    responders (3.0.0)
 | 
				
			||||||
      actionpack (>= 5.0)
 | 
					      actionpack (>= 5.0)
 | 
				
			||||||
      railties (>= 5.0)
 | 
					      railties (>= 5.0)
 | 
				
			||||||
@@ -315,6 +350,7 @@ GEM
 | 
				
			|||||||
      http-cookie (>= 1.0.2, < 2.0)
 | 
					      http-cookie (>= 1.0.2, < 2.0)
 | 
				
			||||||
      mime-types (>= 1.16, < 4.0)
 | 
					      mime-types (>= 1.16, < 4.0)
 | 
				
			||||||
      netrc (~> 0.8)
 | 
					      netrc (~> 0.8)
 | 
				
			||||||
 | 
					    retriable (3.1.2)
 | 
				
			||||||
    rspec-core (3.9.0)
 | 
					    rspec-core (3.9.0)
 | 
				
			||||||
      rspec-support (~> 3.9.0)
 | 
					      rspec-support (~> 3.9.0)
 | 
				
			||||||
    rspec-expectations (3.9.0)
 | 
					    rspec-expectations (3.9.0)
 | 
				
			||||||
@@ -347,8 +383,6 @@ GEM
 | 
				
			|||||||
    rubocop-rspec (1.37.1)
 | 
					    rubocop-rspec (1.37.1)
 | 
				
			||||||
      rubocop (>= 0.68.1)
 | 
					      rubocop (>= 0.68.1)
 | 
				
			||||||
    ruby-progressbar (1.10.1)
 | 
					    ruby-progressbar (1.10.1)
 | 
				
			||||||
    ruby-vips (2.0.16)
 | 
					 | 
				
			||||||
      ffi (~> 1.9)
 | 
					 | 
				
			||||||
    seed_dump (3.3.1)
 | 
					    seed_dump (3.3.1)
 | 
				
			||||||
      activerecord (>= 4)
 | 
					      activerecord (>= 4)
 | 
				
			||||||
      activesupport (>= 4)
 | 
					      activesupport (>= 4)
 | 
				
			||||||
@@ -361,6 +395,11 @@ GEM
 | 
				
			|||||||
      rack (>= 2.0.0)
 | 
					      rack (>= 2.0.0)
 | 
				
			||||||
      rack-protection (>= 2.0.0)
 | 
					      rack-protection (>= 2.0.0)
 | 
				
			||||||
      redis (>= 4.1.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)
 | 
					    simple_oauth (0.3.1)
 | 
				
			||||||
    simplecov (0.17.1)
 | 
					    simplecov (0.17.1)
 | 
				
			||||||
      docile (~> 1.1)
 | 
					      docile (~> 1.1)
 | 
				
			||||||
@@ -402,6 +441,7 @@ GEM
 | 
				
			|||||||
      thread_safe (~> 0.1)
 | 
					      thread_safe (~> 0.1)
 | 
				
			||||||
    tzinfo-data (1.2019.3)
 | 
					    tzinfo-data (1.2019.3)
 | 
				
			||||||
      tzinfo (>= 1.0.0)
 | 
					      tzinfo (>= 1.0.0)
 | 
				
			||||||
 | 
					    uber (0.1.0)
 | 
				
			||||||
    uglifier (4.2.0)
 | 
					    uglifier (4.2.0)
 | 
				
			||||||
      execjs (>= 0.3.0, < 3)
 | 
					      execjs (>= 0.3.0, < 3)
 | 
				
			||||||
    unf (0.1.4)
 | 
					    unf (0.1.4)
 | 
				
			||||||
@@ -442,13 +482,14 @@ DEPENDENCIES
 | 
				
			|||||||
  acts-as-taggable-on
 | 
					  acts-as-taggable-on
 | 
				
			||||||
  annotate
 | 
					  annotate
 | 
				
			||||||
  attr_extras
 | 
					  attr_extras
 | 
				
			||||||
 | 
					  aws-sdk-s3
 | 
				
			||||||
 | 
					  azure-storage
 | 
				
			||||||
  bootsnap
 | 
					  bootsnap
 | 
				
			||||||
  brakeman
 | 
					  brakeman
 | 
				
			||||||
  browser
 | 
					  browser
 | 
				
			||||||
  bullet
 | 
					  bullet
 | 
				
			||||||
  bundle-audit
 | 
					  bundle-audit
 | 
				
			||||||
  byebug
 | 
					  byebug
 | 
				
			||||||
  carrierwave-aws
 | 
					 | 
				
			||||||
  chargebee
 | 
					  chargebee
 | 
				
			||||||
  devise
 | 
					  devise
 | 
				
			||||||
  devise_token_auth
 | 
					  devise_token_auth
 | 
				
			||||||
@@ -457,6 +498,7 @@ DEPENDENCIES
 | 
				
			|||||||
  factory_bot_rails
 | 
					  factory_bot_rails
 | 
				
			||||||
  faker
 | 
					  faker
 | 
				
			||||||
  foreman
 | 
					  foreman
 | 
				
			||||||
 | 
					  google-cloud-storage
 | 
				
			||||||
  haikunator
 | 
					  haikunator
 | 
				
			||||||
  hashie
 | 
					  hashie
 | 
				
			||||||
  jbuilder
 | 
					  jbuilder
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,19 +36,26 @@ module Messages
 | 
				
			|||||||
    def build_contact
 | 
					    def build_contact
 | 
				
			||||||
      return if contact.present?
 | 
					      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)
 | 
					      ContactInbox.create(contact: contact, inbox: @inbox, source_id: @sender_id)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def build_message
 | 
					    def build_message
 | 
				
			||||||
      @message = conversation.messages.new(message_params)
 | 
					      @message = conversation.messages.create!(message_params)
 | 
				
			||||||
      (response.attachments || []).each do |attachment|
 | 
					      (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
 | 
					      end
 | 
				
			||||||
      @message.save!
 | 
					 | 
				
			||||||
    end
 | 
					    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
 | 
					    def conversation
 | 
				
			||||||
      @conversation ||= Conversation.find_by(conversation_params) || Conversation.create!(conversation_params)
 | 
					      @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'}",
 | 
					        name: "#{result['first_name'] || 'John'} #{result['last_name'] || 'Doe'}",
 | 
				
			||||||
        account_id: @inbox.account_id,
 | 
					        account_id: @inbox.account_id,
 | 
				
			||||||
        remote_avatar_url: result['profile_pic'] || nil
 | 
					        remote_avatar_url: result['profile_pic'] || ''
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,8 +12,9 @@ class Api::V1::CallbacksController < ApplicationController
 | 
				
			|||||||
    inbox_name = params[:inbox_name]
 | 
					    inbox_name = params[:inbox_name]
 | 
				
			||||||
    facebook_channel = current_account.facebook_pages.create!(
 | 
					    facebook_channel = current_account.facebook_pages.create!(
 | 
				
			||||||
      name: page_name, page_id: page_id, user_access_token: user_access_token,
 | 
					      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)
 | 
					    inbox = current_account.inboxes.create!(name: inbox_name, channel: facebook_channel)
 | 
				
			||||||
    render json: inbox
 | 
					    render json: inbox
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
@@ -79,7 +80,12 @@ class Api::V1::CallbacksController < ApplicationController
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
  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
 | 
					    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)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
    <div class="contact--profile">
 | 
					    <div class="contact--profile">
 | 
				
			||||||
      <div class="contact--info">
 | 
					      <div class="contact--info">
 | 
				
			||||||
        <thumbnail
 | 
					        <thumbnail
 | 
				
			||||||
          :src="contact.avatar_url"
 | 
					          :src="contact.thumbnail"
 | 
				
			||||||
          size="56px"
 | 
					          size="56px"
 | 
				
			||||||
          :badge="contact.channel"
 | 
					          :badge="contact.channel"
 | 
				
			||||||
          :username="contact.name"
 | 
					          :username="contact.name"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,6 @@
 | 
				
			|||||||
#  extension        :string
 | 
					#  extension        :string
 | 
				
			||||||
#  external_url     :string
 | 
					#  external_url     :string
 | 
				
			||||||
#  fallback_title   :string
 | 
					#  fallback_title   :string
 | 
				
			||||||
#  file             :string
 | 
					 | 
				
			||||||
#  file_type        :integer          default("image")
 | 
					#  file_type        :integer          default("image")
 | 
				
			||||||
#  created_at       :datetime         not null
 | 
					#  created_at       :datetime         not null
 | 
				
			||||||
#  updated_at       :datetime         not null
 | 
					#  updated_at       :datetime         not null
 | 
				
			||||||
@@ -19,12 +18,12 @@
 | 
				
			|||||||
require 'uri'
 | 
					require 'uri'
 | 
				
			||||||
require 'open-uri'
 | 
					require 'open-uri'
 | 
				
			||||||
class Attachment < ApplicationRecord
 | 
					class Attachment < ApplicationRecord
 | 
				
			||||||
 | 
					  include Rails.application.routes.url_helpers
 | 
				
			||||||
  belongs_to :account
 | 
					  belongs_to :account
 | 
				
			||||||
  belongs_to :message
 | 
					  belongs_to :message
 | 
				
			||||||
  mount_uploader :file, AttachmentUploader # used for images
 | 
					  has_one_attached :file
 | 
				
			||||||
  enum file_type: [:image, :audio, :video, :file, :location, :fallback]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  before_create :set_file_extension
 | 
					  enum file_type: [:image, :audio, :video, :file, :location, :fallback]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def push_event_data
 | 
					  def push_event_data
 | 
				
			||||||
    return base_data.merge(location_metadata) if file_type.to_sym == :location
 | 
					    return base_data.merge(location_metadata) if file_type.to_sym == :location
 | 
				
			||||||
@@ -68,13 +67,7 @@ class Attachment < ApplicationRecord
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def set_file_extension
 | 
					  def file_url
 | 
				
			||||||
    if external_url && !fallback?
 | 
					    file.attached? ? url_for(file) : ''
 | 
				
			||||||
      self.extension = begin
 | 
					 | 
				
			||||||
                         Pathname.new(URI(external_url).path).extname
 | 
					 | 
				
			||||||
                       rescue StandardError
 | 
					 | 
				
			||||||
                         nil
 | 
					 | 
				
			||||||
                       end
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,6 @@
 | 
				
			|||||||
# Table name: channel_facebook_pages
 | 
					# Table name: channel_facebook_pages
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  id                :integer          not null, primary key
 | 
					#  id                :integer          not null, primary key
 | 
				
			||||||
#  avatar            :string
 | 
					 | 
				
			||||||
#  name              :string           not null
 | 
					#  name              :string           not null
 | 
				
			||||||
#  page_access_token :string           not null
 | 
					#  page_access_token :string           not null
 | 
				
			||||||
#  user_access_token :string           not null
 | 
					#  user_access_token :string           not null
 | 
				
			||||||
@@ -20,11 +19,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
module Channel
 | 
					module Channel
 | 
				
			||||||
  class FacebookPage < ApplicationRecord
 | 
					  class FacebookPage < ApplicationRecord
 | 
				
			||||||
 | 
					    include Avatarable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    self.table_name = 'channel_facebook_pages'
 | 
					    self.table_name = 'channel_facebook_pages'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    validates :account_id, presence: true
 | 
					    validates :account_id, presence: true
 | 
				
			||||||
    validates :page_id, uniqueness: { scope: :account_id }
 | 
					    validates :page_id, uniqueness: { scope: :account_id }
 | 
				
			||||||
    mount_uploader :avatar, AvatarUploader
 | 
					    has_one_attached :avatar
 | 
				
			||||||
    belongs_to :account
 | 
					    belongs_to :account
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    has_one :inbox, as: :channel, dependent: :destroy
 | 
					    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
 | 
					# Table name: contacts
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  id           :integer          not null, primary key
 | 
					#  id           :integer          not null, primary key
 | 
				
			||||||
#  avatar       :string
 | 
					 | 
				
			||||||
#  email        :string
 | 
					#  email        :string
 | 
				
			||||||
#  name         :string
 | 
					#  name         :string
 | 
				
			||||||
#  phone_number :string
 | 
					#  phone_number :string
 | 
				
			||||||
@@ -20,13 +19,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class Contact < ApplicationRecord
 | 
					class Contact < ApplicationRecord
 | 
				
			||||||
  include Pubsubable
 | 
					  include Pubsubable
 | 
				
			||||||
 | 
					  include Avatarable
 | 
				
			||||||
  validates :account_id, presence: true
 | 
					  validates :account_id, presence: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  belongs_to :account
 | 
					  belongs_to :account
 | 
				
			||||||
  has_many :conversations, dependent: :destroy
 | 
					  has_many :conversations, dependent: :destroy
 | 
				
			||||||
  has_many :contact_inboxes, dependent: :destroy
 | 
					  has_many :contact_inboxes, dependent: :destroy
 | 
				
			||||||
  has_many :inboxes, through: :contact_inboxes
 | 
					  has_many :inboxes, through: :contact_inboxes
 | 
				
			||||||
  mount_uploader :avatar, AvatarUploader
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def get_source_id(inbox_id)
 | 
					  def get_source_id(inbox_id)
 | 
				
			||||||
    contact_inboxes.find_by!(inbox_id: inbox_id).source_id
 | 
					    contact_inboxes.find_by!(inbox_id: inbox_id).source_id
 | 
				
			||||||
@@ -36,7 +35,7 @@ class Contact < ApplicationRecord
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
      id: id,
 | 
					      id: id,
 | 
				
			||||||
      name: name,
 | 
					      name: name,
 | 
				
			||||||
      thumbnail: avatar.thumb.url,
 | 
					      thumbnail: avatar_url,
 | 
				
			||||||
      pubsub_token: pubsub_token
 | 
					      pubsub_token: pubsub_token
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,11 +68,10 @@ class Inbox < ApplicationRecord
 | 
				
			|||||||
    Facebook::Messenger::Subscriptions.subscribe(
 | 
					    Facebook::Messenger::Subscriptions.subscribe(
 | 
				
			||||||
      access_token: channel.page_access_token,
 | 
					      access_token: channel.page_access_token,
 | 
				
			||||||
      subscribed_fields: %w[
 | 
					      subscribed_fields: %w[
 | 
				
			||||||
        message_mention messages messaging_account_linking messaging_checkout_updates
 | 
					        messages messaging_postbacks messaging_optins message_deliveries
 | 
				
			||||||
        message_echoes message_deliveries messaging_game_plays messaging_optins messaging_optouts
 | 
					        message_reads messaging_payments messaging_pre_checkouts messaging_checkout_updates
 | 
				
			||||||
        messaging_payments messaging_postbacks messaging_pre_checkouts message_reads messaging_referrals
 | 
					        messaging_account_linking messaging_referrals message_echoes messaging_game_plays
 | 
				
			||||||
        messaging_handovers messaging_policy_enforcement messaging_page_feedback
 | 
					        standby messaging_handovers messaging_policy_enforcement message_reactions
 | 
				
			||||||
        messaging_appointments messaging_direct_sends
 | 
					 | 
				
			||||||
      ]
 | 
					      ]
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,6 +47,7 @@ class User < ApplicationRecord
 | 
				
			|||||||
  include DeviseTokenAuth::Concerns::User
 | 
					  include DeviseTokenAuth::Concerns::User
 | 
				
			||||||
  include Events::Types
 | 
					  include Events::Types
 | 
				
			||||||
  include Pubsubable
 | 
					  include Pubsubable
 | 
				
			||||||
 | 
					  include Avatarable
 | 
				
			||||||
  include Rails.application.routes.url_helpers
 | 
					  include Rails.application.routes.url_helpers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  devise :database_authenticatable,
 | 
					  devise :database_authenticatable,
 | 
				
			||||||
@@ -57,12 +58,6 @@ class User < ApplicationRecord
 | 
				
			|||||||
         :validatable,
 | 
					         :validatable,
 | 
				
			||||||
         :confirmable
 | 
					         :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
 | 
					  # The validation below has been commented out as it does not
 | 
				
			||||||
  # work because :validatable in devise overrides this.
 | 
					  # work because :validatable in devise overrides this.
 | 
				
			||||||
  # validates_uniqueness_of :email, scope: :account_id
 | 
					  # 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)
 | 
					    Rails.configuration.dispatcher.dispatch(AGENT_REMOVED, Time.zone.now, account: account)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def avatar_url
 | 
					 | 
				
			||||||
    if avatar.attached? && avatar.representable?
 | 
					 | 
				
			||||||
      url_for(avatar.representation(resize: '250x250'))
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      ''
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def push_event_data
 | 
					  def push_event_data
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      name: name,
 | 
					      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.name @contact.name
 | 
				
			||||||
  json.email @contact.email
 | 
					  json.email @contact.email
 | 
				
			||||||
  json.phone_number @contact.phone_number
 | 
					  json.phone_number @contact.phone_number
 | 
				
			||||||
  json.thumbnail @contact.avatar.thumb.url
 | 
					  json.thumbnail @contact.avatar_url
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@ json.data do
 | 
				
			|||||||
        json.sender do
 | 
					        json.sender do
 | 
				
			||||||
          json.id conversation.contact.id
 | 
					          json.id conversation.contact.id
 | 
				
			||||||
          json.name conversation.contact.name
 | 
					          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)
 | 
					          json.channel conversation.inbox.try(:channel_type)
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
        json.assignee conversation.assignee
 | 
					        json.assignee conversation.assignee
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ json.payload do
 | 
				
			|||||||
    json.channel_id inbox.channel_id
 | 
					    json.channel_id inbox.channel_id
 | 
				
			||||||
    json.name inbox.name
 | 
					    json.name inbox.name
 | 
				
			||||||
    json.channel_type inbox.channel_type
 | 
					    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.page_id inbox.channel.try(:page_id)
 | 
				
			||||||
    json.widget_color inbox.channel.try(:widget_color)
 | 
					    json.widget_color inbox.channel.try(:widget_color)
 | 
				
			||||||
    json.website_token inbox.channel.try(:website_token)
 | 
					    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', '') %>
 | 
					  bucket: <%= ENV.fetch('S3_BUCKET_NAME', '') %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Remember not to checkin your GCS keyfile to a repository
 | 
					# Remember not to checkin your GCS keyfile to a repository
 | 
				
			||||||
# google:
 | 
					google:
 | 
				
			||||||
#   service: GCS
 | 
					  service: GCS
 | 
				
			||||||
#   project: your_project
 | 
					  project: <%= ENV.fetch('GCS_PROJECT', '') %>
 | 
				
			||||||
#   credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
 | 
					  credentials: <%= ENV.fetch('GCS_CREDENTIALS', '').to_json %>
 | 
				
			||||||
#   bucket: your_own_bucket
 | 
					  bucket: <%= ENV.fetch('GCS_BUCKET', '') %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
 | 
					# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
 | 
				
			||||||
# microsoft:
 | 
					microsoft:
 | 
				
			||||||
#   service: AzureStorage
 | 
					  service: AzureStorage
 | 
				
			||||||
#   storage_account_name: your_account_name
 | 
					  storage_account_name: <%= ENV.fetch('AZURE_STORAGE_ACCOUNT_NAME', '') %>
 | 
				
			||||||
#   storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
 | 
					  storage_access_key: <%= ENV.fetch('AZURE_STORAGE_ACCESS_KEY', '') %>
 | 
				
			||||||
#   container: your_container_name
 | 
					  container: <%= ENV.fetch('AZURE_STORAGE_CONTAINER', '') %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# mirror:
 | 
					# mirror:
 | 
				
			||||||
#   service: 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.
 | 
					# 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
 | 
					  # These are extensions that must be enabled in order to support this database
 | 
				
			||||||
  enable_extension "plpgsql"
 | 
					  enable_extension "plpgsql"
 | 
				
			||||||
@@ -43,7 +43,6 @@ ActiveRecord::Schema.define(version: 2019_12_09_202758) do
 | 
				
			|||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  create_table "attachments", id: :serial, force: :cascade do |t|
 | 
					  create_table "attachments", id: :serial, force: :cascade do |t|
 | 
				
			||||||
    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
 | 
				
			||||||
@@ -72,7 +71,6 @@ ActiveRecord::Schema.define(version: 2019_12_09_202758) do
 | 
				
			|||||||
    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.index ["page_id", "account_id"], name: "index_channel_facebook_pages_on_page_id_and_account_id", unique: true
 | 
					    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"
 | 
					    t.index ["page_id"], name: "index_channel_facebook_pages_on_page_id"
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
@@ -107,7 +105,6 @@ ActiveRecord::Schema.define(version: 2019_12_09_202758) do
 | 
				
			|||||||
    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 "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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -70,6 +70,7 @@ RUN apk add --update --no-cache \
 | 
				
			|||||||
    openssl \
 | 
					    openssl \
 | 
				
			||||||
    tzdata \
 | 
					    tzdata \
 | 
				
			||||||
    postgresql-client \
 | 
					    postgresql-client \
 | 
				
			||||||
 | 
					    imagemagick \
 | 
				
			||||||
  && gem install bundler
 | 
					  && gem install bundler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN if [ "$RAILS_ENV" = "production" ]; then \
 | 
					RUN if [ "$RAILS_ENV" = "production" ]; then \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ class LocalResource
 | 
				
			|||||||
  attr_reader :uri
 | 
					  attr_reader :uri
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def initialize(uri)
 | 
					  def initialize(uri)
 | 
				
			||||||
    @uri = uri
 | 
					    @uri = URI(uri)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def file
 | 
					  def file
 | 
				
			||||||
@@ -11,6 +11,7 @@ class LocalResource
 | 
				
			|||||||
      f.write(io.read)
 | 
					      f.write(io.read)
 | 
				
			||||||
      f.close
 | 
					      f.close
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					    @file.open
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def io
 | 
					  def io
 | 
				
			||||||
@@ -30,9 +31,6 @@ class LocalResource
 | 
				
			|||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def tmp_folder
 | 
					  def tmp_folder
 | 
				
			||||||
    # If we're using Rails:
 | 
					 | 
				
			||||||
    Rails.root.join('tmp')
 | 
					    Rails.root.join('tmp')
 | 
				
			||||||
    # Otherwise:
 | 
					 | 
				
			||||||
    # '/wherever/you/want'
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
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 }
 | 
					    page_access_token { SecureRandom.uuid }
 | 
				
			||||||
    user_access_token { SecureRandom.uuid }
 | 
					    user_access_token { SecureRandom.uuid }
 | 
				
			||||||
    page_id { SecureRandom.uuid }
 | 
					    page_id { SecureRandom.uuid }
 | 
				
			||||||
 | 
					    inbox
 | 
				
			||||||
    account
 | 
					    account
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
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) }
 | 
					  before { create(:channel_facebook_page) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it { is_expected.to validate_presence_of(:account_id) }
 | 
					  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 belong_to(:account) }
 | 
				
			||||||
  it { is_expected.to have_one(:inbox).dependent(:destroy) }
 | 
					  it { is_expected.to have_one(:inbox).dependent(:destroy) }
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user