Browse Source

Added set of auto offline if agent is not answering chats for 120 seconds.

Martin Edenhofer 9 years ago
parent
commit
f5fa05bf96

+ 23 - 3
app/assets/javascripts/app/controllers/chat.coffee

@@ -18,6 +18,7 @@ class App.CustomerChat extends App.Controller
       @maxChatWindows = parseInt(preferences.chat.max_windows)
 
     @pushStateIntervalOn = undefined
+    @idleTimeout = parseInt(@Config.get('chat_agent_idle_timeout') || 120)
     @messageCounter = 0
     @meta =
       active: false
@@ -107,10 +108,10 @@ class App.CustomerChat extends App.Controller
 
     @el.find('.js-waitingCustomers').popover(
       trigger:    'hover'
-      container:  'body'
       html:       true
       animation:  false
       delay:      100
+      placement:  'bottom'
       title: ->
         App.i18n.translateContent('Waiting Customers')
       content: =>
@@ -119,10 +120,10 @@ class App.CustomerChat extends App.Controller
 
     @el.find('.js-chattingCustomers').popover(
       trigger:    'hover'
-      container:  'body'
       html:       true
       animation:  false
       delay:      100
+      placement:  'bottom'
       title: ->
         App.i18n.translateContent('Chatting Customers')
       content: =>
@@ -131,10 +132,10 @@ class App.CustomerChat extends App.Controller
 
     @el.find('.js-activeAgents').popover(
       trigger:    'hover'
-      container:  'body'
       html:       true
       animation:  false
       delay:      100
+      placement:  'bottom'
       title: ->
         App.i18n.translateContent('Active Agents')
       content: =>
@@ -225,8 +226,11 @@ class App.CustomerChat extends App.Controller
   updateMeta: =>
     if @meta.waiting_chat_count && @maxChatWindows > @windowCount()
       @$('.js-acceptChat').addClass('is-clickable is-blinking')
+      @idleTimeoutStart()
     else
       @$('.js-acceptChat').removeClass('is-clickable is-blinking')
+      @idleTimeoutStop()
+
     @$('.js-badgeWaitingCustomers').text(@meta.waiting_chat_count)
     @$('.js-badgeChattingCustomers').text(@meta.running_chat_count)
     @$('.js-badgeActiveAgents').text(@meta.active_agent_count)
@@ -271,6 +275,7 @@ class App.CustomerChat extends App.Controller
   acceptChat: =>
     return if @windowCount() >= @maxChatWindows
     App.WebSocket.send(event:'chat_session_start')
+    @idleTimeoutStop()
 
   settings: (errors = {}) ->
     new Setting(
@@ -278,6 +283,21 @@ class App.CustomerChat extends App.Controller
       errors: errors
     )
 
+  idleTimeoutStart: =>
+    return if @idleTimeoutId
+    switchOff = =>
+      @switch(false)
+      @notify(
+        type: 'notice'
+        msg:  App.i18n.translateContent('Chat not answered, set to offline automatically.')
+      )
+    @idleTimeoutId = @delay(switchOff, @idleTimeout * 1000)
+
+  idleTimeoutStop: =>
+    return if !@idleTimeoutId
+    @clearDelay(@idleTimeoutId)
+    @idleTimeoutId = undefined
+
 class CustomerChatRouter extends App.ControllerPermanent
   constructor: (params) ->
     super

+ 51 - 0
app/models/chat.rb

@@ -165,6 +165,57 @@ class Chat < ApplicationModel
 
 =begin
 
+broadcast new agent status to all agents
+
+  Chat.broadcast_agent_state_update
+
+optional you can ignore it for dedecated user
+
+  Chat.broadcast_agent_state_update(ignore_user_id)
+
+=end
+
+  def self.broadcast_agent_state_update(ignore_user_id = nil)
+
+    # send broadcast to agents
+    Chat::Agent.where('active = ? OR updated_at > ?', true, Time.zone.now - 15.minutes).each {|item|
+      next if item.updated_by_id == ignore_user_id
+      data = {
+        event: 'chat_status_agent',
+        data: Chat.agent_state(item.updated_by_id),
+      }
+      Sessions.send_to(item.updated_by_id, data)
+    }
+  end
+
+=begin
+
+broadcast new customer queue position to all waiting customers
+
+  Chat.broadcast_customer_state_update
+
+=end
+
+  def self.broadcast_customer_state_update
+
+    # send position update to other waiting sessions
+    position = 0
+    Chat::Session.where(state: 'waiting').order('created_at ASC').each {|local_chat_session|
+      position += 1
+      data = {
+        event: 'chat_session_queue',
+        data: {
+          state: 'queue',
+          position: position,
+          session_id: local_chat_session.session_id,
+        },
+      }
+      local_chat_session.send_to_recipients(data)
+    }
+  end
+
+=begin
+
 cleanup old chat messages
 
   Chat.cleanup

+ 1 - 0
app/models/observer/chat/leave/background_job.rb

@@ -31,6 +31,7 @@ class Observer::Chat::Leave::BackgroundJob
     }
     chat_session.send_to_recipients(message, @client_id)
 
+    Chat.broadcast_agent_state_update
   end
 
 end

+ 25 - 0
db/migrate/20160106000001_update_chat5.rb

@@ -0,0 +1,25 @@
+class UpdateChat5 < ActiveRecord::Migration
+  def change
+
+    Setting.create_if_not_exists(
+      title: 'Agent idle timeout',
+      name: 'chat_agent_idle_timeout',
+      area: 'Chat::Extended',
+      description: 'Idle timeout in seconds till agent is set offline automatically.',
+      options: {
+        form: [
+          {
+            display: '',
+            null: false,
+            name: 'chat_agent_idle_timeout',
+            tag: 'input',
+          },
+        ],
+      },
+      preferences: {},
+      state: '120',
+      frontend: true
+    )
+
+  end
+end

+ 20 - 0
db/seeds.rb

@@ -1214,6 +1214,26 @@ Setting.create_if_not_exists(
   frontend: true
 )
 
+Setting.create_if_not_exists(
+  title: 'Agent idle timeout',
+  name: 'chat_agent_idle_timeout',
+  area: 'Chat::Extended',
+  description: 'Idle timeout in seconds till agent is set offline automatically.',
+  options: {
+    form: [
+      {
+        display: '',
+        null: false,
+        name: 'chat_agent_idle_timeout',
+        tag: 'input',
+      },
+    ],
+  },
+  preferences: {},
+  state: '120',
+  frontend: true
+)
+
 Setting.create_if_not_exists(
   title: 'Define searchable models.',
   name: 'models_searchable',

+ 1 - 1
lib/sessions/event/chat_agent_state.rb

@@ -9,7 +9,7 @@ class Sessions::Event::ChatAgentState < Sessions::Event::ChatBase
     Chat::Agent.state(@session['id'], @payload['data']['active'])
 
     # broadcast new state to agents
-    broadcast_agent_state_update(@session['id'])
+    Chat.broadcast_agent_state_update(@session['id'])
 
     {
       event: 'chat_agent_state',

+ 0 - 31
lib/sessions/event/chat_base.rb

@@ -23,37 +23,6 @@ class Sessions::Event::ChatBase < Sessions::Event::Base
     }
   end
 
-  def broadcast_agent_state_update(ignore_user_id = nil)
-
-    # send broadcast to agents
-    Chat::Agent.where(active: true).each {|item|
-      next if item.updated_by_id == ignore_user_id
-      data = {
-        event: 'chat_status_agent',
-        data: Chat.agent_state(item.updated_by_id),
-      }
-      Sessions.send_to(item.updated_by_id, data)
-    }
-  end
-
-  def broadcast_customer_state_update
-
-    # send position update to other waiting sessions
-    position = 0
-    Chat::Session.where(state: 'waiting').order('created_at ASC').each {|local_chat_session|
-      position += 1
-      data = {
-        event: 'chat_session_queue',
-        data: {
-          state: 'queue',
-          position: position,
-          session_id: local_chat_session.session_id,
-        },
-      }
-      local_chat_session.send_to_recipients(data)
-    }
-  end
-
   def agent_permission_check
     if !@session
       error = {

+ 2 - 2
lib/sessions/event/chat_session_close.rb

@@ -32,10 +32,10 @@ class Sessions::Event::ChatSessionClose < Sessions::Event::ChatBase
       chat_session.save
 
       # set state update to all agents
-      broadcast_agent_state_update
+      Chat.broadcast_agent_state_update
 
       # send position update to other waiting sessions
-      broadcast_customer_state_update
+      Chat.broadcast_customer_state_update
 
     # notify about "leaving"
     else

+ 1 - 1
lib/sessions/event/chat_session_init.rb

@@ -23,7 +23,7 @@ class Sessions::Event::ChatSessionInit < Sessions::Event::ChatBase
     )
 
     # send broadcast to agents
-    broadcast_agent_state_update
+    Chat.broadcast_agent_state_update
 
     # return new session
     {

+ 2 - 2
lib/sessions/event/chat_session_start.rb

@@ -52,10 +52,10 @@ class Sessions::Event::ChatSessionStart < Sessions::Event::ChatBase
     Sessions.send(@client_id, data)
 
     # send state update with sessions to agents
-    broadcast_agent_state_update
+    Chat.broadcast_agent_state_update
 
     # send position update to other waiting sessions
-    broadcast_customer_state_update
+    Chat.broadcast_customer_state_update
 
     nil
   end

Some files were not shown because too many files changed in this diff