Skip to content

Commit

Permalink
chore: Enable email channel (chatwoot#1851)
Browse files Browse the repository at this point in the history
  • Loading branch information
sojan-official authored Mar 4, 2021
1 parent 6aed01d commit ca4a766
Show file tree
Hide file tree
Showing 15 changed files with 54 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<woot-code
v-if="isAEmailInbox"
lang="html"
:script="currentInbox.forward_to_address"
:script="currentInbox.forward_to_email"
>
</woot-code>
</div>
Expand Down
5 changes: 4 additions & 1 deletion app/mailboxes/application_mailbox.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def self.support_mail?
proc do |inbound_mail_obj|
is_a_support_email = false
inbound_mail_obj.mail.to.each do |email|
channel = Channel::Email.find_by(email: email)
channel = Channel::Email.find_by('email = ? OR forward_to_email = ?', email, email)
if channel.present?
is_a_support_email = true
break
Expand All @@ -37,7 +37,10 @@ def self.catch_all_mail?
end

# routing should be defined below the referenced procs

# routes as a reply to existing conversations
routing(reply_mail? => :reply)
# routes as a new conversation in email channel
routing(support_mail? => :support)
routing(catch_all_mail? => :default)
end
2 changes: 1 addition & 1 deletion app/mailboxes/support_mailbox.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def process

def find_channel
mail.to.each do |email|
@channel = Channel::Email.find_by(email: email)
@channel = Channel::Email.find_by('email = ? OR forward_to_email = ?', email, email)
break if @channel.present?
end
raise 'Email channel/inbox not found' if @channel.nil?
Expand Down
6 changes: 1 addition & 5 deletions app/mailers/conversation_reply_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,7 @@ def inbound_email_enabled?
end

def current_domain
@current_domain ||= begin
@account.domain ||
ENV.fetch('MAILER_INBOUND_EMAIL_DOMAIN', false) ||
GlobalConfig.get('MAILER_INBOUND_EMAIL_DOMAIN')['MAILER_INBOUND_EMAIL_DOMAIN']
end
@current_domain ||= @account.inbound_email_domain
end

def account_support_email
Expand Down
8 changes: 8 additions & 0 deletions app/models/account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ def webhook_data
}
end

def inbound_email_domain
domain || GlobalConfig.get('MAILER_INBOUND_EMAIL_DOMAIN')['MAILER_INBOUND_EMAIL_DOMAIN'] || ENV.fetch('MAILER_INBOUND_EMAIL_DOMAIN', false)
end

def support_email
super || GlobalConfig.get('MAILER_SUPPORT_EMAIL')['MAILER_SUPPORT_EMAIL'] || ENV.fetch('MAILER_SENDER_EMAIL', nil)
end

private

def notify_creation
Expand Down
25 changes: 12 additions & 13 deletions app/models/channel/email.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
#
# Table name: channel_email
#
# id :bigint not null, primary key
# email :string not null
# forward_to_address :string not null
# created_at :datetime not null
# updated_at :datetime not null
# account_id :integer not null
# id :bigint not null, primary key
# email :string not null
# forward_to_email :string not null
# created_at :datetime not null
# updated_at :datetime not null
# account_id :integer not null
#
# Indexes
#
# index_channel_email_on_email (email) UNIQUE
# index_channel_email_on_forward_to_address (forward_to_address) UNIQUE
# index_channel_email_on_email (email) UNIQUE
# index_channel_email_on_forward_to_email (forward_to_email) UNIQUE
#

class Channel::Email < ApplicationRecord
Expand All @@ -21,10 +21,10 @@ class Channel::Email < ApplicationRecord
validates :account_id, presence: true
belongs_to :account
validates :email, uniqueness: true
validates :forward_to_address, uniqueness: true
validates :forward_to_email, uniqueness: true

has_one :inbox, as: :channel, dependent: :destroy
before_validation :ensure_forward_to_address, on: :create
before_validation :ensure_forward_to_email, on: :create

def name
'Email'
Expand All @@ -36,8 +36,7 @@ def has_24_hour_messaging_window?

private

def ensure_forward_to_address
email_domain = InstallationConfig.find_by(name: 'MAILER_INBOUND_EMAIL_DOMAIN')&.value
self.forward_to_address ||= "#{SecureRandom.hex}@#{email_domain}"
def ensure_forward_to_email
self.forward_to_email ||= "#{SecureRandom.hex}@#{account.inbound_email_domain}"
end
end
18 changes: 5 additions & 13 deletions app/presenters/mail_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,13 @@ def extract_reply(content)
end

def quoted_text_regexes
return sender_agnostic_regexes if @account.nil? || account_support_email.blank?
return sender_agnostic_regexes if @account.nil? || @account.support_email.blank?

[
Regexp.new("From:\s* #{Regexp.escape(account_support_email)}", Regexp::IGNORECASE),
Regexp.new("<#{Regexp.escape(account_support_email)}>", Regexp::IGNORECASE),
Regexp.new("#{Regexp.escape(account_support_email)}\s+wrote:", Regexp::IGNORECASE),
Regexp.new("On(.*)#{Regexp.escape(account_support_email)}(.*)wrote:", Regexp::IGNORECASE)
Regexp.new("From:\s* #{Regexp.escape(@account.support_email)}", Regexp::IGNORECASE),
Regexp.new("<#{Regexp.escape(@account.support_email)}>", Regexp::IGNORECASE),
Regexp.new("#{Regexp.escape(@account.support_email)}\s+wrote:", Regexp::IGNORECASE),
Regexp.new("On(.*)#{Regexp.escape(@account.support_email)}(.*)wrote:", Regexp::IGNORECASE)
] + sender_agnostic_regexes
end

Expand All @@ -109,12 +109,4 @@ def sender_agnostic_regexes
Regexp.new("from:\s*$", Regexp::IGNORECASE)
]
end

def account_support_email
@account_support_email ||= begin
@account.support_email ||
GlobalConfig.get('MAILER_SUPPORT_EMAIL')['MAILER_SUPPORT_EMAIL'] ||
ENV.fetch('MAILER_SENDER_EMAIL', nil)
end
end
end
2 changes: 1 addition & 1 deletion app/views/api/v1/models/_inbox.json.jbuilder
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ json.welcome_tagline resource.channel.try(:welcome_tagline)
json.enable_auto_assignment resource.enable_auto_assignment
json.web_widget_script resource.channel.try(:web_widget_script)
json.website_token resource.channel.try(:website_token)
json.forward_to_address resource.channel.try(:forward_to_address)
json.forward_to_email resource.channel.try(:forward_to_email)
json.phone_number resource.channel.try(:phone_number)
json.selected_feature_flags resource.channel.try(:selected_feature_flags)
json.reply_time resource.channel.try(:reply_time)
Expand Down
2 changes: 1 addition & 1 deletion config/features.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
- name: inbound_emails
enabled: false
- name: channel_email
enabled: false
enabled: true
- name: channel_facebook
enabled: true
- name: channel_twitter
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class RenameChannelEmailForwardAddress < ActiveRecord::Migration[6.0]
def change
rename_column :channel_email, :forward_to_address, :forward_to_email
end
end
6 changes: 3 additions & 3 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2021_02_22_131155) do
ActiveRecord::Schema.define(version: 2021_03_03_192243) do

# These are extensions that must be enabled in order to support this database
enable_extension "pg_stat_statements"
Expand Down Expand Up @@ -131,11 +131,11 @@
create_table "channel_email", force: :cascade do |t|
t.integer "account_id", null: false
t.string "email", null: false
t.string "forward_to_address", null: false
t.string "forward_to_email", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["email"], name: "index_channel_email_on_email", unique: true
t.index ["forward_to_address"], name: "index_channel_email_on_forward_to_address", unique: true
t.index ["forward_to_email"], name: "index_channel_email_on_forward_to_email", unique: true
end

create_table "channel_facebook_pages", id: :serial, force: :cascade do |t|
Expand Down
4 changes: 1 addition & 3 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
SuperAdmin.create!(email: '[email protected]', password: '123456')

account = Account.create!(
name: 'Acme Inc',
domain: 'support.chatwoot.com',
support_email: ENV.fetch('MAILER_SENDER_EMAIL', '[email protected]')
name: 'Acme Inc'
)

user = User.new(name: 'John', email: '[email protected]', password: '123456')
Expand Down
2 changes: 1 addition & 1 deletion spec/factories/channel/channel_email.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
FactoryBot.define do
factory :channel_email, class: 'Channel::Email' do
sequence(:email) { |n| "care-#{n}@example.com" }
sequence(:forward_to_address) { |n| "forward-#{n}@chatwoot.com" }
sequence(:forward_to_email) { |n| "forward-#{n}@chatwoot.com" }
account
after(:create) do |channel_email|
create(:inbox, channel: channel_email, account: channel_email.account)
Expand Down
13 changes: 9 additions & 4 deletions spec/mailboxes/application_mailbox_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,18 @@
describe 'Support' do
let!(:channel_email) { create(:channel_email) }

before do
it 'routes support emails to Support Mailbox when mail is to channel email' do
# this email is hardcoded in the support.eml, that's why we are updating this
channel_email.email = '[email protected]'
channel_email.save
channel_email.update(email: '[email protected]')
dbl = double
expect(SupportMailbox).to receive(:new).and_return(dbl)
expect(dbl).to receive(:perform_processing).and_return(true)
described_class.route support_mail
end

it 'routes support emails to Support Mailbox' do
it 'routes support emails to Support Mailbox when mail is to channel forward to email' do
# this email is hardcoded in the support.eml, that's why we are updating this
channel_email.update(forward_to_email: '[email protected]')
dbl = double
expect(SupportMailbox).to receive(:new).and_return(dbl)
expect(dbl).to receive(:perform_processing).and_return(true)
Expand Down
2 changes: 1 addition & 1 deletion spec/mailers/conversation_reply_mailer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
let(:conversation) { create(:conversation, assignee: agent, inbox: inbox_member.inbox, account: account) }
let!(:message) { create(:message, conversation: conversation, account: account) }
let(:mail) { described_class.reply_with_summary(message.conversation, Time.zone.now).deliver_now }
let(:domain) { account.domain || ENV.fetch('MAILER_INBOUND_EMAIL_DOMAIN', false) }
let(:domain) { account.inbound_email_domain }

it 'renders the receiver email' do
expect(mail.to).to eq([message&.conversation&.contact&.email])
Expand Down

0 comments on commit ca4a766

Please sign in to comment.