From 16fe912fbdef3a1f0d5569aed39a80f4d7de9a4e Mon Sep 17 00:00:00 2001 From: Pranav Raj S Date: Tue, 29 Oct 2019 12:50:54 +0530 Subject: [PATCH] [Feature] Website live chat (#187) Co-authored-by: Nithin David Thomas Co-authored-by: Sojan Jose --- .scss-lint.yml | 4 + Gemfile | 2 + Gemfile.lock | 2 + .../api/v1/widget/inboxes_controller.rb | 26 +++ .../api/v1/widget/messages_controller.rb | 74 ++++++-- app/controllers/widgets_controller.rb | 47 +++++ app/finders/message_finder.rb | 10 +- .../dashboard/api/channel/webChannel.js | 9 + .../assets/images/channels/website.png | Bin 0 -> 6037 bytes .../assets/scss/_foundation-custom.scss | 11 ++ .../dashboard/components/ChatList.vue | 2 +- .../components/layout/SidebarItem.vue | 2 +- .../components/widgets/ChannelItem.vue | 52 ++++-- app/javascript/dashboard/constants.js | 3 - .../dashboard/helper/actionCable.js | 23 +-- .../dashboard/i18n/locale/en/inboxMgmt.json | 13 ++ .../dashboard/settings/inbox/ChannelList.vue | 22 +-- .../routes/dashboard/settings/inbox/Index.vue | 9 +- .../dashboard/settings/inbox/Settings.vue | 34 +++- .../settings/inbox/channel-factory.js | 26 +-- .../inbox/{ => channels}/Facebook.vue | 9 +- .../settings/inbox/channels/Website.vue | 83 +++++++++ .../dashboard/store/modules/sidebar.js | 17 +- app/javascript/packs/application.js | 7 + app/javascript/packs/sdk.js | 160 ++++++++++++++++++ app/javascript/packs/widget.js | 19 +++ .../helpers/BaseActionCableConnector.js | 26 +++ app/javascript/widget/App.vue | 25 +++ app/javascript/widget/api/auth.js | 12 ++ app/javascript/widget/api/conversation.js | 16 ++ app/javascript/widget/api/endPoints.js | 17 ++ .../widget/assets/images/defaultUser.png | Bin 0 -> 3856 bytes .../widget/assets/images/message-send.svg | 11 ++ app/javascript/widget/assets/images/send.png | Bin 0 -> 1795 bytes .../widget/assets/scss/_buttons.scss | 57 +++++++ app/javascript/widget/assets/scss/_forms.scss | 71 ++++++++ .../widget/assets/scss/_mixins.scss | 20 +++ app/javascript/widget/assets/scss/_reset.scss | 54 ++++++ .../widget/assets/scss/_variables.scss | 90 ++++++++++ app/javascript/widget/assets/scss/sdk.css | 65 +++++++ app/javascript/widget/assets/scss/woot.scss | 16 ++ .../widget/components/AgentMessage.vue | 83 +++++++++ .../widget/components/AgentMessageBubble.vue | 27 +++ .../widget/components/ChatFooter.vue | 33 ++++ .../widget/components/ChatHeaderExpanded.vue | 51 ++++++ .../widget/components/ChatInputArea.vue | 29 ++++ .../widget/components/ChatInputWrap.vue | 65 +++++++ .../widget/components/ChatMessage.vue | 38 +++++ .../widget/components/ChatSendButton.vue | 63 +++++++ .../widget/components/ConversationWrap.vue | 33 ++++ .../widget/components/HelloWorld.vue | 31 ++++ app/javascript/widget/components/Spinner.vue | 52 ++++++ .../widget/components/UserAvatar.vue | 46 +++++ .../widget/components/UserMessage.vue | 55 ++++++ .../widget/components/UserMessageBubble.vue | 36 ++++ app/javascript/widget/helpers/actionCable.js | 16 ++ app/javascript/widget/helpers/axios.js | 15 ++ app/javascript/widget/helpers/constants.js | 12 ++ app/javascript/widget/helpers/utils.js | 10 ++ app/javascript/widget/router.js | 24 +++ app/javascript/widget/store/index.js | 11 ++ .../widget/store/modules/conversation.js | 60 +++++++ app/javascript/widget/views/About.vue | 5 + app/javascript/widget/views/Home.vue | 78 +++++++++ app/listeners/action_cable_listener.rb | 8 + app/models/account.rb | 1 + app/models/channel/web_widget.rb | 17 ++ app/views/api/v1/inboxes/index.json.jbuilder | 1 + .../v1/widget/messages/index.json.jbuilder | 9 + app/views/layouts/vueapp.html.erb | 2 +- app/views/widgets/index.html.erb | 18 ++ config/application.rb | 4 + config/routes.rb | 10 +- config/webpack/development.js | 4 - config/webpack/environment.js | 5 + config/webpack/resolve.js | 1 + ...4062958_add_website_token_to_web_widget.rb | 6 + db/schema.rb | 3 +- package.json | 4 +- yarn.lock | 34 +++- 80 files changed, 2040 insertions(+), 106 deletions(-) create mode 100644 app/controllers/api/v1/widget/inboxes_controller.rb create mode 100644 app/controllers/widgets_controller.rb create mode 100644 app/javascript/dashboard/api/channel/webChannel.js create mode 100644 app/javascript/dashboard/assets/images/channels/website.png rename app/javascript/dashboard/routes/dashboard/settings/inbox/{ => channels}/Facebook.vue (96%) create mode 100644 app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Website.vue create mode 100755 app/javascript/packs/sdk.js create mode 100644 app/javascript/packs/widget.js create mode 100644 app/javascript/shared/helpers/BaseActionCableConnector.js create mode 100755 app/javascript/widget/App.vue create mode 100755 app/javascript/widget/api/auth.js create mode 100755 app/javascript/widget/api/conversation.js create mode 100755 app/javascript/widget/api/endPoints.js create mode 100755 app/javascript/widget/assets/images/defaultUser.png create mode 100755 app/javascript/widget/assets/images/message-send.svg create mode 100755 app/javascript/widget/assets/images/send.png create mode 100755 app/javascript/widget/assets/scss/_buttons.scss create mode 100755 app/javascript/widget/assets/scss/_forms.scss create mode 100755 app/javascript/widget/assets/scss/_mixins.scss create mode 100755 app/javascript/widget/assets/scss/_reset.scss create mode 100755 app/javascript/widget/assets/scss/_variables.scss create mode 100644 app/javascript/widget/assets/scss/sdk.css create mode 100755 app/javascript/widget/assets/scss/woot.scss create mode 100755 app/javascript/widget/components/AgentMessage.vue create mode 100755 app/javascript/widget/components/AgentMessageBubble.vue create mode 100755 app/javascript/widget/components/ChatFooter.vue create mode 100755 app/javascript/widget/components/ChatHeaderExpanded.vue create mode 100755 app/javascript/widget/components/ChatInputArea.vue create mode 100755 app/javascript/widget/components/ChatInputWrap.vue create mode 100755 app/javascript/widget/components/ChatMessage.vue create mode 100755 app/javascript/widget/components/ChatSendButton.vue create mode 100755 app/javascript/widget/components/ConversationWrap.vue create mode 100755 app/javascript/widget/components/HelloWorld.vue create mode 100755 app/javascript/widget/components/Spinner.vue create mode 100755 app/javascript/widget/components/UserAvatar.vue create mode 100755 app/javascript/widget/components/UserMessage.vue create mode 100755 app/javascript/widget/components/UserMessageBubble.vue create mode 100644 app/javascript/widget/helpers/actionCable.js create mode 100755 app/javascript/widget/helpers/axios.js create mode 100755 app/javascript/widget/helpers/constants.js create mode 100755 app/javascript/widget/helpers/utils.js create mode 100755 app/javascript/widget/router.js create mode 100755 app/javascript/widget/store/index.js create mode 100755 app/javascript/widget/store/modules/conversation.js create mode 100755 app/javascript/widget/views/About.vue create mode 100755 app/javascript/widget/views/Home.vue create mode 100644 app/views/api/v1/widget/messages/index.json.jbuilder create mode 100644 app/views/widgets/index.html.erb create mode 100644 db/migrate/20191024062958_add_website_token_to_web_widget.rb diff --git a/.scss-lint.yml b/.scss-lint.yml index 59284ef1c..215e9c49e 100644 --- a/.scss-lint.yml +++ b/.scss-lint.yml @@ -1,3 +1,7 @@ linters: LeadingZero: enabled: false + +exclude: + - 'app/javascript/widget/assets/scss/_reset.scss' + - 'app/javascript/widget/assets/scss/sdk.css' diff --git a/Gemfile b/Gemfile index 893be6119..1fb109bbb 100644 --- a/Gemfile +++ b/Gemfile @@ -53,6 +53,8 @@ gem 'telegram-bot-ruby' gem 'twitter' # facebook client gem 'koala' +# Random name generator +gem 'haikunator' ##--- gems for debugging and error reporting ---## # static analysis diff --git a/Gemfile.lock b/Gemfile.lock index 205747213..c74e87f2d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -192,6 +192,7 @@ GEM foreman (0.86.0) globalid (0.4.2) activesupport (>= 4.2.0) + haikunator (1.1.0) hashie (3.6.0) http (3.3.0) addressable (~> 2.3) @@ -455,6 +456,7 @@ DEPENDENCIES faker figaro foreman + haikunator hashie jbuilder (~> 2.5) kaminari diff --git a/app/controllers/api/v1/widget/inboxes_controller.rb b/app/controllers/api/v1/widget/inboxes_controller.rb new file mode 100644 index 000000000..2e0269db0 --- /dev/null +++ b/app/controllers/api/v1/widget/inboxes_controller.rb @@ -0,0 +1,26 @@ +class Api::V1::Widget::InboxesController < ApplicationController + def create + ActiveRecord::Base.transaction do + channel = web_widgets.create!( + website_name: permitted_params[:website_name], + website_url: permitted_params[:website_url] + ) + inbox = inboxes.create!(name: permitted_params[:website_name], channel: channel) + render json: inbox + end + end + + private + + def inboxes + current_account.inboxes + end + + def web_widgets + current_account.web_widgets + end + + def permitted_params + params.fetch(:website).permit(:website_name, :website_url) + end +end diff --git a/app/controllers/api/v1/widget/messages_controller.rb b/app/controllers/api/v1/widget/messages_controller.rb index 8bc2cf446..662fd927e 100644 --- a/app/controllers/api/v1/widget/messages_controller.rb +++ b/app/controllers/api/v1/widget/messages_controller.rb @@ -1,28 +1,68 @@ -class Api::V1::Widget::MessagesController < ApplicationController - # TODO: move widget apis to different controller. - skip_before_action :set_current_user, only: [:create_incoming] - skip_before_action :check_subscription, only: [:create_incoming] - skip_around_action :handle_with_exception, only: [:create_incoming] +class Api::V1::Widget::MessagesController < ActionController::Base + before_action :set_conversation, only: [:create] - def create_incoming - builder = Integrations::Widget::IncomingMessageBuilder.new(incoming_message_params) - builder.perform - render json: builder.message + def index + @messages = conversation.nil? ? [] : message_finder.perform end - def create_outgoing - builder = Integrations::Widget::OutgoingMessageBuilder.new(outgoing_message_params) - builder.perform - render json: builder.message + def create + @message = conversation.messages.new(message_params) + @message.save! end private - def incoming_message_params - params.require(:message).permit(:contact_id, :inbox_id, :content) + def conversation + @conversation ||= ::Conversation.find_by( + contact_id: cookie_params[:contact_id], + inbox_id: cookie_params[:inbox_id] + ) end - def outgoing_message_params - params.require(:message).permit(:user_id, :inbox_id, :content, :conversation_id) + def set_conversation + @conversation = ::Conversation.create!(conversation_params) if conversation.nil? + end + + def message_params + { + account_id: conversation.account_id, + inbox_id: conversation.inbox_id, + message_type: :incoming, + content: permitted_params[:content] + } + end + + def conversation_params + { + account_id: inbox.account_id, + inbox_id: inbox.id, + contact_id: cookie_params[:contact_id] + } + end + + def inbox + @inbox ||= ::Inbox.find_by(id: cookie_params[:inbox_id]) + end + + def cookie_params + JSON.parse(cookies.signed[cookie_name]).symbolize_keys + end + + def message_finder_params + { + filter_internal_messages: true + } + end + + def message_finder + @message_finder ||= MessageFinder.new(conversation, message_finder_params) + end + + def cookie_name + 'cw_conversation_' + params[:website_token] + end + + def permitted_params + params.fetch(:message).permit(:content) end end diff --git a/app/controllers/widgets_controller.rb b/app/controllers/widgets_controller.rb new file mode 100644 index 000000000..733e99df4 --- /dev/null +++ b/app/controllers/widgets_controller.rb @@ -0,0 +1,47 @@ +class WidgetsController < ActionController::Base + before_action :set_web_widget + before_action :set_contact + before_action :build_contact + + private + + def set_web_widget + @web_widget = ::Channel::WebWidget.find_by!(website_token: permitted_params[:website_token]) + end + + def set_contact + return if cookie_params[:source_id].nil? + + contact_inbox = ::ContactInbox.find_by( + inbox_id: @web_widget.inbox.id, + source_id: cookie_params[:source_id] + ) + + @contact = contact_inbox.contact + end + + def build_contact + return if @contact.present? + + contact_inbox = @web_widget.create_contact_inbox + @contact = contact_inbox.contact + + cookies.signed[cookie_name] = JSON.generate( + source_id: contact_inbox.source_id, + contact_id: @contact.id, + inbox_id: @web_widget.inbox.id + ).to_s + end + + def cookie_params + cookies.signed[cookie_name] ? JSON.parse(cookies.signed[cookie_name]).symbolize_keys : {} + end + + def permitted_params + params.permit(:website_token) + end + + def cookie_name + 'cw_conversation_' + permitted_params[:website_token] + end +end diff --git a/app/finders/message_finder.rb b/app/finders/message_finder.rb index bcac94418..e839e4946 100644 --- a/app/finders/message_finder.rb +++ b/app/finders/message_finder.rb @@ -10,11 +10,17 @@ class MessageFinder private + def messages + return @conversation.messages if @params[:filter_internal_messages].blank? + + @conversation.messages.where.not('private = ? OR message_type = ?', true, 2) + end + def current_messages if @params[:before].present? - @conversation.messages.reorder('created_at desc').where('id < ?', @params[:before]).limit(20).reverse + messages.reorder('created_at desc').where('id < ?', @params[:before]).limit(20).reverse else - @conversation.messages.reorder('created_at desc').limit(20).reverse + messages.reorder('created_at desc').limit(20).reverse end end end diff --git a/app/javascript/dashboard/api/channel/webChannel.js b/app/javascript/dashboard/api/channel/webChannel.js new file mode 100644 index 000000000..7fc5fb2db --- /dev/null +++ b/app/javascript/dashboard/api/channel/webChannel.js @@ -0,0 +1,9 @@ +import ApiClient from '../ApiClient'; + +class WebChannel extends ApiClient { + constructor() { + super('widget/inboxes'); + } +} + +export default new WebChannel(); diff --git a/app/javascript/dashboard/assets/images/channels/website.png b/app/javascript/dashboard/assets/images/channels/website.png new file mode 100644 index 0000000000000000000000000000000000000000..fdc909bc28d0c0bfc2f458085bed5f2a5af85e28 GIT binary patch literal 6037 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 literal 0 HcmV?d00001 diff --git a/app/javascript/dashboard/assets/scss/_foundation-custom.scss b/app/javascript/dashboard/assets/scss/_foundation-custom.scss index 0a70eaf89..f918ed97c 100644 --- a/app/javascript/dashboard/assets/scss/_foundation-custom.scss +++ b/app/javascript/dashboard/assets/scss/_foundation-custom.scss @@ -25,3 +25,14 @@ border-radius: $space-smaller; font-size: $font-size-mini; } + +code { + border: 0; + font-family: 'Monaco'; + font-size: $font-size-mini; + + &.hljs { + background: $color-background; + padding: $space-two; + } +} diff --git a/app/javascript/dashboard/components/ChatList.vue b/app/javascript/dashboard/components/ChatList.vue index 2b771a973..a996aae43 100644 --- a/app/javascript/dashboard/components/ChatList.vue +++ b/app/javascript/dashboard/components/ChatList.vue @@ -121,7 +121,7 @@ export default { fetchData() { if (this.chatLists.length === 0) { this.$store.dispatch('fetchAllConversations', { - inbox: this.conversationInbox, + inboxId: this.conversationInbox ? this.conversationInbox : undefined, assigneeStatus: this.allMessageType, convStatus: this.activeStatusTab, }); diff --git a/app/javascript/dashboard/components/layout/SidebarItem.vue b/app/javascript/dashboard/components/layout/SidebarItem.vue index c48998ba8..087467616 100644 --- a/app/javascript/dashboard/components/layout/SidebarItem.vue +++ b/app/javascript/dashboard/components/layout/SidebarItem.vue @@ -22,7 +22,7 @@