Added cti call log ui.
This commit is contained in:
parent
30acbec315
commit
4646aca840
10 changed files with 492 additions and 50 deletions
114
app/assets/javascripts/app/controllers/cti.coffee
Normal file
114
app/assets/javascripts/app/controllers/cti.coffee
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
class App.CTI extends App.Controller
|
||||||
|
constructor: ->
|
||||||
|
super
|
||||||
|
|
||||||
|
@meta =
|
||||||
|
active: false
|
||||||
|
|
||||||
|
preferences = @Session.get('preferences') || {}
|
||||||
|
@meta.active = preferences.cti || false
|
||||||
|
|
||||||
|
@load()
|
||||||
|
|
||||||
|
App.Event.bind(
|
||||||
|
'cti_event'
|
||||||
|
(data) =>
|
||||||
|
console.log('cti_event', data)
|
||||||
|
if data.state is 'newCall'
|
||||||
|
console.log('notify')
|
||||||
|
@notify(data)
|
||||||
|
'cti_event'
|
||||||
|
)
|
||||||
|
App.Event.bind(
|
||||||
|
'cti_list_push'
|
||||||
|
(data) =>
|
||||||
|
@list = data
|
||||||
|
@render()
|
||||||
|
'cti_list_push'
|
||||||
|
)
|
||||||
|
|
||||||
|
# fetch data, render view
|
||||||
|
load: ->
|
||||||
|
@ajax(
|
||||||
|
id: 'cti_log'
|
||||||
|
type: 'GET'
|
||||||
|
url: "#{@apiPath}/cti/log"
|
||||||
|
success: (data) =>
|
||||||
|
@list = data
|
||||||
|
@render()
|
||||||
|
)
|
||||||
|
|
||||||
|
notify: (data) ->
|
||||||
|
console.log(data)
|
||||||
|
#return if !
|
||||||
|
if data.state is 'newCall' && data.direction is 'in'
|
||||||
|
App.Event.trigger 'notify', {
|
||||||
|
type: 'notice'
|
||||||
|
msg: App.i18n.translateContent('Call from %s for %s', data.from, data.to)
|
||||||
|
timeout: 2500
|
||||||
|
}
|
||||||
|
|
||||||
|
featureActive: =>
|
||||||
|
return true
|
||||||
|
if @Config.get('sipgate_integration')
|
||||||
|
return true
|
||||||
|
false
|
||||||
|
|
||||||
|
render: ->
|
||||||
|
if !@isRole('CTI')
|
||||||
|
@renderScreenUnauthorized(objectName: 'CTI')
|
||||||
|
return
|
||||||
|
|
||||||
|
@html App.view('cti/index')(
|
||||||
|
list: @list
|
||||||
|
)
|
||||||
|
|
||||||
|
@updateNavMenu()
|
||||||
|
|
||||||
|
show: (params) =>
|
||||||
|
@title 'CTI', true
|
||||||
|
@navupdate '#cti'
|
||||||
|
|
||||||
|
counter: ->
|
||||||
|
counter = 0
|
||||||
|
|
||||||
|
switch: (state = undefined) =>
|
||||||
|
|
||||||
|
# read state
|
||||||
|
if state is undefined
|
||||||
|
return @meta.active
|
||||||
|
|
||||||
|
@meta.active = state
|
||||||
|
|
||||||
|
# update user preferences
|
||||||
|
@ajax(
|
||||||
|
id: 'preferences'
|
||||||
|
type: 'PUT'
|
||||||
|
url: "#{@apiPath}/users/preferences"
|
||||||
|
data: JSON.stringify(user: {cti: state})
|
||||||
|
processData: true
|
||||||
|
)
|
||||||
|
|
||||||
|
updateNavMenu: =>
|
||||||
|
delay = ->
|
||||||
|
App.Event.trigger('menu:render')
|
||||||
|
@delay(delay, 200, 'updateNavMenu')
|
||||||
|
|
||||||
|
class CTIRouter extends App.ControllerPermanent
|
||||||
|
constructor: (params) ->
|
||||||
|
super
|
||||||
|
|
||||||
|
# check authentication
|
||||||
|
return if !@authenticate(false, 'CTI')
|
||||||
|
|
||||||
|
App.TaskManager.execute(
|
||||||
|
key: 'CTI'
|
||||||
|
controller: 'CTI'
|
||||||
|
params: {}
|
||||||
|
show: true
|
||||||
|
persistent: true
|
||||||
|
)
|
||||||
|
|
||||||
|
App.Config.set('cti', CTIRouter, 'Routes')
|
||||||
|
App.Config.set('CTI', { controller: 'CTI', authentication: true }, 'permanentTask')
|
||||||
|
App.Config.set('CTI', { prio: 1300, parent: '', name: 'Phone', target: '#cti', key: 'CTI', shown: false, role: ['CTI'], class: 'phone' }, 'NavBar')
|
28
app/assets/javascripts/app/views/cti/index.jst.eco
Normal file
28
app/assets/javascripts/app/views/cti/index.jst.eco
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<div class="main flex">
|
||||||
|
<h1><%- @T('Caller log') %></h1>
|
||||||
|
|
||||||
|
<div class="page-content">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th><%- @T('From') %></th>
|
||||||
|
<th><%- @T('To') %></th>
|
||||||
|
<th><%- @T('State') %></th>
|
||||||
|
<th><%- @T('Comment') %></th>
|
||||||
|
<th><%- @T('Time') %></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% for item in @list: %>
|
||||||
|
<tr>
|
||||||
|
<td><%= item.from %></td>
|
||||||
|
<td><%= item.to %></td>
|
||||||
|
<td><%= item.state %></td>
|
||||||
|
<td><%= item.comment %></td>
|
||||||
|
<td><%- @humanTime(item.created_at) %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -287,12 +287,11 @@ class ApplicationController < ActionController::Base
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def authentication_check(auth_param = {} )
|
def authentication_check(auth_param = {})
|
||||||
result = authentication_check_only(auth_param)
|
result = authentication_check_only(auth_param)
|
||||||
|
|
||||||
# check if basic_auth fallback is possible
|
# check if basic_auth fallback is possible
|
||||||
if auth_param[:basic_auth_promt] && result[:auth] == false
|
if auth_param[:basic_auth_promt] && result[:auth] == false
|
||||||
|
|
||||||
return request_http_basic_authentication
|
return request_http_basic_authentication
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,54 +1,60 @@
|
||||||
|
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
require 'builder'
|
require 'builder'
|
||||||
|
|
||||||
class Integration::SipgateController < ApplicationController
|
class Integration::SipgateController < ApplicationController
|
||||||
before_action { http_log_config facility: 'sipgate.io' }
|
|
||||||
|
# list current caller log
|
||||||
|
def index
|
||||||
|
return if !authentication_check
|
||||||
|
return if deny_if_not_role('CTI')
|
||||||
|
list = Cti::Log.order('created_at DESC').limit(60)
|
||||||
|
render json: list
|
||||||
|
end
|
||||||
|
|
||||||
# notify about inbound call / block inbound call
|
# notify about inbound call / block inbound call
|
||||||
def in
|
def in
|
||||||
|
http_log_config facility: 'sipgate.io'
|
||||||
return if !configured?
|
return if !configured?
|
||||||
|
|
||||||
|
if params['event'] == 'newCall'
|
||||||
|
|
||||||
config = Setting.get('sipgate_config')
|
config = Setting.get('sipgate_config')
|
||||||
config_inbound = config[:inbound] || {}
|
config_inbound = config[:inbound] || {}
|
||||||
block_caller_ids = config_inbound[:block_caller_ids] || []
|
block_caller_ids = config_inbound[:block_caller_ids] || []
|
||||||
|
|
||||||
if params['event'] == 'newCall'
|
|
||||||
|
|
||||||
# check if call need to be blocked
|
# check if call need to be blocked
|
||||||
block_caller_ids.each {|item|
|
block_caller_ids.each {|item|
|
||||||
next unless item[:caller_id] == params['from']
|
next unless item[:caller_id] == params['from']
|
||||||
xml = Builder::XmlMarkup.new(indent: 2)
|
xml = Builder::XmlMarkup.new(indent: 2)
|
||||||
xml.instruct!
|
xml.instruct!
|
||||||
content = xml.Response('onHangup' => in_url, 'onAnswer' => in_url) do
|
content = xml.Response(onHangup: url, onAnswer: url) do
|
||||||
xml.Reject('reason' => 'busy')
|
xml.Reject('reason' => 'busy')
|
||||||
end
|
end
|
||||||
|
|
||||||
send_data content, type: 'application/xml; charset=UTF-8;'
|
send_data content, type: 'application/xml; charset=UTF-8;'
|
||||||
|
|
||||||
params['Reject'] = 'busy'
|
#params['Reject'] = 'busy'
|
||||||
Sessions.broadcast(
|
params['comment'] = 'reject, busy'
|
||||||
event: 'sipgate.io',
|
if params['user']
|
||||||
data: params
|
params['comment'] = "#{params['user']} -> reject, busy"
|
||||||
)
|
end
|
||||||
|
update_log(params)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
update_log(params)
|
||||||
|
|
||||||
xml = Builder::XmlMarkup.new(indent: 2)
|
xml = Builder::XmlMarkup.new(indent: 2)
|
||||||
xml.instruct!
|
xml.instruct!
|
||||||
content = xml.Response('onHangup' => in_url, 'onAnswer' => in_url)
|
content = xml.Response(onHangup: url, onAnswer: url)
|
||||||
|
|
||||||
send_data content, type: 'application/xml; charset=UTF-8;'
|
send_data content, type: 'application/xml; charset=UTF-8;'
|
||||||
|
|
||||||
# search for caller
|
|
||||||
Sessions.broadcast(
|
|
||||||
event: 'sipgate.io',
|
|
||||||
data: params
|
|
||||||
)
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# set caller id of outbound call
|
# set caller id of outbound call
|
||||||
def out
|
def out
|
||||||
|
http_log_config facility: 'sipgate.io'
|
||||||
return if !configured?
|
return if !configured?
|
||||||
|
|
||||||
config = Setting.get('sipgate_config')
|
config = Setting.get('sipgate_config')
|
||||||
|
@ -61,31 +67,32 @@ class Integration::SipgateController < ApplicationController
|
||||||
# set callerId
|
# set callerId
|
||||||
content = nil
|
content = nil
|
||||||
to = params[:to]
|
to = params[:to]
|
||||||
|
from = nil
|
||||||
if to
|
if to
|
||||||
config_outbound.each {|row|
|
config_outbound.each {|row|
|
||||||
dest = row[:dest].gsub(/\*/, '.+?')
|
dest = row[:dest].gsub(/\*/, '.+?')
|
||||||
next if to !~ /^#{dest}$/
|
next if to !~ /^#{dest}$/
|
||||||
content = xml.Response('onHangup' => in_url, 'onAnswer' => in_url) do
|
from = row[:caller_id]
|
||||||
xml.Dial(callerId: row[:caller_id]) { xml.Number(params[:to]) }
|
content = xml.Response(onHangup: url, onAnswer: url) do
|
||||||
|
xml.Dial(callerId: from) { xml.Number(params[:to]) }
|
||||||
end
|
end
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if !content && default_caller_id
|
if !content && default_caller_id
|
||||||
content = xml.Response('onHangup' => in_url, 'onAnswer' => in_url) do
|
from = default_caller_id
|
||||||
|
content = xml.Response(onHangup: url, onAnswer: url) do
|
||||||
xml.Dial(callerId: default_caller_id) { xml.Number(params[:to]) }
|
xml.Dial(callerId: default_caller_id) { xml.Number(params[:to]) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
content = xml.Response('onHangup' => in_url, 'onAnswer' => in_url)
|
content = xml.Response(onHangup: url, onAnswer: url)
|
||||||
end
|
end
|
||||||
|
|
||||||
send_data content, type: 'application/xml; charset=UTF-8;'
|
send_data content, type: 'application/xml; charset=UTF-8;'
|
||||||
|
if from
|
||||||
# notify about outbound call
|
params['from'] = from
|
||||||
Sessions.broadcast(
|
end
|
||||||
event: 'sipgate.io:out',
|
update_log(params)
|
||||||
data: params
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -103,23 +110,69 @@ class Integration::SipgateController < ApplicationController
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_log(params)
|
||||||
|
|
||||||
|
user = params['user']
|
||||||
|
if params['user'] && params['user'].class == Array
|
||||||
|
user = params['user'].join(', ')
|
||||||
|
end
|
||||||
|
from_comment = nil
|
||||||
|
to_comment = nil
|
||||||
|
if params['direction'] == 'in'
|
||||||
|
to_comment = user
|
||||||
|
else
|
||||||
|
from_comment = user
|
||||||
|
end
|
||||||
|
comment = nil
|
||||||
|
if params['cause']
|
||||||
|
comment = params['cause']
|
||||||
|
end
|
||||||
|
|
||||||
|
if params['event'] == 'newCall'
|
||||||
|
Cti::Log.create(
|
||||||
|
direction: params['direction'],
|
||||||
|
from: params['from'],
|
||||||
|
from_comment: from_comment,
|
||||||
|
to: params['to'],
|
||||||
|
to_comment: to_comment,
|
||||||
|
call_id: params['callId'],
|
||||||
|
comment: comment,
|
||||||
|
state: params['event'],
|
||||||
|
)
|
||||||
|
elsif params['event'] == 'answer'
|
||||||
|
log = Cti::Log.find_by(call_id: params['callId'])
|
||||||
|
raise "No such call_id #{params['callId']}" if !log
|
||||||
|
log.state = 'answer'
|
||||||
|
log.comment = comment
|
||||||
|
log.save
|
||||||
|
elsif params['event'] == 'hangup'
|
||||||
|
log = Cti::Log.find_by(call_id: params['callId'])
|
||||||
|
raise "No such call_id #{params['callId']}" if !log
|
||||||
|
log.state = 'hangup'
|
||||||
|
log.comment = comment
|
||||||
|
log.save
|
||||||
|
else
|
||||||
|
raise "Unknown event #{params['event']}"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
def xml_error(error)
|
def xml_error(error)
|
||||||
xml = Builder::XmlMarkup.new(indent: 2)
|
xml = Builder::XmlMarkup.new(indent: 2)
|
||||||
xml.instruct!
|
xml.instruct!
|
||||||
content = xml.Response() do
|
content = xml.Response() do
|
||||||
xml.Error(error)
|
xml.Error(error)
|
||||||
end
|
end
|
||||||
send_data content, type: 'application/xml; charset=UTF-8;', status: '500'
|
send_data content, type: 'application/xml; charset=UTF-8;', status: 422
|
||||||
end
|
end
|
||||||
|
|
||||||
def base_url
|
def base_url
|
||||||
http_type = Setting.get('http_type')
|
http_type = Setting.get('http_type')
|
||||||
fqdn = Setting.get('fqdn')
|
fqdn = Setting.get('fqdn')
|
||||||
|
|
||||||
"#{http_type}://#{fqdn}/api/v1/sipgate"
|
"#{http_type}://#{fqdn}/api/v1/sipgate"
|
||||||
end
|
end
|
||||||
|
|
||||||
def in_url
|
def url
|
||||||
"#{base_url}/in"
|
"#{base_url}/#{params['direction']}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -85,7 +85,7 @@ class UsersController < ApplicationController
|
||||||
group_ids = []
|
group_ids = []
|
||||||
role_ids = []
|
role_ids = []
|
||||||
if count <= 2
|
if count <= 2
|
||||||
Role.where(name: [ Z_ROLENAME_ADMIN, 'Agent', 'Chat']).each { |role|
|
Role.where(name: [ Z_ROLENAME_ADMIN, 'Agent', 'Chat', 'CTI']).each { |role|
|
||||||
role_ids.push role.id
|
role_ids.push role.id
|
||||||
}
|
}
|
||||||
Group.all().each { |group|
|
Group.all().each { |group|
|
||||||
|
|
78
app/models/cti/log.rb
Normal file
78
app/models/cti/log.rb
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
module Cti
|
||||||
|
class Log < ApplicationModel
|
||||||
|
self.table_name = 'cti_logs'
|
||||||
|
|
||||||
|
after_create :push_event, :push_caller_list
|
||||||
|
after_update :push_event, :push_caller_list
|
||||||
|
after_destroy :push_event, :push_caller_list
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
Cti::Log.create(
|
||||||
|
direction: 'in',
|
||||||
|
from: '007',
|
||||||
|
from_comment: '',
|
||||||
|
to: '008',
|
||||||
|
to_comment: '',
|
||||||
|
call_id: '1',
|
||||||
|
comment: '',
|
||||||
|
state: 'newCall',
|
||||||
|
)
|
||||||
|
|
||||||
|
Cti::Log.create(
|
||||||
|
direction: 'in',
|
||||||
|
from: '007',
|
||||||
|
from_comment: '',
|
||||||
|
to: '008',
|
||||||
|
to_comment: '',
|
||||||
|
call_id: '2',
|
||||||
|
comment: '',
|
||||||
|
state: 'answer',
|
||||||
|
)
|
||||||
|
|
||||||
|
Cti::Log.create(
|
||||||
|
direction: 'in',
|
||||||
|
from: '009',
|
||||||
|
from_comment: '',
|
||||||
|
to: '010',
|
||||||
|
to_comment: '',
|
||||||
|
call_id: '3',
|
||||||
|
comment: '',
|
||||||
|
state: 'hangup',
|
||||||
|
)
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def push_event
|
||||||
|
users = User.of_role('CTI')
|
||||||
|
users.each {|user|
|
||||||
|
|
||||||
|
# send notify about event
|
||||||
|
Sessions.send_to(
|
||||||
|
user.id,
|
||||||
|
{
|
||||||
|
event: 'cti_event',
|
||||||
|
data: self,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def push_caller_list
|
||||||
|
list = Cti::Log.order('created_at DESC').limit(60)
|
||||||
|
|
||||||
|
users = User.of_role('CTI')
|
||||||
|
users.each {|user|
|
||||||
|
|
||||||
|
# send notify on create/update/delete
|
||||||
|
Sessions.send_to(
|
||||||
|
user.id,
|
||||||
|
{
|
||||||
|
event: 'cti_list_push',
|
||||||
|
data: list,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,5 +1,6 @@
|
||||||
Zammad::Application.routes.draw do
|
Zammad::Application.routes.draw do
|
||||||
|
|
||||||
|
match '/api/v1/cti/log', to: 'integration/sipgate#index', via: :get
|
||||||
match '/api/v1/sipgate/in', to: 'integration/sipgate#in', via: :post
|
match '/api/v1/sipgate/in', to: 'integration/sipgate#in', via: :post
|
||||||
match '/api/v1/sipgate/out', to: 'integration/sipgate#out', via: :post
|
match '/api/v1/sipgate/out', to: 'integration/sipgate#out', via: :post
|
||||||
|
|
||||||
|
|
26
db/migrate/20160422000003_create_cti_log.rb
Normal file
26
db/migrate/20160422000003_create_cti_log.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
class CreateCtiLog < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
create_table :cti_logs do |t|
|
||||||
|
t.string :direction, limit: 20, null: false
|
||||||
|
t.string :state, limit: 20, null: false
|
||||||
|
t.string :from, limit: 100, null: false
|
||||||
|
t.string :from_comment, limit: 250, null: true
|
||||||
|
t.string :to, limit: 100, null: false
|
||||||
|
t.string :to_comment, limit: 250, null: true
|
||||||
|
t.string :call_id, limit: 250, null: false
|
||||||
|
t.string :comment, limit: 500, null: true
|
||||||
|
t.timestamps null: false
|
||||||
|
end
|
||||||
|
add_index :cti_logs, [:call_id], unique: true
|
||||||
|
add_index :cti_logs, [:direction]
|
||||||
|
add_index :cti_logs, [:from]
|
||||||
|
|
||||||
|
Role.create_if_not_exists(
|
||||||
|
name: 'CTI',
|
||||||
|
note: 'Access to CTI feature.',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1
|
||||||
|
)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -1915,6 +1915,13 @@ Role.create_if_not_exists(
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_by_id: 1
|
created_by_id: 1
|
||||||
)
|
)
|
||||||
|
Role.create_if_not_exists(
|
||||||
|
id: 6,
|
||||||
|
name: 'CTI',
|
||||||
|
note: 'Access to CTI feature.',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1
|
||||||
|
)
|
||||||
|
|
||||||
Group.create_if_not_exists(
|
Group.create_if_not_exists(
|
||||||
id: 1,
|
id: 1,
|
||||||
|
|
|
@ -5,6 +5,8 @@ require 'rexml/document'
|
||||||
class SipgateControllerTest < ActionDispatch::IntegrationTest
|
class SipgateControllerTest < ActionDispatch::IntegrationTest
|
||||||
setup do
|
setup do
|
||||||
|
|
||||||
|
Cti::Log.destroy_all
|
||||||
|
|
||||||
Setting.create_or_update(
|
Setting.create_or_update(
|
||||||
title: 'sipgate.io integration',
|
title: 'sipgate.io integration',
|
||||||
name: 'sipgate_integration',
|
name: 'sipgate_integration',
|
||||||
|
@ -65,12 +67,27 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest
|
||||||
preferences: { prio: 2 },
|
preferences: { prio: 2 },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
groups = Group.where(name: 'Users')
|
||||||
|
roles = Role.where(name: 'Agent')
|
||||||
|
agent = User.create_or_update(
|
||||||
|
login: 'cti-agent@example.com',
|
||||||
|
firstname: 'E',
|
||||||
|
lastname: 'S',
|
||||||
|
email: 'cti-agent@example.com',
|
||||||
|
password: 'agentpw',
|
||||||
|
active: true,
|
||||||
|
roles: roles,
|
||||||
|
groups: groups,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'basic call' do
|
test 'basic call' do
|
||||||
|
|
||||||
# inbound - I
|
# inbound - I
|
||||||
params = 'event=newCall&direction=in&from=4912347114711&to=4930600000000&callId=4991155921769858278&user%5B%5D=user+1&user%5B%5D=user+2'
|
params = 'event=newCall&direction=in&from=4912347114711&to=4930600000000&callId=4991155921769858278-1&user%5B%5D=user+1&user%5B%5D=user+2'
|
||||||
post '/api/v1/sipgate/in', params
|
post '/api/v1/sipgate/in', params
|
||||||
assert_response(200)
|
assert_response(200)
|
||||||
on_hangup = nil
|
on_hangup = nil
|
||||||
|
@ -85,7 +102,7 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest
|
||||||
assert_equal('http://zammad.example.com/api/v1/sipgate/in', on_answer)
|
assert_equal('http://zammad.example.com/api/v1/sipgate/in', on_answer)
|
||||||
|
|
||||||
# inbound - II - block caller
|
# inbound - II - block caller
|
||||||
params = 'event=newCall&direction=in&from=491715000000&to=4930600000000&callId=4991155921769858278&user%5B%5D=user+1&user%5B%5D=user+2'
|
params = 'event=newCall&direction=in&from=491715000000&to=4930600000000&callId=4991155921769858278-2&user%5B%5D=user+1&user%5B%5D=user+2'
|
||||||
post '/api/v1/sipgate/in', params
|
post '/api/v1/sipgate/in', params
|
||||||
assert_response(200)
|
assert_response(200)
|
||||||
on_hangup = nil
|
on_hangup = nil
|
||||||
|
@ -105,7 +122,7 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest
|
||||||
assert_equal('busy', reason)
|
assert_equal('busy', reason)
|
||||||
|
|
||||||
# outbound - I - set default_caller_id
|
# outbound - I - set default_caller_id
|
||||||
params = 'event=newCall&direction=out&from=4930600000000&to=4912347114711&callId=8621106404543334274&user%5B%5D=user+1'
|
params = 'event=newCall&direction=out&from=4930600000000&to=4912347114711&callId=8621106404543334274-3&user%5B%5D=user+1'
|
||||||
post '/api/v1/sipgate/out', params
|
post '/api/v1/sipgate/out', params
|
||||||
assert_response(200)
|
assert_response(200)
|
||||||
on_hangup = nil
|
on_hangup = nil
|
||||||
|
@ -126,11 +143,11 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest
|
||||||
end
|
end
|
||||||
assert_equal('4930777000000', caller_id)
|
assert_equal('4930777000000', caller_id)
|
||||||
assert_equal('4912347114711', number_to_dail)
|
assert_equal('4912347114711', number_to_dail)
|
||||||
assert_equal('http://zammad.example.com/api/v1/sipgate/in', on_hangup)
|
assert_equal('http://zammad.example.com/api/v1/sipgate/out', on_hangup)
|
||||||
assert_equal('http://zammad.example.com/api/v1/sipgate/in', on_answer)
|
assert_equal('http://zammad.example.com/api/v1/sipgate/out', on_answer)
|
||||||
|
|
||||||
# outbound - II - set caller_id based on routing_table by explicite number
|
# outbound - II - set caller_id based on routing_table by explicite number
|
||||||
params = 'event=newCall&direction=out&from=4930600000000&to=491714000000&callId=8621106404543334274&user%5B%5D=user+1'
|
params = 'event=newCall&direction=out&from=4930600000000&to=491714000000&callId=8621106404543334274-4&user%5B%5D=user+1'
|
||||||
post '/api/v1/sipgate/out', params
|
post '/api/v1/sipgate/out', params
|
||||||
assert_response(200)
|
assert_response(200)
|
||||||
on_hangup = nil
|
on_hangup = nil
|
||||||
|
@ -151,11 +168,11 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest
|
||||||
end
|
end
|
||||||
assert_equal('41715880339000', caller_id)
|
assert_equal('41715880339000', caller_id)
|
||||||
assert_equal('491714000000', number_to_dail)
|
assert_equal('491714000000', number_to_dail)
|
||||||
assert_equal('http://zammad.example.com/api/v1/sipgate/in', on_hangup)
|
assert_equal('http://zammad.example.com/api/v1/sipgate/out', on_hangup)
|
||||||
assert_equal('http://zammad.example.com/api/v1/sipgate/in', on_answer)
|
assert_equal('http://zammad.example.com/api/v1/sipgate/out', on_answer)
|
||||||
|
|
||||||
# outbound - III - set caller_id based on routing_table by 41*
|
# outbound - III - set caller_id based on routing_table by 41*
|
||||||
params = 'event=newCall&direction=out&from=4930600000000&to=4147110000000&callId=8621106404543334274&user%5B%5D=user+1'
|
params = 'event=newCall&direction=out&from=4930600000000&to=4147110000000&callId=8621106404543334274-5&user%5B%5D=user+1'
|
||||||
post '/api/v1/sipgate/out', params
|
post '/api/v1/sipgate/out', params
|
||||||
assert_response(200)
|
assert_response(200)
|
||||||
on_hangup = nil
|
on_hangup = nil
|
||||||
|
@ -176,14 +193,14 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest
|
||||||
end
|
end
|
||||||
assert_equal('41715880339000', caller_id)
|
assert_equal('41715880339000', caller_id)
|
||||||
assert_equal('4147110000000', number_to_dail)
|
assert_equal('4147110000000', number_to_dail)
|
||||||
assert_equal('http://zammad.example.com/api/v1/sipgate/in', on_hangup)
|
assert_equal('http://zammad.example.com/api/v1/sipgate/out', on_hangup)
|
||||||
assert_equal('http://zammad.example.com/api/v1/sipgate/in', on_answer)
|
assert_equal('http://zammad.example.com/api/v1/sipgate/out', on_answer)
|
||||||
|
|
||||||
# no config
|
# no config
|
||||||
Setting.set('sipgate_config', {})
|
Setting.set('sipgate_config', {})
|
||||||
params = 'event=newCall&direction=in&from=4912347114711&to=4930600000000&callId=4991155921769858278&user%5B%5D=user+1&user%5B%5D=user+2'
|
params = 'event=newCall&direction=in&from=4912347114711&to=4930600000000&callId=4991155921769858278-6&user%5B%5D=user+1&user%5B%5D=user+2'
|
||||||
post '/api/v1/sipgate/in', params
|
post '/api/v1/sipgate/in', params
|
||||||
assert_response(500)
|
assert_response(422)
|
||||||
error = nil
|
error = nil
|
||||||
content = @response.body
|
content = @response.body
|
||||||
response = REXML::Document.new(content)
|
response = REXML::Document.new(content)
|
||||||
|
@ -194,4 +211,123 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test 'log call' do
|
||||||
|
|
||||||
|
# outbound - I - new call
|
||||||
|
params = 'event=newCall&direction=out&from=4930600000000&to=4912347114711&callId=1234567890-1&user%5B%5D=user+1'
|
||||||
|
post '/api/v1/sipgate/out', params
|
||||||
|
assert_response(200)
|
||||||
|
log = Cti::Log.find_by(call_id: '1234567890-1')
|
||||||
|
assert(log)
|
||||||
|
assert_equal('4930777000000', log.from)
|
||||||
|
assert_equal('4912347114711', log.to)
|
||||||
|
assert_equal('out', log.direction)
|
||||||
|
assert_equal('user 1', log.from_comment)
|
||||||
|
assert_equal(nil, log.comment)
|
||||||
|
assert_equal('newCall', log.state)
|
||||||
|
|
||||||
|
# outbound - I - hangup by agent
|
||||||
|
params = 'event=hangup&direction=out&callId=1234567890-1&cause=cancel'
|
||||||
|
post '/api/v1/sipgate/out', params
|
||||||
|
assert_response(200)
|
||||||
|
log = Cti::Log.find_by(call_id: '1234567890-1')
|
||||||
|
assert(log)
|
||||||
|
assert_equal('4930777000000', log.from)
|
||||||
|
assert_equal('4912347114711', log.to)
|
||||||
|
assert_equal('out', log.direction)
|
||||||
|
assert_equal('user 1', log.from_comment)
|
||||||
|
assert_equal('cancel', log.comment)
|
||||||
|
assert_equal('hangup', log.state)
|
||||||
|
|
||||||
|
# outbound - II - new call
|
||||||
|
params = 'event=newCall&direction=out&from=4930600000000&to=4912347114711&callId=1234567890-2&user%5B%5D=user+1'
|
||||||
|
post '/api/v1/sipgate/out', params
|
||||||
|
assert_response(200)
|
||||||
|
log = Cti::Log.find_by(call_id: '1234567890-2')
|
||||||
|
assert(log)
|
||||||
|
assert_equal('4930777000000', log.from)
|
||||||
|
assert_equal('4912347114711', log.to)
|
||||||
|
assert_equal('out', log.direction)
|
||||||
|
assert_equal('user 1', log.from_comment)
|
||||||
|
assert_equal(nil, log.comment)
|
||||||
|
assert_equal('newCall', log.state)
|
||||||
|
|
||||||
|
# outbound - II - answer by customer
|
||||||
|
params = 'event=answer&direction=out&callId=1234567890-2&from=4930600000000&to=4912347114711'
|
||||||
|
post '/api/v1/sipgate/out', params
|
||||||
|
assert_response(200)
|
||||||
|
log = Cti::Log.find_by(call_id: '1234567890-2')
|
||||||
|
assert(log)
|
||||||
|
assert_equal('4930777000000', log.from)
|
||||||
|
assert_equal('4912347114711', log.to)
|
||||||
|
assert_equal('out', log.direction)
|
||||||
|
assert_equal('user 1', log.from_comment)
|
||||||
|
assert_equal(nil, log.comment)
|
||||||
|
assert_equal('answer', log.state)
|
||||||
|
|
||||||
|
# outbound - II - hangup by customer
|
||||||
|
params = 'event=hangup&direction=out&callId=1234567890-2&cause=normalClearing&from=4930600000000&to=4912347114711'
|
||||||
|
post '/api/v1/sipgate/out', params
|
||||||
|
assert_response(200)
|
||||||
|
log = Cti::Log.find_by(call_id: '1234567890-2')
|
||||||
|
assert(log)
|
||||||
|
assert_equal('4930777000000', log.from)
|
||||||
|
assert_equal('4912347114711', log.to)
|
||||||
|
assert_equal('out', log.direction)
|
||||||
|
assert_equal('user 1', log.from_comment)
|
||||||
|
assert_equal('normalClearing', log.comment)
|
||||||
|
assert_equal('hangup', log.state)
|
||||||
|
|
||||||
|
# inbound - I - new call
|
||||||
|
params = 'event=newCall&direction=in&to=4930600000000&from=4912347114711&callId=1234567890-3&user%5B%5D=user+1'
|
||||||
|
post '/api/v1/sipgate/in', params
|
||||||
|
assert_response(200)
|
||||||
|
log = Cti::Log.find_by(call_id: '1234567890-3')
|
||||||
|
assert(log)
|
||||||
|
assert_equal('4930600000000', log.to)
|
||||||
|
assert_equal('4912347114711', log.from)
|
||||||
|
assert_equal('in', log.direction)
|
||||||
|
assert_equal('user 1', log.to_comment)
|
||||||
|
assert_equal(nil, log.comment)
|
||||||
|
assert_equal('newCall', log.state)
|
||||||
|
|
||||||
|
# inbound - I - answer by customer
|
||||||
|
params = 'event=answer&direction=in&callId=1234567890-3&to=4930600000000&from=4912347114711'
|
||||||
|
post '/api/v1/sipgate/in', params
|
||||||
|
assert_response(200)
|
||||||
|
log = Cti::Log.find_by(call_id: '1234567890-3')
|
||||||
|
assert(log)
|
||||||
|
assert_equal('4930600000000', log.to)
|
||||||
|
assert_equal('4912347114711', log.from)
|
||||||
|
assert_equal('in', log.direction)
|
||||||
|
assert_equal('user 1', log.to_comment)
|
||||||
|
assert_equal(nil, log.comment)
|
||||||
|
assert_equal('answer', log.state)
|
||||||
|
|
||||||
|
# inbound - I - hangup by customer
|
||||||
|
params = 'event=hangup&direction=in&callId=1234567890-3&cause=normalClearing&to=4930600000000&from=4912347114711'
|
||||||
|
post '/api/v1/sipgate/in', params
|
||||||
|
assert_response(200)
|
||||||
|
log = Cti::Log.find_by(call_id: '1234567890-3')
|
||||||
|
assert(log)
|
||||||
|
assert_equal('4930600000000', log.to)
|
||||||
|
assert_equal('4912347114711', log.from)
|
||||||
|
assert_equal('in', log.direction)
|
||||||
|
assert_equal('user 1', log.to_comment)
|
||||||
|
assert_equal('normalClearing', log.comment)
|
||||||
|
assert_equal('hangup', log.state)
|
||||||
|
|
||||||
|
get '/api/v1/cti/log'
|
||||||
|
assert_response(401)
|
||||||
|
|
||||||
|
headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' }
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('cti-agent@example.com', 'agentpw')
|
||||||
|
get '/api/v1/cti/log', {}, headers.merge('Authorization' => credentials)
|
||||||
|
assert_response(200)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal(result.class, Array)
|
||||||
|
assert_equal(3, result.count)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue