Hace no mucho comentábamos el uso de un calendario en webdav para que Asterisk comprobara los días festivos al recibir una llamada y supiera si debía permitir la llamada o saltar directamente al buzón de voz.
En esta entrada vamos a hacer algo parecido pero esta vez usando Google Calendar, el cual nos permite acceder a los eventos mediante una URL que apunta a nuestro calendario en formato Icalendar. Haremos que nuestro Asterisk consulte nuestro Google Calendar para tratar las llamadas entrantes y sepa si debe pasar la llamada, desviarla o saltar al buzón de voz del usuario.
Lo primero que haremos será crear una cuenta en google si no tenemos una. Con esta cuenta podemos crear tantos calendarios como queramos. En este caso crearemos un calendario para marcar los festivos de la empresa. Vamos a obviar los pasos a seguir para crear un calendario y supongamos que ya tenemos un calendario creado para tal efecto.
A la izquierda de la panatalla veremos nuestros calendario entre todos los que tenemos asociados a nuestra cuenta y debajo de ellos un enlace administrar calendarios.

Pinchamos en administrar calendario y en la pantalla que nos sale elegimos el calendario que hayamos creado para marcar los festivos. Ahora tenemos una pantalla en la que podemos editar las propiedades del calendario, compartirlo con otros usuarios…etc. En este caso lo que nos interesa es la sección llamada Dirección Privada.

Vemos tres iconos XML ICAL HTML que nos dan acceso a nuestro calendario en diferentes formatos. En este caso lo que nos interesa es el formato ICAL. Guardamos la dirección del enlace al que apunta el icono porque es lo que vamos a usar para leer el calendario.
Una vez creado el calendario solo nos queda marcarlo con diferentes festivos. Podemos simplemente poner Festivo o podemos discriminar más y diferenciar todo lo que queramos. En este howto vamos a diferenciar festivos locales, festivos nacionales y festivos de empresa. Lo que vamos a hacer es crear un evento el día en cuestión, a cualquier hora y de cualquier duración, en el que pongamos estas etiquetas:

Una vez tenemos el calendario llega el momento de usarlo. Vamos a crear un AGI en ruby que consulte nuestro calendario y devuelva a asterisk una variable SALTO que usaremos en el dialplan.
calendario.rb
-
#!/usr/bin/ruby
-
require ‘rubygems’
-
require ‘icalendar’
-
require ‘open-uri’
-
include Icalendar
-
URL="http://www.google.com/calendar/ical/xxxxxx%40irontec.com/private-XXXXXXXXXXXXXXXXXX/basic.ics"
-
calendarios = Icalendar.parse(open(URL))
-
calendario = calendarios[0]
-
festivo=nil
-
calendario.events.each do |evento|
-
if evento.dtstart.yday == Date.today.yday
-
festivo=evento.summary
-
break
-
end
-
end
-
#Festivos
-
if festivo == nil
-
salto = "laboral"
-
elsif festivo == "Festivo Irontec"
-
salto = "festivo-irontec"
-
elsif festivo == "Festivo Nacional"
-
salto = "festivo-nacional"
-
elsif festivo == "Festivo Local"
-
salto = "festivo-local"
-
else
-
salto = "laboral"
-
end
-
print("SET VARIABLE SALTO #{salto}")
-
exit
Una vez hecho esto ya solo tenemos que hacer el tratamiento en el dialplan. Doy por supuesto que ya sabemos hacer esto así que voy a poner una líneas meramente descriptivas:
-
[entrantes]
-
exten => 944048182,1,AGI(calendario.rb)
-
exten =>944048182,n,Goto(${SALTO},s,1)
-
[laboral]
-
exten => s,1,NoOp(Aqui tratamiento de día laboral)
-
[festivo-nacional]
-
exten => s,1,NoOp(Festivo nacional)
-
…
Una vez hecho esto ya solo nos queda probarlo para ver que todo esta correcto. Ya tenemos una centralita aún más inteligente que demuestra una vez más que Asterisk está a años luz de las centralitas tradicionales. ¡Bienvenidos a la telefonía del siglo XXI!
Nota -> Siento lo de la indentación y coloreado del código pero wordpress es un mal bicho. Voy a ver si le hago la pelota a uno de mis compañeros del departamento web para que me hackeen un poco el CSS

¡Qué buena! Muy útil y práctica, sip.
Puestos a ser exageradamente puntillosos se me ocurre que en vez de consultar un único calendario podría consultar también los de cada miembro de la empresa (en caso de que alguien marque su extensión directamente en el IVR).
Por ejemplo:
- Un señor llama a la centralita.
- Se consulta el calendario general de la empresa. Es laboral normal, se continúa.
- El señor marca (o dice) la extensión o nombre de la persona con la que quiere contactar.
- Se busca en el calendario personal de esa persona y hoy casualmente tiene una entrada con las etiquetas: “estado:disponible”, “desvio:673123123″.
- Así que Asterisk en vez de llamar a su extensión SIP le llama al móvil.
XDDD
Pero en fin, que es lo que tú dices, ¡¡se puede hacer de tó!!
Iñaki: Eso ya lo tengo pensado y hasta hecho. Hasta un calendario donde se marcan las vacaciones de cada uno y así la centralita te dice que el trabajador esta actualmente de vacaciones y te pasa con otra persona del mismo departamento
Pero como puedes suponer no puedo poner todos los escenarios posibles. A partir de ese script y con un poco de dialplan la imaginación es el límite.
Muy buenas, ante todo felicitar al personal por el trabajo que está bastante bien. Encontrar buenas guías en castellano es francamente difícil.
El comentario de Iñaki Baz me parece muy interesante, yo busco algo parecido, os comento.
La idea sería consultar el calendario en el ldap de la empresa y desviar la llamada al buzón de voz de Asterisk si el destinatario de la llamada no está disponible ya sea por vacaciones, baja o cualquier otra cosa.
Entiendo que es muy parecido a lo aquí comentáis pero estoy muy verde, no se como se gestiona el buzón de voz, donde se almacenan las grabaciones, en que formato se realizan, etc.
No se si es mucho pedir pero un howto sobre el tema sería muy interesante. Si estáis muy ocupados os agradecería algún enlace donde se detallen este tipo de cosas preferiblemente en castellano pero si es en inglés no pasa nada.
Muchas gracias por todo, saludos
Hola !
Estoy intentando implementar pero lo consigo. devuelve “Failed to execute”. Te suena que puede ser?
un saludo.
Ignacio
— Executing [59@via-directa:2] Wait(“IAX2/albir-1″, “2″) in new stack
— Executing [59@via-directa:3] AGI(“IAX2/albir-1″, “calendario.rb”) in new stack
— Launched AGI Script /var/lib/asterisk/agi-bin/calendario.rb
== calendario.rb: Failed to execute ‘/var/lib/asterisk/agi-bin/calendario.rb’: Exec format error
— AGI Script calendario.rb completed, returning 0
— Executing [59@via-directa:4] Goto(“IAX2/albir-1″, “$(SALTO)|s|1″) in new stack
— Goto ($(SALTO),s,1)
[Nov 18 12:30:49] WARNING[26773]: pbx.c:2450 __ast_pbx_run: Channel ‘IAX2/albir-1′ sent into invalid extension ‘s’ in context ‘$(SALTO)’, but no invalid handler
— Hungup ‘IAX2/albir-1′
¿Has probado a ejecutar el script desde una línea de comandos?
¿Has dado permisos de ejecución al script?
¿Has habilitado el AGI debug en asterisk?
¿Tienes instalado un intérprete de ruby?
Aquí estamos para difundir cosas pero este no es el foro adecuado para resolver dudas. Mira un poco el error y si no pregunta en la lista de asterisk-es que estaremos encantados de ayudarte.
Un saludo
Jon Bonilla
Irontec.
Hola. Se que este no es medio para hacer una consulta técnica, pero me veo obligado ya que no he podido realizarla en ningun sitio en castellano.
Ya tengo el script creado y se ejecuta bien en línea de comandos, pero cuando lo ejecuto através del dialplan me sale este mensaje en el CLI: calendario.rb: Failed to execute ‘/var/lib/asterisk/agi-bin/calendario.rb’: Permission denied
Yo he dado todos los permisos al script, no se que podrá ser, espero que me puedan ayudar.
Saludos
Hola a Todos!!!
Se que este post ya esta un poco antigüo pero espero puedan apoyarme. Hice el procedimiento y todo funciona bien, tanto en consola como en asterisk. Pero no me retorna el valor de la variable SALTO al dial plan.
Tengo instalado los gems: icalendar, ruby-agi
Alguna sugerencia?
Anexo la salida por si sirbe de algo:
AGI Tx >> agi_request: cal.rb
AGI Tx >> agi_channel: SIP/101-0000003e
AGI Tx >> agi_language: en
AGI Tx >> agi_type: SIP
AGI Tx >> agi_uniqueid: 1311205929.120
AGI Tx >> agi_callerid: 101
AGI Tx >> agi_calleridname: device
AGI Tx >> agi_callingpres: 0
AGI Tx >> agi_callingani2: 0
AGI Tx >> agi_callington: 0
AGI Tx >> agi_callingtns: 0
AGI Tx >> agi_dnid: 101
AGI Tx >> agi_rdnis: unknown
AGI Tx >> agi_context: entrantes
AGI Tx >> agi_extension: 101
AGI Tx >> agi_priority: 1
AGI Tx >> agi_enhanced: 0.0
AGI Tx >> agi_accountcode:
AGI Tx >>
— AGI Script cal.rb completed, returning 0
— Executing [101@entrantes:2] NoOp(“SIP/101-0000003e”, “”) in new stack
== Auto fallthrough, channel ‘SIP/101-0000003e’ status is ‘UNKNOWN’
Gracias de antemano!!