diff --git a/app/controllers/api/v1/accounts/conversations_controller.rb b/app/controllers/api/v1/accounts/conversations_controller.rb
index 6311ccb08d16a..7e84c890bd1b4 100644
--- a/app/controllers/api/v1/accounts/conversations_controller.rb
+++ b/app/controllers/api/v1/accounts/conversations_controller.rb
@@ -3,7 +3,7 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro
include DateRangeHelper
include HmacConcern
- before_action :conversation, except: [:index, :meta, :search, :create, :filter]
+ before_action :conversation, except: [:index, :meta, :search, :create, :filter, :ticket]
before_action :inbox, :contact, :contact_inbox, only: [:create]
def index
diff --git a/app/views/mailers/digitaltolk_mailer/send_email.erb b/app/views/mailers/digitaltolk_mailer/send_email.erb
new file mode 100644
index 0000000000000..5a6b9632a58b5
--- /dev/null
+++ b/app/views/mailers/digitaltolk_mailer/send_email.erb
@@ -0,0 +1,17 @@
+
You just got a form submission!
+
+
+Form
+<%= @form_name %>
+
+
+Site
+Digitaltolk
+
+
+Submitted content
+<% if @content.present? %>
+ <% @content.each do |key, value| %>
+ <%= key %>: <%= value %>
+ <% end %>
+<% end %>
\ No newline at end of file
diff --git a/app/workers/digitaltolk_email_worker.rb b/app/workers/digitaltolk_email_worker.rb
new file mode 100644
index 0000000000000..d8ec759d016ea
--- /dev/null
+++ b/app/workers/digitaltolk_email_worker.rb
@@ -0,0 +1,10 @@
+class DigitaltolkEmailWorker
+ include Sidekiq::Worker
+ sidekiq_options queue: :mailers, retry: 3
+
+ def perform(params)
+ data = JSON.parse(params).with_indifferent_access
+
+ Digitaltolk::DigitaltolkMailer.send_email(data).deliver_later
+ end
+end
diff --git a/config/routes.rb b/config/routes.rb
index f224f39f7103e..0e83f63a4854c 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -81,6 +81,7 @@
get :meta
get :search
post :filter
+ post :ticket
end
scope module: :conversations do
resources :messages, only: [:index, :create, :destroy] do
@@ -106,7 +107,6 @@
post :unread
post :custom_attributes
get :attachments
- post :ticket
end
end
diff --git a/lib/digitaltolk/add_conversation_service.rb b/lib/digitaltolk/add_conversation_service.rb
new file mode 100644
index 0000000000000..5ae833f074cd2
--- /dev/null
+++ b/lib/digitaltolk/add_conversation_service.rb
@@ -0,0 +1,69 @@
+class Digitaltolk::AddConversationService
+ attr_accessor :inbox_id, :params
+
+ def initialize(inbox_id, params)
+ @inbox_id = inbox_id
+ @params = params
+ end
+
+ def perform
+ find_or_create_contact
+
+ ConversationBuilder.new(params: ActionController::Parameters.new(conversation_params), contact_inbox: @contact_inbox).perform
+ end
+
+ private
+
+ def inbox
+ @inbox ||= Inbox.find_by(id: @inbox_id)
+ end
+
+ def find_or_create_contact
+ @contact = inbox.contacts.find_by(email: email_address)
+
+ if @contact.present?
+ @contact_inbox = ContactInbox.find_by(inbox: @inbox, contact: @contact)
+ else
+ create_contact
+ end
+ end
+
+ def create_contact
+ @contact_inbox = ::ContactInboxWithContactBuilder.new(
+ source_id: email_address,
+ inbox: inbox,
+ contact_attributes: {
+ name: identify_contact_name,
+ email: email_address,
+ additional_attributes: {
+ source_id: "email:"
+ }
+ }
+ ).perform
+ @contact = @contact_inbox.contact
+ end
+
+ def email_address
+ params.dig(:email)
+ end
+
+ def identify_contact_name
+ email_address.split('@').first
+ end
+
+ def conversation_params
+ {
+ account_id: params.dig(:account_id),
+ assignee_id: params.dig(:assignee_id),
+ contact_id: @contact.id,
+ inbox_id: params.dig(:inbox_id),
+ source_id: params.dig(:email),
+ additional_attributes: {
+ mail_subject: params.dig(:subject)
+ },
+ message: {
+ content: params.dig(:content)
+ }
+ }
+ end
+end
\ No newline at end of file
diff --git a/lib/digitaltolk/add_message_service.rb b/lib/digitaltolk/add_message_service.rb
new file mode 100644
index 0000000000000..28810e29f5baa
--- /dev/null
+++ b/lib/digitaltolk/add_message_service.rb
@@ -0,0 +1,35 @@
+class Digitaltolk::AddMessageService
+ attr_accessor :sender, :conversation, :content, :is_incoming
+
+ def initialize(sender, conversation, content, is_incoming = false)
+ @conversation = conversation
+ @content = content
+ @sender = sender
+ @is_incoming = is_incoming
+ end
+
+ def perform
+ return unless @conversation.present?
+
+ create_message
+ end
+
+ private
+
+ def create_message
+ return unless content.present?
+
+ Messages::MessageBuilder.new(sender, @conversation, message_params).perform
+ end
+
+ def message_type
+ is_incoming ? 'incoming' : 'outgoing'
+ end
+
+ def message_params
+ {
+ message_type: message_type,
+ content: content
+ }
+ end
+end
\ No newline at end of file
diff --git a/lib/digitaltolk/digitaltolk_mailer.rb b/lib/digitaltolk/digitaltolk_mailer.rb
new file mode 100644
index 0000000000000..22503cd275ec8
--- /dev/null
+++ b/lib/digitaltolk/digitaltolk_mailer.rb
@@ -0,0 +1,22 @@
+class Digitaltolk::DigitaltolkMailer < ApplicationMailer
+ def send_email(params)
+ return unless smtp_config_set_or_development?
+ return unless params.dig(:to).present?
+ return unless params.dig(:from).present?
+
+ @form_name = params.dig(:form_name)
+ @content = params.dig(:data)
+
+ email_params = {
+ to: params.dig(:to),
+ reply_to: params.dig(:from),
+ subject: params.dig(:subject)
+ }
+
+ mail(email_params) do |format|
+ format.html do
+ render 'mailers/digitaltolk_mailer/send_email', layout: false
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/lib/digitaltolk/fix_invalid_conversation.rb b/lib/digitaltolk/fix_invalid_conversation.rb
index 3d33b31c9dfbd..776bec845755b 100644
--- a/lib/digitaltolk/fix_invalid_conversation.rb
+++ b/lib/digitaltolk/fix_invalid_conversation.rb
@@ -31,6 +31,10 @@ def fix_conversation_contact
def fix_message_email
conversation.messages.incoming.where("content_attributes::text LIKE '%#{Digitaltolk::MailHelper::INVALID_LOOPIA_EMAIL}%'").each do |msg|
+ next if msg.blank?
+ next if msg.content_attributes.blank?
+ next if msg.content_attributes.dig(:email, :from).blank?
+
msg.content_attributes[:email][:from] = [email_from_body]
msg.save
end
@@ -51,7 +55,7 @@ def email_from_body
match = first_message.content.to_s.match(email_regex)
return if match.nil?
- @email_from_body = match[0]
+ @email_from_body = match.first
end
def find_or_create_original_contact
diff --git a/lib/digitaltolk/mail_helper.rb b/lib/digitaltolk/mail_helper.rb
index 7928a9c3cbaf8..e11c3ced764b3 100644
--- a/lib/digitaltolk/mail_helper.rb
+++ b/lib/digitaltolk/mail_helper.rb
@@ -6,7 +6,7 @@ def self.email_from_body(html_content)
return if html_content.blank?
match = html_content.to_s.match(EMAIL_REGEX)
- match[0]
+ match.first
rescue
nil
end
diff --git a/lib/digitaltolk/send_email_ticket_service.rb b/lib/digitaltolk/send_email_ticket_service.rb
index a7a15fba476ff..2d8d529f7ce4a 100644
--- a/lib/digitaltolk/send_email_ticket_service.rb
+++ b/lib/digitaltolk/send_email_ticket_service.rb
@@ -1,6 +1,9 @@
class Digitaltolk::SendEmailTicketService
attr_accessor :account, :user, :params, :errors, :conversation
+ CUSTOMER_TYPE = 2
+ TRANSLATOR_TYPE = 3
+
def initialize(account, user, params)
@account = account
@user = user
@@ -9,9 +12,19 @@ def initialize(account, user, params)
end
def perform
- find_conversation
- validate
- create_message
+ begin
+ ActiveRecord::Base.transaction do
+ validate_params
+ find_or_create_conversation if @errors.blank?
+ validate_data if @errors.blank?
+ create_message if @errors.blank?
+ end
+ rescue StandardError => e
+ Rails.logger.error e
+ Rails.logger.error e.backtrace.first
+ @errors << e.message
+ end
+
result_data
end
@@ -26,54 +39,85 @@ def result_data
def result_json(success, message)
{
success: success,
- message: message
+ message: message,
+ conversation_id: @conversation&.id
}
end
def conversations
- @account.where(conversation_id: account)
+ inbox.conversations
+ end
+
+ def conversation_params
+ {
+ subject: params.dig(:title),
+ content: params.dig(:body),
+ inbox_id: params.dig(:inbox_id),
+ email: params.dig(:requester, :email),
+ assignee_id: nil,
+ account_id: @account.id,
+ }
+ end
+
+ def find_or_create_conversation
+ if for_customer?
+ @conversation = conversations.where("custom_attributes ->> 'booking_id' = ?", booking_id).last
+ elsif for_translator?
+ @conversation = Digitaltolk::AddConversationService.new(inbox_id, conversation_params).perform
+ end
+ end
+
+ def for_customer?
+ recipient_type.to_i == CUSTOMER_TYPE
+ end
+
+ def for_translator?
+ recipient_type.to_i == TRANSLATOR_TYPE
end
- def find_conversation
- @conversation = Conversation.where("custom_attributes ->> 'booking_id' = ?", booking_id).last
+ def recipient_type
+ params.dig(:recipient_type)
+ end
+
+ def inbox
+ @inbox ||= @account.inboxes.find_by(id: inbox_id)
+ end
+
+ def inbox_id
+ params.dig(:inbox_id)
end
def booking_id
- params.dig(:booking_id)
+ params.dig(:booking_id).to_s
end
- def validate
+ def validate_params
if booking_id.blank?
- @errors << "Parameter booking_id is required."
+ @errors << "Parameter booking_id is required"
end
- #validate email address
+ if recipient_type.blank?
+ @errors << "Recipient Type is required"
+ elsif !for_customer? && !for_translator?
+ @errors << "Unknown recipient_type #{recipient_type}"
+ end
- if @conversation.blank?
- @errors << "Conversation with booking number #{booking_id} not found"
+ if inbox.blank?
+ @errors << "Inbox with id #{inbox_id} was not found"
end
end
- def create_message
- return if @errors.present?
-
- @message = @conversation.messages.build(message_params)
- @message.save!
+ def validate_data
+ @errors << invalid_booking_message if @conversation.blank?
end
- def message_type
- 'outgoing'
+ def invalid_booking_message
+ "Conversation with booking ID #{booking_id} not found"
end
- def message_params
- {
- account_id: @conversation.account_id,
- inbox_id: @conversation.inbox_id,
- message_type: message_type,
- content: @params[:body],
- private: false,
- sender: user,
- content_type: 'input_email',
- }
+ def create_message
+ return if @errors.present?
+
+ @message = Digitaltolk::AddMessageService.new(@user, @conversation, @params.dig(:body), true).perform
end
end
\ No newline at end of file
diff --git a/lib/digitaltolk/webflow_service.rb b/lib/digitaltolk/webflow_service.rb
index 42ced9751c711..705994b0a93e8 100644
--- a/lib/digitaltolk/webflow_service.rb
+++ b/lib/digitaltolk/webflow_service.rb
@@ -1,13 +1,129 @@
class Digitaltolk::WebflowService
attr_accessor :params
+ INFO_EMAIL = 'info@digitaltolk.se'
+ WEBFORM_EMAIL = 'webformular@digitaltolk.se'
+
def initialize(params)
@params = params
end
def perform
- puts '----------------------------------------------'
- puts "webflow_params: #{params}"
- puts '----------------------------------------------'
+ # temporary disable
+ return false
+
+ unless form_submission?
+ Rails.logger.error "Error: webflow trigger type not supported '#{trigger_event}'"
+ return
+ end
+
+ process_webflow_submission
+ rescue StandardError => e
+ Rails.logger.error e
+ Rails.logger.error e.backtrace.first
+ end
+
+ private
+
+ def process_webflow_submission
+ if from_email.blank?
+ Rails.logger.error 'blank from email'
+ return
+ end
+
+ emails.each_with_index do |recipient_email, index|
+ next if recipient_email.blank?
+
+ second_interval = (10 * (index + 1))
+ Rails.logger.info "Sent webform email for #{from_email}"
+ DigitaltolkEmailWorker.perform_in(second_interval.seconds, email_params(recipient_email).to_json)
+ end
+ end
+
+ def emails
+ [INFO_EMAIL, WEBFORM_EMAIL]
+ end
+
+ def webflow_params
+ @params.dig(:params, :webflow)
+ end
+
+ def email_params(to)
+ {
+ 'to': to,
+ 'from': from_email,
+ 'subject': subject,
+ 'data': form_data,
+ 'form_name': form_name
+ }
end
+
+ def form_data
+ webflow_params.dig(:payload, :data)
+ end
+
+ def form_name
+ webflow_params.dig(:payload, :name)
+ end
+
+ def from_email
+ form_data.dig('Email-kom')
+ end
+
+ def subject
+ 'You have a new form submission on your Webflow site!'
+ end
+
+ def trigger_event
+ webflow_params.dig(:triggerType)
+ end
+
+ def form_submission?
+ trigger_event.to_s.downcase == 'form_submission'
+ end
+
+ # def test_webhook_data
+ # data = {
+ # "params": {
+ # "triggerType": "form_submission",
+ # "payload": {
+ # "name": "Info kontakt",
+ # "siteId": "6476e981f6a8eff9068d9af2",
+ # "data": {
+ # "Name-kom": "Test JM",
+ # "Email-kom": "jmanuel.derecho@gmail.com",
+ # "phone-kom": "",
+ # "Bok.nr.": "#3364311",
+ # "Subject": "Mejl för tolk",
+ # "Meddelande": "Hej! Har bokat tolk men ser inte tolkens mejladress någonstans. Behöver den för att skicka video länk."
+ # },
+ # "submittedAt": "2024-02-01T15:35:45.897Z",
+ # "id": "65bbba510f02b427c7024707",
+ # "formId": "64dd32123cda9a590ffbf718"
+ # },
+ # "controller": "webhooks/webflow",
+ # "action": "process_payload",
+ # "webflow": {
+ # "triggerType": "form_submission",
+ # "payload": {
+ # "name": "Info kontakt",
+ # "siteId": "6476e981f6a8eff9068d9af2",
+ # "data": {
+ # "Name-kom": "Test JM",
+ # "Email-kom": "jmanuel.derecho@gmail.com",
+ # "phone-kom": "",
+ # "Bok.nr.": "#3364311",
+ # "Subject": "Mejl för tolk",
+ # "Meddelande": "Hej! Har bokat tolk men ser inte tolkens mejladress någonstans. Behöver den för att skicka video länk."
+ # },
+ # "submittedAt": "2024-02-01T15:35:45.897Z",
+ # "id": "65bbba510f02b427c7024707",
+ # "formId": "64dd32123cda9a590ffbf718"
+ # }
+ # }
+ # }
+ # }
+
+ # ActionController::Parameters.new(data)
+ # end
end
\ No newline at end of file