2016-04-23 09:04:33 +00:00
|
|
|
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
|
|
|
|
2016-04-21 07:36:25 +00:00
|
|
|
require 'builder'
|
|
|
|
|
|
|
|
class Integration::SipgateController < ApplicationController
|
2016-04-23 09:04:33 +00:00
|
|
|
|
|
|
|
# list current caller log
|
|
|
|
def index
|
|
|
|
return if !authentication_check
|
|
|
|
return if deny_if_not_role('CTI')
|
2016-04-28 13:15:50 +00:00
|
|
|
list = Cti::Log.order('created_at DESC, id DESC').limit(60)
|
2016-04-23 09:04:33 +00:00
|
|
|
render json: list
|
|
|
|
end
|
2016-04-21 07:36:25 +00:00
|
|
|
|
2016-04-27 11:37:13 +00:00
|
|
|
# set caller log to done
|
|
|
|
def done
|
|
|
|
return if !authentication_check
|
|
|
|
return if deny_if_not_role('CTI')
|
|
|
|
log = Cti::Log.find(params['id'])
|
|
|
|
log.done = params['done']
|
|
|
|
log.save
|
|
|
|
render json: {}
|
|
|
|
end
|
|
|
|
|
2016-04-21 07:36:25 +00:00
|
|
|
# notify about inbound call / block inbound call
|
|
|
|
def in
|
2016-04-23 09:04:33 +00:00
|
|
|
http_log_config facility: 'sipgate.io'
|
2016-04-21 13:43:13 +00:00
|
|
|
return if !configured?
|
2016-04-21 07:36:25 +00:00
|
|
|
|
|
|
|
if params['event'] == 'newCall'
|
|
|
|
|
2016-04-23 09:04:33 +00:00
|
|
|
config = Setting.get('sipgate_config')
|
|
|
|
config_inbound = config[:inbound] || {}
|
|
|
|
block_caller_ids = config_inbound[:block_caller_ids] || []
|
|
|
|
|
2016-04-21 07:36:25 +00:00
|
|
|
# check if call need to be blocked
|
|
|
|
block_caller_ids.each {|item|
|
|
|
|
next unless item[:caller_id] == params['from']
|
|
|
|
xml = Builder::XmlMarkup.new(indent: 2)
|
|
|
|
xml.instruct!
|
2016-04-23 09:04:33 +00:00
|
|
|
content = xml.Response(onHangup: url, onAnswer: url) do
|
2016-04-21 07:36:25 +00:00
|
|
|
xml.Reject('reason' => 'busy')
|
|
|
|
end
|
|
|
|
|
|
|
|
send_data content, type: 'application/xml; charset=UTF-8;'
|
|
|
|
|
2016-04-23 09:04:33 +00:00
|
|
|
#params['Reject'] = 'busy'
|
|
|
|
params['comment'] = 'reject, busy'
|
|
|
|
if params['user']
|
|
|
|
params['comment'] = "#{params['user']} -> reject, busy"
|
|
|
|
end
|
|
|
|
update_log(params)
|
2016-04-21 07:36:25 +00:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2016-04-23 09:04:33 +00:00
|
|
|
update_log(params)
|
|
|
|
|
2016-04-21 07:36:25 +00:00
|
|
|
xml = Builder::XmlMarkup.new(indent: 2)
|
|
|
|
xml.instruct!
|
2016-04-23 09:04:33 +00:00
|
|
|
content = xml.Response(onHangup: url, onAnswer: url)
|
2016-04-21 07:36:25 +00:00
|
|
|
send_data content, type: 'application/xml; charset=UTF-8;'
|
|
|
|
end
|
|
|
|
|
|
|
|
# set caller id of outbound call
|
|
|
|
def out
|
2016-04-23 09:04:33 +00:00
|
|
|
http_log_config facility: 'sipgate.io'
|
2016-04-21 13:43:13 +00:00
|
|
|
return if !configured?
|
2016-04-21 07:36:25 +00:00
|
|
|
|
|
|
|
config = Setting.get('sipgate_config')
|
|
|
|
config_outbound = config[:outbound][:routing_table]
|
|
|
|
default_caller_id = config[:outbound][:default_caller_id]
|
|
|
|
|
|
|
|
xml = Builder::XmlMarkup.new(indent: 2)
|
|
|
|
xml.instruct!
|
|
|
|
|
|
|
|
# set callerId
|
|
|
|
content = nil
|
|
|
|
to = params[:to]
|
2016-04-23 09:04:33 +00:00
|
|
|
from = nil
|
2016-04-21 07:36:25 +00:00
|
|
|
if to
|
|
|
|
config_outbound.each {|row|
|
|
|
|
dest = row[:dest].gsub(/\*/, '.+?')
|
|
|
|
next if to !~ /^#{dest}$/
|
2016-04-23 09:04:33 +00:00
|
|
|
from = row[:caller_id]
|
|
|
|
content = xml.Response(onHangup: url, onAnswer: url) do
|
|
|
|
xml.Dial(callerId: from) { xml.Number(params[:to]) }
|
2016-04-21 07:36:25 +00:00
|
|
|
end
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if !content && default_caller_id
|
2016-04-23 09:04:33 +00:00
|
|
|
from = default_caller_id
|
|
|
|
content = xml.Response(onHangup: url, onAnswer: url) do
|
2016-04-21 07:36:25 +00:00
|
|
|
xml.Dial(callerId: default_caller_id) { xml.Number(params[:to]) }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
2016-04-23 09:04:33 +00:00
|
|
|
content = xml.Response(onHangup: url, onAnswer: url)
|
2016-04-21 07:36:25 +00:00
|
|
|
end
|
|
|
|
|
2016-04-21 15:11:10 +00:00
|
|
|
send_data content, type: 'application/xml; charset=UTF-8;'
|
2016-04-23 09:04:33 +00:00
|
|
|
if from
|
|
|
|
params['from'] = from
|
|
|
|
end
|
|
|
|
update_log(params)
|
2016-04-21 07:36:25 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2016-04-21 13:43:13 +00:00
|
|
|
def configured?
|
2016-04-21 07:36:25 +00:00
|
|
|
if !Setting.get('sipgate_integration')
|
2016-04-21 13:43:13 +00:00
|
|
|
xml_error('Feature is disable, please contact your admin to enable it!')
|
|
|
|
return false
|
2016-04-21 07:36:25 +00:00
|
|
|
end
|
2016-04-21 13:43:13 +00:00
|
|
|
config = Setting.get('sipgate_config')
|
|
|
|
if !config || !config[:inbound] || !config[:outbound]
|
|
|
|
xml_error('Feature not configured, please contact your admin!')
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2016-04-23 09:04:33 +00:00
|
|
|
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
|
2016-04-28 13:15:50 +00:00
|
|
|
from_comment = update_log_item('from')
|
2016-04-23 09:04:33 +00:00
|
|
|
else
|
|
|
|
from_comment = user
|
2016-04-28 13:15:50 +00:00
|
|
|
to_comment = update_log_item('to')
|
2016-04-23 09:04:33 +00:00
|
|
|
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'
|
2016-04-27 11:37:13 +00:00
|
|
|
log.start = Time.zone.now
|
|
|
|
if user
|
|
|
|
log.to_comment = user
|
|
|
|
end
|
2016-04-23 09:04:33 +00:00
|
|
|
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
|
2016-04-27 11:37:13 +00:00
|
|
|
if params['direction'] == 'in' && log.state == 'newCall'
|
|
|
|
log.done = false
|
|
|
|
end
|
|
|
|
if params['direction'] == 'in' && log.to_comment == 'voicemail'
|
|
|
|
log.done = false
|
|
|
|
end
|
2016-04-23 09:04:33 +00:00
|
|
|
log.state = 'hangup'
|
2016-04-27 11:37:13 +00:00
|
|
|
log.end = Time.zone.now
|
2016-04-23 09:04:33 +00:00
|
|
|
log.comment = comment
|
|
|
|
log.save
|
|
|
|
else
|
|
|
|
raise "Unknown event #{params['event']}"
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2016-04-28 13:15:50 +00:00
|
|
|
def update_log_item(direction)
|
|
|
|
from_comment_known = ''
|
|
|
|
from_comment_maybe = ''
|
|
|
|
caller_ids = Cti::CallerId.lookup(params[direction])
|
|
|
|
caller_ids.each {|record|
|
|
|
|
comment = ''
|
|
|
|
if record.user_id
|
|
|
|
user = User.lookup(id: record.user_id)
|
|
|
|
if user
|
|
|
|
comment += user.fullname
|
|
|
|
end
|
|
|
|
elsif !record.comment.empty?
|
|
|
|
comment += record.comment
|
|
|
|
end
|
|
|
|
if record.level == 'known'
|
|
|
|
if !from_comment_known.empty?
|
|
|
|
from_comment_known += ','
|
|
|
|
end
|
|
|
|
from_comment_known += comment
|
|
|
|
else
|
|
|
|
if !from_comment_maybe.empty?
|
|
|
|
from_comment_maybe += ','
|
|
|
|
end
|
|
|
|
from_comment_maybe += comment
|
|
|
|
end
|
|
|
|
}
|
|
|
|
return from_comment_known if !from_comment_known.empty?
|
|
|
|
return "maybe #{from_comment_maybe}" if !from_comment_maybe.empty?
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
2016-04-21 13:43:13 +00:00
|
|
|
def xml_error(error)
|
|
|
|
xml = Builder::XmlMarkup.new(indent: 2)
|
|
|
|
xml.instruct!
|
|
|
|
content = xml.Response() do
|
|
|
|
xml.Error(error)
|
|
|
|
end
|
2016-04-23 09:04:33 +00:00
|
|
|
send_data content, type: 'application/xml; charset=UTF-8;', status: 422
|
2016-04-21 07:36:25 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def base_url
|
|
|
|
http_type = Setting.get('http_type')
|
|
|
|
fqdn = Setting.get('fqdn')
|
|
|
|
"#{http_type}://#{fqdn}/api/v1/sipgate"
|
|
|
|
end
|
|
|
|
|
2016-04-23 09:04:33 +00:00
|
|
|
def url
|
|
|
|
"#{base_url}/#{params['direction']}"
|
2016-04-21 07:36:25 +00:00
|
|
|
end
|
|
|
|
end
|