---
title: "Freeswitch Integración - event2dial"
date: 2023-07-01T16:15:01-05:00
draft: false
---

Una de las funcionalidades más prácticas o almenos más usadas por empresas
en la gestión de sus usuarios es un mecanimo que conecte al usuario
con un agente ante un evento, los eventos más comunes son:

* el usuario solicita que lo contacten (ejemplo al diligenciar un formulario)
* un agente solicita contactar con otro usuario sin conocer el número destino (ejemplo gestión en un CRM).
* contactar a usuario ante una campaña de mercadeo.

Para FreeSWITCH tenemos muy poca documentación de como realizar este tipo de
integraciones así que vamos a realizar una implementación de este tipo de servicio (event2dial)
desde FreeSWITCH.

Nuestro escenario sería:

* Como consumidor debo estar en la capacidad de solicitar que me contacten lo más antes posible.

Para satisfacer el escenario anterio en un ambiente web, llegamos al acuerdo que el usuario
pueda diligenciar un formulario para ser contactado.

FreeSWITCH es un softswitch extenso el cual ofrece diferentes medios para realizar
integraciónes, donde por nombrar algunos:

* por medio de **mod_event_socket**
* por medio de lenguage integrados como: **mod_lua**,  **mod_python**, **mod_perl**
* por medio de **mod_xml_curl**
* por medio de **mod_xml_rpc**
* por medio de **mod_httapi**
* o bien una mezcla de todo

para esta implementación usaremos el modulo **mod_xml_rpc** el cual nos ofrece un [**rpc**](https://en.wikipedia.org/wiki/Remote_procedure_call)
para comandar el FreeSWITCH siendo la ejecución de forma sincronica es decir al comandar esperaremos por el resultado,
para unas decenas de llamadas por minuto esto es suficiente pero para superar estos limites necesitariamos otra
estrategia diferente.

importante antes de empezar:

* conocer como instalar y operar un FreeSWITCH
* ejecutable **freeswitch 1.10.9** con los modulos **mod_xml_rpc** y **mod_sofia**


**freeswitch.xml**
```xml @mdtoapp file:freeswitch.xml
<?xml version="1.0"?>
<document type="freeswitch/xml">
  <section name="configuration" description="Various Configuration">
	<configuration name="modules.conf" description="Modules">
	  <modules>
		<load module="mod_console"/>
		<load module="mod_commands"/>
		<load module="mod_dptools"/>
		<!-- habilitamos el modulo de nuestro interes -->
		<load module="mod_xml_rpc"/>
	  </modules>
	</configuration>
	
	<!-- resto de configuración -->
	
	<!-- configuracion minima para xml_rpc.conf OJO actualmente escucha en todas la interfaz -->
	<configuration name="xml_rpc.conf" description="XML RPC">
	  <settings>
		<param name="http-port" value="8080"/>
	  </settings>
	</configuration>
  </section>

  <section name="dialplan" description="Regex/XML Dialplan">
	<!-- cuando contactemos el usuario con el `originate` el FreeSWITCH
		 ejecutará el siguiente plan de marcado para controlar su flujo
		 áca podemos indicar acciones como:
		 - conectar con un usuario/extensión
		 - conectar con una linea de tierra o mobil
		 - reproducir un audio
		 - mover la llamada a una queue
		 - iniciar un IVR
	-->
	<context name="event2dial">
	  <!-- acciones a realizar una vez se logro contactar al usuario -->
	  <extension name="event2dial">
		<condition>
		  <!-- todas las llamadas son contestadas por el agente 1000 -->
		  <action application="set" data="hangup_after_bridge=true"/>
		  <action application="bridge" data="user/1000"/>
		  <action application="hangup"/>
		</condition>
	  </extension>
	</context>
  </section>
</document>
```

<!--
```sh @mdtoapp @execute
freeswitch -nonat -lp -conf . -log . -db . -run . -temp . &
sleep 3s
```
-->

primero confirmamos actividad del puerto, en caso de no obtener
respuesta revisar configuración de FreeSWITCH.

```sh @mdtoapp @execute
curl -sSG -XGET 'http://localhost:8080/xmlapi/uptime'
# 2
```

ahora, asumamos que tenemos configurada la pasarela `celulares` que nos
da salida a llamadas a celulares en colombia, entonces
para lanzar la llamada al numero 3001234567 seria:

```sh @mdtoapp @execute
curl -sSG -XGET 'http://localhost:8080/api/originate?"%7Boriginate_timeout%3D30%2Corigination_uuid%3DMYUUID%2Corigination_caller_id_name%3D123%2Corigination_caller_id_number%3D123%7Dsofia%2Fcelulares%2F3001234567%20event2dial%20XML%20event2dial%29"'

```

aclaraciónes:

* se debe codificar por partes los argumentos del comando se separan con `%20` y cada argumento se codifica con url, ejemplo de codificacion en ruby seria:
  *  `['{originate_timeout=30}sofia/gateway/celulares/3001234576', 'event2dial', 'XML', 'event2dial'].map { |v| URI.encode_www_form_component(v) }.join('%20')`
* `originate_timeout` = 30, esperamos almenos 30 segundos que contesten o colgamos (este comportamiento no aplica para destinos con buzón de voz).
* `origination_uuid` = UUIDv4, asignamos identificador a la llamada.
* `origination_caller_id_name` = 123, dependiendo de la linea destino podemos enviar un nombre a ser visualizado en el telefono.
* `origination_caller_id_number` = 123, dependiendo de la linea destino podemos enviar el numero de origen.

estados de retorno:

`+OK <uuidv4>` indicando que fue exitoso el lanzamiento de la llamada

`-ERR <cause>` indica el motivo por el cual no se puedo lanzar la llamada

Resumiendo:

* requerimos un FreeSWITCH previamente configurado con una o varias pasarelas a que nos den salida a los destinos requeridos
* activar y configurar **mod_xml_rpc**
* comandar llamada con **originate** por medio de HTTP.

Con lo anterior tenemos todas las herramientas para integrar FreeSWITCH en los flujos de negoció.

<!--
detener freeswitch

```sh @mdtoapp @execute
freeswitch -conf . -stop -run .
```
-->










