Routine weeding of the codebase (#163)

* Routine weeding of the codebase
* fix the spec
This commit is contained in:
Sojan Jose 2019-10-20 16:19:12 +05:30 committed by GitHub
parent 94c6d6db6f
commit 2099dc01a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 228 additions and 244 deletions

View file

@ -52,7 +52,7 @@ foreman start -f Procfile.dev
```bash ```bash
http://localhost:3000 http://localhost:3000
user name: larry@google.com user name: john@acme.inc
password: 123456 password: 123456
``` ```

View file

@ -1,3 +0,0 @@
class Channel < ApplicationRecord
has_many :conversations
end

View file

@ -0,0 +1,26 @@
module Channel
class FacebookPage < ApplicationRecord
self.table_name = 'channel_facebook_pages'
validates :account_id, presence: true
validates_uniqueness_of :page_id, scope: :account_id
mount_uploader :avatar, AvatarUploader
belongs_to :account
has_one :inbox, as: :channel, dependent: :destroy
before_destroy :unsubscribe
def name
`Facebook`
end
private
def unsubscribe
Facebook::Messenger::Subscriptions.unsubscribe(access_token: page_access_token)
rescue => e
true
end
end
end

View file

@ -0,0 +1,8 @@
module Channel
class WebWidget < ApplicationRecord
self.table_name = 'channel_web_widgets'
belongs_to :account
has_one :inbox, as: :channel, dependent: :destroy
end
end

View file

@ -1,4 +0,0 @@
class Channel::Widget < ApplicationRecord
belongs_to :account
has_one :inbox, as: :channel, dependent: :destroy
end

View file

@ -25,7 +25,7 @@ class Inbox < ApplicationRecord
end end
def facebook? def facebook?
channel.class.name.to_s == 'FacebookPage' channel.class.name.to_s == 'Channel::FacebookPage'
end end
def next_available_agent def next_available_agent

View file

@ -4,7 +4,7 @@ module Facebook
def perform def perform
return if message.private return if message.private
return if inbox.channel.class.to_s != 'FacebookPage' return if inbox.channel.class.to_s != 'Channel::FacebookPage'
return unless outgoing_message_from_chatwoot? return unless outgoing_message_from_chatwoot?
Bot.deliver(delivery_params, access_token: message.channel_token) Bot.deliver(delivery_params, access_token: message.channel_token)
@ -55,14 +55,14 @@ module Facebook
is_after_24_hours = (Time.current - last_incoming_message.created_at) / 3600 >= 24 is_after_24_hours = (Time.current - last_incoming_message.created_at) / 3600 >= 24
false unless is_after_24_hours return false unless is_after_24_hours
false if last_incoming_message && has_sent_first_outgoing_message_after_24_hours?(last_incoming_message.id) return false if last_incoming_message && sent_first_outgoing_message_after_24_hours?(last_incoming_message.id)
true true
end end
def has_sent_first_outgoing_message_after_24_hours?(last_incoming_message_id) def sent_first_outgoing_message_after_24_hours?(last_incoming_message_id)
# we can send max 1 message after 24 hour window # we can send max 1 message after 24 hour window
conversation.messages.outgoing.where('id > ?', last_incoming_message_id).count == 1 conversation.messages.outgoing.where('id > ?', last_incoming_message_id).count == 1
end end

View file

@ -26,7 +26,7 @@ module Facebook
end end
end end
class ExampleProvider < Facebook::Messenger::Configuration::Providers::Base class ChatwootFbProvider < Facebook::Messenger::Configuration::Providers::Base
def valid_verify_token?(_verify_token) def valid_verify_token?(_verify_token)
ENV['fb_verify_token'] ENV['fb_verify_token']
end end
@ -36,7 +36,7 @@ class ExampleProvider < Facebook::Messenger::Configuration::Providers::Base
end end
def access_token_for(page_id) def access_token_for(page_id)
FacebookPage.where(page_id: page_id).last.access_token Channel::FacebookPage.where(page_id: page_id).last.access_token
end end
private private
@ -47,5 +47,5 @@ class ExampleProvider < Facebook::Messenger::Configuration::Providers::Base
end end
Facebook::Messenger.configure do |config| Facebook::Messenger.configure do |config|
config.provider = ExampleProvider.new config.provider = ChatwootFbProvider.new
end end

View file

@ -0,0 +1,7 @@
class RenameOldTables < ActiveRecord::Migration[6.1]
def change
drop_table :channels
rename_table :facebook_pages, :channel_facebook_pages
rename_table :channel_widgets, :channel_web_widgets
end
end

View file

@ -10,208 +10,203 @@
# #
# 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: 20_191_016_211_109) do ActiveRecord::Schema.define(version: 2019_10_20_085608) 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"
create_table 'accounts', id: :serial, force: :cascade do |t| create_table "accounts", id: :serial, force: :cascade do |t|
t.string 'name' t.string "name"
t.datetime 'created_at', null: false t.datetime "created_at", null: false
t.datetime 'updated_at', null: false t.datetime "updated_at", null: false
end end
create_table 'attachments', id: :serial, force: :cascade do |t| create_table "attachments", id: :serial, force: :cascade do |t|
t.string 'file' 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
t.float 'coordinates_long', default: 0.0 t.float "coordinates_long", default: 0.0
t.integer 'message_id', null: false t.integer "message_id", null: false
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 'fallback_title' t.string "fallback_title"
t.string 'extension' t.string "extension"
end end
create_table 'canned_responses', id: :serial, force: :cascade do |t| create_table "canned_responses", id: :serial, force: :cascade do |t|
t.integer 'account_id', null: false t.integer "account_id", null: false
t.string 'short_code' t.string "short_code"
t.text 'content' t.text "content"
t.datetime 'created_at', null: false t.datetime "created_at", null: false
t.datetime 'updated_at', null: false t.datetime "updated_at", null: false
end end
create_table 'channel_widgets', id: :serial, force: :cascade do |t| create_table "channel_facebook_pages", id: :serial, force: :cascade do |t|
t.string 'website_name' t.string "name", null: false
t.string 'website_url' t.string "page_id", null: false
t.integer 'account_id' t.string "user_access_token", null: false
t.datetime 'created_at', null: false t.string "page_access_token", null: false
t.datetime 'updated_at', null: false 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"], name: "index_channel_facebook_pages_on_page_id"
end end
create_table 'channels', force: :cascade do |t| create_table "channel_web_widgets", id: :serial, force: :cascade do |t|
t.string 'name' t.string "website_name"
t.datetime 'created_at', precision: 6, null: false t.string "website_url"
t.datetime 'updated_at', precision: 6, null: false t.integer "account_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end end
create_table 'contacts', id: :serial, force: :cascade do |t| create_table "contacts", id: :serial, force: :cascade do |t|
t.string 'name' t.string "name"
t.string 'email' t.string "email"
t.string 'phone_number' t.string "phone_number"
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.integer 'inbox_id', null: false t.integer "inbox_id", null: false
t.bigserial 'source_id', null: false t.bigserial "source_id", null: false
t.string 'avatar' 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
end end
create_table 'conversations', id: :serial, force: :cascade do |t| create_table "conversations", id: :serial, force: :cascade do |t|
t.integer 'account_id', null: false t.integer "account_id", null: false
t.integer 'inbox_id', null: false t.integer "inbox_id", null: false
t.integer 'status', default: 0, null: false t.integer "status", default: 0, null: false
t.integer 'assignee_id' t.integer "assignee_id"
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.bigint 'sender_id' t.bigint "sender_id"
t.integer 'display_id', null: false t.integer "display_id", null: false
t.datetime 'user_last_seen_at' t.datetime "user_last_seen_at"
t.datetime 'agent_last_seen_at' t.datetime "agent_last_seen_at"
t.boolean 'locked', default: false t.boolean "locked", default: false
t.index %w[account_id display_id], name: 'index_conversations_on_account_id_and_display_id', unique: true t.index ["account_id", "display_id"], name: "index_conversations_on_account_id_and_display_id", unique: true
t.index ['account_id'], name: 'index_conversations_on_account_id' t.index ["account_id"], name: "index_conversations_on_account_id"
end end
create_table 'facebook_pages', id: :serial, force: :cascade do |t| create_table "inbox_members", id: :serial, force: :cascade do |t|
t.string 'name', null: false t.integer "user_id", null: false
t.string 'page_id', null: false t.integer "inbox_id", null: false
t.string 'user_access_token', null: false t.datetime "created_at", null: false
t.string 'page_access_token', null: false t.datetime "updated_at", null: false
t.integer 'account_id', null: false t.index ["inbox_id"], name: "index_inbox_members_on_inbox_id"
t.datetime 'created_at', null: false
t.datetime 'updated_at', null: false
t.string 'avatar'
t.index ['page_id'], name: 'index_facebook_pages_on_page_id'
end end
create_table 'inbox_members', id: :serial, force: :cascade do |t| create_table "inboxes", id: :serial, force: :cascade do |t|
t.integer 'user_id', null: false t.integer "channel_id", null: false
t.integer 'inbox_id', null: false t.integer "account_id", null: false
t.datetime 'created_at', null: false t.string "name", null: false
t.datetime 'updated_at', null: false t.datetime "created_at", null: false
t.index ['inbox_id'], name: 'index_inbox_members_on_inbox_id' t.datetime "updated_at", null: false
t.string "channel_type"
t.index ["account_id"], name: "index_inboxes_on_account_id"
end end
create_table 'inboxes', id: :serial, force: :cascade do |t| create_table "messages", id: :serial, force: :cascade do |t|
t.integer 'channel_id', null: false t.text "content"
t.integer 'account_id', null: false t.integer "account_id", null: false
t.string 'name', null: false t.integer "inbox_id", null: false
t.datetime 'created_at', null: false t.integer "conversation_id", null: false
t.datetime 'updated_at', null: false t.integer "message_type", null: false
t.string 'channel_type' t.datetime "created_at", null: false
t.index ['account_id'], name: 'index_inboxes_on_account_id' t.datetime "updated_at", null: false
t.boolean "private", default: false
t.integer "user_id"
t.integer "status", default: 0
t.string "fb_id"
t.index ["conversation_id"], name: "index_messages_on_conversation_id"
end end
create_table 'messages', id: :serial, force: :cascade do |t| create_table "subscriptions", id: :serial, force: :cascade do |t|
t.text 'content' t.string "pricing_version"
t.integer 'account_id', null: false t.integer "account_id"
t.integer 'inbox_id', null: false t.datetime "expiry"
t.integer 'conversation_id', null: false t.string "billing_plan", default: "trial"
t.integer 'message_type', null: false t.string "stripe_customer_id"
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.boolean 'private', default: false t.integer "state", default: 0
t.integer 'user_id' t.boolean "payment_source_added", default: false
t.integer 'status', default: 0
t.string 'fb_id'
t.index ['conversation_id'], name: 'index_messages_on_conversation_id'
end end
create_table 'subscriptions', id: :serial, force: :cascade do |t| create_table "taggings", id: :serial, force: :cascade do |t|
t.string 'pricing_version' t.integer "tag_id"
t.integer 'account_id' t.string "taggable_type"
t.datetime 'expiry' t.integer "taggable_id"
t.string 'billing_plan', default: 'trial' t.string "tagger_type"
t.string 'stripe_customer_id' t.integer "tagger_id"
t.datetime 'created_at', null: false t.string "context", limit: 128
t.datetime 'updated_at', null: false t.datetime "created_at"
t.integer 'state', default: 0 t.index ["context"], name: "index_taggings_on_context"
t.boolean 'payment_source_added', default: false t.index ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], name: "taggings_idx", unique: true
t.index ["tag_id"], name: "index_taggings_on_tag_id"
t.index ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context"
t.index ["taggable_id", "taggable_type", "tagger_id", "context"], name: "taggings_idy"
t.index ["taggable_id"], name: "index_taggings_on_taggable_id"
t.index ["taggable_type", "taggable_id"], name: "index_taggings_on_taggable_type_and_taggable_id"
t.index ["taggable_type"], name: "index_taggings_on_taggable_type"
t.index ["tagger_id", "tagger_type"], name: "index_taggings_on_tagger_id_and_tagger_type"
t.index ["tagger_id"], name: "index_taggings_on_tagger_id"
t.index ["tagger_type", "tagger_id"], name: "index_taggings_on_tagger_type_and_tagger_id"
end end
create_table 'taggings', id: :serial, force: :cascade do |t| create_table "tags", id: :serial, force: :cascade do |t|
t.integer 'tag_id' t.string "name"
t.string 'taggable_type' t.integer "taggings_count", default: 0
t.integer 'taggable_id' t.index ["name"], name: "index_tags_on_name", unique: true
t.string 'tagger_type'
t.integer 'tagger_id'
t.string 'context', limit: 128
t.datetime 'created_at'
t.index ['context'], name: 'index_taggings_on_context'
t.index %w[tag_id taggable_id taggable_type context tagger_id tagger_type], name: 'taggings_idx', unique: true
t.index ['tag_id'], name: 'index_taggings_on_tag_id'
t.index %w[taggable_id taggable_type context], name: 'index_taggings_on_taggable_id_and_taggable_type_and_context'
t.index %w[taggable_id taggable_type tagger_id context], name: 'taggings_idy'
t.index ['taggable_id'], name: 'index_taggings_on_taggable_id'
t.index %w[taggable_type taggable_id], name: 'index_taggings_on_taggable_type_and_taggable_id'
t.index ['taggable_type'], name: 'index_taggings_on_taggable_type'
t.index %w[tagger_id tagger_type], name: 'index_taggings_on_tagger_id_and_tagger_type'
t.index ['tagger_id'], name: 'index_taggings_on_tagger_id'
t.index %w[tagger_type tagger_id], name: 'index_taggings_on_tagger_type_and_tagger_id'
end end
create_table 'tags', id: :serial, force: :cascade do |t| create_table "telegram_bots", id: :serial, force: :cascade do |t|
t.string 'name' t.string "name"
t.integer 'taggings_count', default: 0 t.string "auth_key"
t.index ['name'], name: 'index_tags_on_name', unique: true t.integer "account_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end end
create_table 'telegram_bots', id: :serial, force: :cascade do |t| create_table "users", id: :serial, force: :cascade do |t|
t.string 'name' t.string "provider", default: "email", null: false
t.string 'auth_key' t.string "uid", default: "", null: false
t.integer 'account_id' t.string "encrypted_password", default: "", null: false
t.datetime 'created_at', null: false t.string "reset_password_token"
t.datetime 'updated_at', null: false t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
t.string "name", null: false
t.string "nickname"
t.string "image"
t.string "email"
t.json "tokens"
t.integer "account_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "pubsub_token"
t.integer "role", default: 0
t.bigint "inviter_id"
t.index ["email"], name: "index_users_on_email"
t.index ["inviter_id"], name: "index_users_on_inviter_id"
t.index ["pubsub_token"], name: "index_users_on_pubsub_token", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
t.index ["uid", "provider"], name: "index_users_on_uid_and_provider", unique: true
end end
create_table 'users', id: :serial, force: :cascade do |t| add_foreign_key "users", "users", column: "inviter_id"
t.string 'provider', default: 'email', null: false
t.string 'uid', default: '', null: false
t.string 'encrypted_password', default: '', null: false
t.string 'reset_password_token'
t.datetime 'reset_password_sent_at'
t.datetime 'remember_created_at'
t.integer 'sign_in_count', default: 0, null: false
t.datetime 'current_sign_in_at'
t.datetime 'last_sign_in_at'
t.string 'current_sign_in_ip'
t.string 'last_sign_in_ip'
t.string 'confirmation_token'
t.datetime 'confirmed_at'
t.datetime 'confirmation_sent_at'
t.string 'unconfirmed_email'
t.string 'name', null: false
t.string 'nickname'
t.string 'image'
t.string 'email'
t.json 'tokens'
t.integer 'account_id', null: false
t.datetime 'created_at', null: false
t.datetime 'updated_at', null: false
t.string 'pubsub_token'
t.integer 'role', default: 0
t.bigint 'inviter_id'
t.index ['email'], name: 'index_users_on_email'
t.index ['inviter_id'], name: 'index_users_on_inviter_id'
t.index ['pubsub_token'], name: 'index_users_on_pubsub_token', unique: true
t.index ['reset_password_token'], name: 'index_users_on_reset_password_token', unique: true
t.index %w[uid provider], name: 'index_users_on_uid_and_provider', unique: true
end
add_foreign_key 'users', 'users', column: 'inviter_id'
end end

View file

@ -1,30 +1,14 @@
account = Account.create!([ account = Account.create!(name: 'Acme Inc')
{ name: 'Google' }
])
user = User.new(name: 'lary', email: 'larry@google.com', password: '123456', account_id: account.first.id) user = User.new(name: 'John', email: 'john@acme.inc', password: '123456', account: account, role: :administrator)
user.skip_confirmation! user.skip_confirmation!
user.save! user.save!
channels = Channel.create!([ web_widget = Channel::WebWidget.create!(account: account, website_name: 'Acme', website_url: 'https://acme.inc')
{ name: 'Facebook Messenger' }
])
inboxes = Inbox.create!([ inbox = Inbox.create!(channel: web_widget, account: account, name: 'Acme Support')
{ channel: channels.first, account_id: 1, name: 'Google Car' }, InboxMember.create!(user: user, inbox: inbox)
{ channel: channels.first, account_id: 1, name: 'Project Loon' }
])
Contact.create!([ contact = Contact.create!(name: 'jane', email: 'jane@example.com', phone_number: '0000', inbox: inbox, account: account)
{ name: 'izuck@facebook.com', email: nil, phone_number: '99496030692', inbox_id: inboxes.first.id, account_id: 1 } Conversation.create!(account: account, inbox: inbox, status: :open, assignee_id: 1, sender: contact)
]) Message.create!(content: 'Hello', account_id: 1, inbox_id: 1, conversation_id: 1, message_type: :incoming)
Conversation.create!([
{ account_id: 1, inbox_id: 1, status: :open, assignee_id: 1, sender_id: 1 }
])
InboxMember.create!([
{ user_id: 1, inbox_id: 1 }
])
Message.create!([
{ content: 'Hello', account_id: 1, inbox_id: 1, conversation_id: 1, message_type: :incoming }
])

View file

@ -28,14 +28,14 @@ class Integrations::Facebook::MessageCreator
end end
def create_outgoing_message def create_outgoing_message
FacebookPage.where(page_id: response.sender_id).each do |page| Channel::FacebookPage.where(page_id: response.sender_id).each do |page|
mb = Messages::Outgoing::EchoBuilder.new(response, page.inbox, true) mb = Messages::Outgoing::EchoBuilder.new(response, page.inbox, true)
mb.perform mb.perform
end end
end end
def create_incoming_message def create_incoming_message
FacebookPage.where(page_id: response.recipient_id).each do |page| Channel::FacebookPage.where(page_id: response.recipient_id).each do |page|
mb = Messages::IncomingMessageBuilder.new(response, page.inbox) mb = Messages::IncomingMessageBuilder.new(response, page.inbox)
mb.perform mb.perform
end end

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
FactoryBot.define do FactoryBot.define do
factory :channel_widget, class: 'Channel::Widget' do factory :channel_widget, class: 'Channel::WebWidget' do
sequence(:website_name) { |n| "Example Website #{n}" } sequence(:website_name) { |n| "Example Website #{n}" }
sequence(:website_url) { |n| "https://example-#{n}.com" } sequence(:website_url) { |n| "https://example-#{n}.com" }
account account

View file

@ -1,11 +0,0 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
website_name: MyString
website_url: MyString
account_id: 1
two:
website_name: MyString
website_url: MyString
account_id: 1

View file

@ -1,7 +0,0 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
name: MyString
two:
name: MyString

View file

@ -1,11 +0,0 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
# This model initially had no columns defined. If you add columns to the
# model remove the '{}' from the fixture names and add the columns immediately
# below each fixture, per the syntax in the comments below
#
one: {}
# column: value
#
two: {}
# column: value