Integrar XMPP com VoIP tem sido nos últimos anos um dos meus maiores objetivos. A criação de uma solução integrada de comunicação realtime com open source passa por estas duas tecnologias, e fazê-las conversar entre si (de forma útil) sempre foi um dos meus desejos.
Desde que comecei a trabalhar com Asterisk e Openfire, há uns 9 anos atrás, tenho pensado em criar algo fazendo uso desta integração e, após a versão 11 do Asterisk, aparentemente tal objetivo começou a ficar mais próximo.
Usando AGIs em python, comecei a desenvolver uma “ferramenta” que permite que o usuário realize uma série de ações através da sua conta xmpp no seu cliente de IM preferido (ex: Pidgin). Por enquanto o software já dispõe de:
- Envio de mensagem SIP para ramal
- Envio de SMS
- Ativação/desativação de DND
- Ativação/desativação de desvio
- Login/logoff de fila
- Obtenção de informações sobre o ramal
- Obtenção de informações sobre fila
- Envio de mensagem XMPP para todos os usuários logados em uma determinada fila
- Exibição de informações dos peers SIP e IAX
- Outros recursos ainda em desevolvimento.
Para que tudo isso funcione é preciso também realizar configurações e/ou alterações no DB do Asterisk, no AMI (fonte principal das ações) e no plano de discagem. Isso é necessário para que seja possível garantir o armazenamento de outros dados (JID) e para a realização de operações pertinentes aos recursos da ferramenta (controle do DND e desvio, por exemplo).
Minha intenção é que assim que a ferramenta esteja mais madura, a mesma seja implementada no servidor XMPP do Mundo Open Source para que os leitores possam experimentá-la e testá-la, para posterior lançamento do código fonte.
Mas, enquanto a mesma ainda está na fala pré alpha ( 🙂 ), gostaria de já compartilhar, de forma prática, essa possibilidade de integração para que vocês também possam construir suas soluções, e, quem sabe, possamos trocar ideias e desenvolver novos recursos e ferramentas juntos.
Pré requisitos
Para que você possa implementar o aqui proposto é preciso ter os seguintes recursos disponíveis:
- Servidor Asterisk 11 ou superior funcional e com suporte a XMPP (res_xmpp)
- Servidor XMPP (sugiro Openfire 3.9.3, mas outros podem ser usados) funcional
- Uma conta para o Asterisk no seu servidor XMPP
Por onde começar?
Para começar e preciso fazer o Asterisk se comunicar com seu servidor XMPP. Para isso edite o arquivo /etc/asterisk/xmpp.conf e crie uma sessão para o mesmo. Ex:
[asterisk] type=client serverhost=xmpp.meudominio.com.br username=asterisk@xmpp.meudominio.com.br secret=senha priority=1 usetls=yes port=5222 usesasl=yes buddy=marcelo@xmpp.meudominio.com.br status=available statusmessage="Servidor Asterisk" sendtodialplan=yes context=from_xmpp keepalive=yes
Edite também o arquivo /etc/asterisk/extensions.conf e crie o contexto from_xmpp com o seguinte conteúdo:
[from_xmpp] exten => s,1,NoOp(Mensagem XMPP) same => n,NoOp(Para: ${MESSAGE(to)}) same => n,NoOp(de: ${MESSAGE(from)}) same => n,NoOp(Mensagem: ${MESSAGE(body)}) same => n,NoOp(Enviando mensagem SIP) ; AGI que processa a mensagem enviada e obtém as variáveis ; ${XMPP_MSG} - texto da mensagem ; ${XMPP_SIPDEST} - ramal do destinatário ; ${XMPP_SIPORIG} - ramal do remetente same => n,agi(process_xmpp_msg.agi) ; Seta ${XMPPRESOURCE} = nome da seção no arquivo xmpp.conf (pode ser uma global) same => n,Set(XMPPRESOURCE=asterisk) same => n,Set(MESSAGE(body)=${XMPP_MSG}) same => n,MessageSend(sip:${XMPP_SIPDEST},sip:${XMPP_SIPORIG}) same => n,JabberSend(${XMPPRESOURCE},${MESSAGE(from):5},"Mensagem enviada. Status:${MESSAGE_SEND_STATUS}). )
E como usar?
Para se “comunicar” com seu Asterisk, basta mandar mensagens para o JID configurado no arquivo xmpp.conf (no caso, asterisk@xmpp.meudominio.com.br). Toda a mensagem será recebida no contexto configurado (no caso, from_xmpp) e armazenada na variável ${MESSAGE}, como pode-se observar no código acima. O contexto de
exemplo foi criado com vários comandos NoOP para que você possa entender bem o que contém cada variável.
UPDATE 29/08/14: a pedidos segue uma versão do script process_xmpp_msg.agi adaptado de meu script original. Espero que esteja funcionando 100%. 🙂
Atenção: como o intuito deste post é tratar especificamente da integração entre XMPP e VoIP, não foi listado o conteúdo do script process_xmpp_msg.agi, já que ele é basicamente usado para tratar texto e pesquisar dados no DB.
Exemplos de saída e logs
Envio via Pidgin:
(02:53:00 PM) marcelo@xmpp.meudominio.com.br/meuresource: msg 5010 Isso é um teste
(02:53:01 PM) asterisk@xmpp.meudominio.com.br: Mensagem enviada. Status: SUCCESS.
Logs do console do Asterisk:
— Executing [s@from_xmpp:1] NoOp(“Message/ast_msg_queue”, “Mensagem XMPP”) in new stack
— Executing [s@from_xmpp:2] NoOp(“Message/ast_msg_queue”, “Para: xmpp:asterisk@xmpp.meudominio.com.br”) in new stack
— Executing [s@from_xmpp:3] NoOp(“Message/ast_msg_queue”, “de: xmpp:marcelo@xmpp.meudominio.com.br/meuresource”) in new stack
— Executing [s@from_xmpp:4] NoOp(“Message/ast_msg_queue”, “Mensagem: msg 5010 Isso é um teste”) in new stack
— Executing [s@from_xmpp:10] NoOp(“Message/ast_msg_queue”, “Enviando mensagem SIP”) in new stack
— Executing [s@from_xmpp:11] Set(“Message/ast_msg_queue”, “MESSAGE(body)=Isso é um teste”) in new stack
— Executing [s@from_xmpp:12] MessageSend(“Message/ast_msg_queue”, “sip:5010,sip:5099”) in new stack
— Executing [s@from_xmpp:15] JabberSend(“Message/ast_msg_queue”, “asterisk,marcelo@xmpp.meudominio.com.br/meuresource,Mensagem enviada. Status: SUCCESS.”) in new stack
Espero que vocês também consigam perceber o universo de possibilidades criado por esta integração. Fiquem à vontade para deixar seus comentários e/ou fazer contato para que possamos discutir o recurso mais a fundo.
Até mais!
Leia também: