Chore: Switch from Carrierwave to ActiveStorage (#393)
This commit is contained in:
parent
f02d422b6a
commit
f875a09fb7
29 changed files with 192 additions and 164 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue