# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ require 'builder' class Integration::PlacetelController < ApplicationController skip_before_action :verify_csrf_token before_action :check_configured, :check_token # notify about inbound call / block inbound call def event local_params = ActiveSupport::HashWithIndifferentAccess.new(params.permit!.to_h) # do placetel event mapping if local_params['event'] == 'IncomingCall' local_params['direction'] = 'in' local_params['event'] = 'newCall' elsif local_params['event'] == 'HungUp' local_params['event'] = 'hangup' elsif local_params['event'] == 'CallAccepted' local_params['event'] = 'answer' end if local_params['direction'].blank? entry = Cti::Log.find_by(call_id: params[:call_id]) if entry local_params['direction'] = entry.direction end end if local_params['type'] == 'missed' local_params['cause'] = 'cancel' elsif local_params['type'] == 'voicemail' local_params['cause'] = 'voicemail' elsif local_params['type'] == 'blocked' local_params['cause'] = 'blocked' elsif local_params['type'] == 'accepted' local_params['cause'] = 'normalClearing' end if local_params['direction'] == 'in' if local_params['event'] == 'newCall' config_inbound = config_integration[:inbound] || {} block_caller_ids = config_inbound[:block_caller_ids] || [] # check if call need to be blocked block_caller_ids.each do |item| next unless item[:caller_id] == local_params['from'] xml = Builder::XmlMarkup.new(indent: 2) xml.instruct! content = xml.Response() do xml.Reject('reason' => 'busy') end send_data content, type: 'application/xml; charset=UTF-8;' #local_params['Reject'] = 'busy' local_params['comment'] = 'reject, busy' if local_params['user'] local_params['comment'] = "#{local_params['user']} -> reject, busy" end Cti::Log.process(local_params) return true end end Cti::Log.process(local_params) xml = Builder::XmlMarkup.new(indent: 2) xml.instruct! content = xml.Response() send_data content, type: 'application/xml; charset=UTF-8;' return true elsif local_params['direction'] == 'out' config_outbound = config_integration[:outbound] routing_table = nil default_caller_id = nil if config_outbound.present? routing_table = config_outbound[:routing_table] default_caller_id = config_outbound[:default_caller_id] end xml = Builder::XmlMarkup.new(indent: 2) xml.instruct! # set callerId content = nil to = local_params[:to] from = nil if to && routing_table.present? routing_table.each do |row| dest = row[:dest].gsub(/\*/, '.+?') next if to !~ /^#{dest}$/ from = row[:caller_id] content = xml.Response() do xml.Dial(callerId: from) { xml.Number(params[:to]) } end break end if !content && default_caller_id.present? from = default_caller_id content = xml.Response() do xml.Dial(callerId: default_caller_id) { xml.Number(params[:to]) } end end else content = xml.Response() end send_data(content, type: 'application/xml; charset=UTF-8;') if from.present? local_params['from'] = from end Cti::Log.process(local_params) return true end response_error('Invalid direction!') end private def check_token if Setting.get('placetel_token') != params[:token] response_unauthorized('Invalid token, please contact your admin!') return end true end def check_configured http_log_config facility: 'placetel' if !Setting.get('placetel_integration') response_error('Feature is disable, please contact your admin to enable it!') return end if config_integration.blank? || config_integration[:inbound].blank? || config_integration[:outbound].blank? response_error('Feature not configured, please contact your admin!') return end true end def xml_error(error, code) xml = Builder::XmlMarkup.new(indent: 2) xml.instruct! content = xml.Response() do xml.Error(error) end send_data content, type: 'application/xml; charset=UTF-8;', status: code end def config_integration @config_integration ||= Setting.get('placetel_config') end def response_error(error) xml_error(error, 422) end def response_unauthorized(error) xml_error(error, 401) end end