diff --git a/app/builders/messages/outgoing/normal_builder.rb b/app/builders/messages/outgoing/normal_builder.rb index 668022e64..c420b2a41 100644 --- a/app/builders/messages/outgoing/normal_builder.rb +++ b/app/builders/messages/outgoing/normal_builder.rb @@ -3,11 +3,13 @@ class Messages::Outgoing::NormalBuilder attr_reader :message def initialize(user, conversation, params) - @content = params[:message] + @content = params[:content] @private = params[:private] || false @conversation = conversation @user = user @fb_id = params[:fb_id] + @content_type = params[:content_type] + @items = params.to_unsafe_h&.dig(:content_attributes, :items) @attachment = params[:attachment] end @@ -34,7 +36,9 @@ class Messages::Outgoing::NormalBuilder content: @content, private: @private, user_id: @user&.id, - source_id: @fb_id + source_id: @fb_id, + content_type: @content_type, + items: @items } end end diff --git a/app/controllers/api/v1/accounts/conversations_controller.rb b/app/controllers/api/v1/accounts/conversations_controller.rb index 895091cca..3050c8ab7 100644 --- a/app/controllers/api/v1/accounts/conversations_controller.rb +++ b/app/controllers/api/v1/accounts/conversations_controller.rb @@ -1,5 +1,6 @@ class Api::V1::Accounts::ConversationsController < Api::BaseController before_action :conversation, except: [:index] + before_action :contact_inbox, only: [:create] def index result = conversation_finder.perform @@ -7,6 +8,10 @@ class Api::V1::Accounts::ConversationsController < Api::BaseController @conversations_count = result[:count] end + def create + @conversation = ::Conversation.create!(conversation_params) + end + def show; end def toggle_status @@ -29,6 +34,19 @@ class Api::V1::Accounts::ConversationsController < Api::BaseController @conversation ||= current_account.conversations.find_by(display_id: params[:id]) end + def contact_inbox + @contact_inbox ||= ::ContactInbox.find_by!(source_id: params[:source_id]) + end + + def conversation_params + { + account_id: current_account.id, + inbox_id: @contact_inbox.inbox_id, + contact_id: @contact_inbox.contact_id, + contact_inbox_id: @contact_inbox.id + } + end + def conversation_finder @conversation_finder ||= ConversationFinder.new(current_user, params) end diff --git a/app/controllers/api/v1/widget/base_controller.rb b/app/controllers/api/v1/widget/base_controller.rb index eb19e2bdd..9ef4a04f2 100644 --- a/app/controllers/api/v1/widget/base_controller.rb +++ b/app/controllers/api/v1/widget/base_controller.rb @@ -2,9 +2,9 @@ class Api::V1::Widget::BaseController < ApplicationController private def conversation - @conversation ||= @contact_inbox.conversations.find_by( + @conversation ||= @contact_inbox.conversations.where( inbox_id: auth_token_params[:inbox_id] - ) + ).last end def auth_token_params diff --git a/app/controllers/api/v1/widget/events_controller.rb b/app/controllers/api/v1/widget/events_controller.rb new file mode 100644 index 000000000..faa44994c --- /dev/null +++ b/app/controllers/api/v1/widget/events_controller.rb @@ -0,0 +1,16 @@ +class Api::V1::Widget::EventsController < Api::V1::Widget::BaseController + include Events::Types + before_action :set_web_widget + before_action :set_contact + + def create + Rails.configuration.dispatcher.dispatch(permitted_params[:name], Time.zone.now, contact_inbox: @contact_inbox) + head :no_content + end + + private + + def permitted_params + params.permit(:name, :website_token) + end +end diff --git a/app/controllers/api/v1/widget/messages_controller.rb b/app/controllers/api/v1/widget/messages_controller.rb index 7d16f7641..7e0c446ea 100644 --- a/app/controllers/api/v1/widget/messages_controller.rb +++ b/app/controllers/api/v1/widget/messages_controller.rb @@ -15,8 +15,12 @@ class Api::V1::Widget::MessagesController < Api::V1::Widget::BaseController end def update - @message.update!(input_submitted_email: contact_email) - update_contact(contact_email) + if @message.content_type == 'input_email' + @message.update!(submitted_email: contact_email) + update_contact(contact_email) + else + @message.update!(message_update_params[:message]) + end rescue StandardError => e render json: { error: @contact.errors, message: e.message }.to_json, status: 500 end @@ -116,6 +120,10 @@ class Api::V1::Widget::MessagesController < Api::V1::Widget::BaseController contact_email.split('@')[0] end + def message_update_params + params.permit(message: [submitted_values: [:name, :title, :value]]) + end + def permitted_params params.permit(:id, :before, :website_token, contact: [:email], message: [:content, :referer_url, :timestamp]) end diff --git a/app/controllers/concerns/access_token_auth_helper.rb b/app/controllers/concerns/access_token_auth_helper.rb index c5173e422..e7af9e116 100644 --- a/app/controllers/concerns/access_token_auth_helper.rb +++ b/app/controllers/concerns/access_token_auth_helper.rb @@ -1,6 +1,6 @@ module AccessTokenAuthHelper BOT_ACCESSIBLE_ENDPOINTS = { - 'api/v1/accounts/conversations' => ['toggle_status'], + 'api/v1/accounts/conversations' => %w[toggle_status create], 'api/v1/accounts/conversations/messages' => ['create'] }.freeze diff --git a/app/javascript/dashboard/api/inbox/message.js b/app/javascript/dashboard/api/inbox/message.js index 579d97a10..4ceac84d0 100644 --- a/app/javascript/dashboard/api/inbox/message.js +++ b/app/javascript/dashboard/api/inbox/message.js @@ -9,7 +9,7 @@ class MessageApi extends ApiClient { create({ conversationId, message, private: isPrivate }) { return axios.post(`${this.url}/${conversationId}/messages`, { - message, + content: message, private: isPrivate, }); } diff --git a/app/javascript/dashboard/i18n/de.js b/app/javascript/dashboard/i18n/de.js index 55cb77a8c..6988a5d95 100644 --- a/app/javascript/dashboard/i18n/de.js +++ b/app/javascript/dashboard/i18n/de.js @@ -15,6 +15,10 @@ export default { DOWNLOAD: 'Herunterladen', UPLOADING: 'Hochladen...', }, + + FORM_BUBBLE: { + SUBMIT: 'Einreichen', + }, }, CONFIRM_EMAIL: 'Überprüfen...', SETTINGS: { diff --git a/app/javascript/dashboard/i18n/en.js b/app/javascript/dashboard/i18n/en.js index ae0e144d6..61029e9af 100644 --- a/app/javascript/dashboard/i18n/en.js +++ b/app/javascript/dashboard/i18n/en.js @@ -15,6 +15,9 @@ export default { DOWNLOAD: 'Download', UPLOADING: 'Uploading...', }, + FORM_BUBBLE: { + SUBMIT: 'Submit', + }, }, CONFIRM_EMAIL: 'Verifying...', SETTINGS: { diff --git a/app/javascript/packs/sdk.js b/app/javascript/packs/sdk.js index 459c2bc4b..5a9826a7c 100755 --- a/app/javascript/packs/sdk.js +++ b/app/javascript/packs/sdk.js @@ -1,6 +1,5 @@ import Cookies from 'js-cookie'; import { IFrameHelper } from '../sdk/IFrameHelper'; -import { onBubbleClick } from '../sdk/bubbleHelpers'; const runSDK = ({ baseUrl, websiteToken }) => { const chatwootSettings = window.chatwootSettings || {}; @@ -13,7 +12,7 @@ const runSDK = ({ baseUrl, websiteToken }) => { websiteToken, toggle() { - onBubbleClick(); + IFrameHelper.events.toggleBubble(); }, setUser(identifier, user) { @@ -39,7 +38,7 @@ const runSDK = ({ baseUrl, websiteToken }) => { reset() { if (window.$chatwoot.isOpen) { - onBubbleClick(); + IFrameHelper.events.toggleBubble(); } Cookies.remove('cw_conversation'); diff --git a/app/javascript/sdk/IFrameHelper.js b/app/javascript/sdk/IFrameHelper.js index ec55c731d..ed85d7121 100644 --- a/app/javascript/sdk/IFrameHelper.js +++ b/app/javascript/sdk/IFrameHelper.js @@ -88,6 +88,9 @@ export const IFrameHelper = { toggleBubble: () => { onBubbleClick(); + if (window.$chatwoot.isOpen) { + IFrameHelper.pushEvent('webwidget.triggered'); + } }, }, onLoad: ({ widget_color: widgetColor }) => { diff --git a/app/javascript/shared/components/CardButton.vue b/app/javascript/shared/components/CardButton.vue index eea0b1a5a..d6d116ade 100644 --- a/app/javascript/shared/components/CardButton.vue +++ b/app/javascript/shared/components/CardButton.vue @@ -4,6 +4,8 @@ :key="action.uri" class="action-button button" :href="action.uri" + target="_blank" + rel="noopener nofollow noreferrer" > {{ action.text }} @@ -44,11 +46,14 @@ export default { @import '~dashboard/assets/scss/mixins.scss'; .action-button { - width: 100%; - padding: 0; - max-height: 34px; - margin-top: $space-smaller; + align-items: center; border-radius: $space-micro; + display: flex; font-weight: $font-weight-medium; + justify-content: center; + margin-top: $space-smaller; + max-height: 34px; + padding: 0; + width: 100%; } diff --git a/app/javascript/shared/components/ChatCard.vue b/app/javascript/shared/components/ChatCard.vue index 8accb6d8c..4e856bb6b 100644 --- a/app/javascript/shared/components/ChatCard.vue +++ b/app/javascript/shared/components/ChatCard.vue @@ -52,7 +52,6 @@ export default { @import '~dashboard/assets/scss/mixins.scss'; .card-message { - @include border-normal; background: white; max-width: 220px; padding: $space-small; diff --git a/app/javascript/shared/components/ChatForm.vue b/app/javascript/shared/components/ChatForm.vue new file mode 100644 index 000000000..f694db407 --- /dev/null +++ b/app/javascript/shared/components/ChatForm.vue @@ -0,0 +1,114 @@ +