Skype integration now exists with Asterisk through a
commercial module from Digium called Skype for Asterisk (SFA).[163] The SFA module loads directly into Asterisk and allows
communication with all users on the Skype network directly by using an
account created on the Skype Manager. Previous methods were messy,
requiring the use of a Windows-based computer running another instance of
Skype controlled via an API (application programming interface) and
directing media to a sound card and into Asterisk via chan_oss
or chan_alsa
. Now, two methods exist: SFA and Skype
Connect (formerly known as Skype for SIP).
As an Asterisk module, Skype for Asterisk does have some features that Skype Connect does not, including text chat, presence updates, and the ability to call a Skype user directly rather an via SkypeIn number. Additionally, Skype for Asterisk utilizes Skype’s encryption for calls, which provides security benefits without the need to use SRTP (secure RTP) with SIP.
Since Skype for Asterisk is a commercial product, documentation for installing and configuring the module is available from Digium directly. For the most up-to-date installation documentation and information about the Skype for Asterisk module, see http://www.digium.com/en/products/software/skypeforasterisk.php.
You can download the modules from http://downloads.digium.com/pub/telephony/skypeforasterisk, and the registration utility for registering commercial modules from Digium is available at http://downloads.digium.com/pub/register.
In this section we’ll explore the various ways we can utilize Skype from our dialplan, such as sending calls to and receiving calls from users on the Skype network and exchanging messages with our Skype buddies. We’ll also show you how to implement a clever dialplan that will make it easier to call your friends on the Skype network without having to assign everyone an extension number.
While the README
file that comes with the Skype module helps to document the chan_skype.conf
configuration, and
the sample chan_skype.conf
file
is well-documented, it is worth
showing a simple version of the configuration for the purposes of
documenting the usage of Skype from the dialplan.
Users configured in chan_skype.conf
must be created with
the Skype Manager interface. Personal Skype IDs are not
allowed.
Our example Skype user will be
pbx.shifteight.org. We’ll configure this user in
chan_skype.conf
. There are
additional options that could be set here, but for our purposes we’re
keeping it simple:
[general] default_user=pbx.shifteight.org [pbx.shifteight.org] secret=my_secret_pass context=skype_incoming exten=start buddy_autoadd=true
The default_user
option in the [general]
section is used to control which
account we should use when placing calls via Skype. If we had multiple
accounts, the default_user
would be
used when placing calls unless we specified a different user to place
the call as (we’ll discuss this further in the next section).
We’ve also defined the password
(secret
), the context
incoming calls will enter into, and
the extension (exten
) that will be
executed within the context. If we had multiple Skype users and wanted
to control all of them from the same context, we could give them each different extension
values, such as exten=leifmadsen
or
exten=
russellbryant
.
Additionally, we’ve enabled the ability to automatically add people who contact us to our buddies list.
Placing a call to a Skype buddy is relatively
straightforward. Like with other channel types in Asterisk, the
Skype
channel type is used to place
calls to endpoints on the Skype network.
Utilizing the Dial()
application from the dialplan, we can
place calls to other Skype users:
[LocalSets] exten => 100,1,Answer() same => n,Dial(Skype/vuc.me,30) same => n,Playback(silence/1&user&is-curntly-unavail) same => n,Hangup()
Our dialplan simply answers the
call and attempts to place a call to
vuc.me,[164] wait 30 seconds for that user to answer, and, if there
is no answer, play back a message saying that the user is currently
unavailable before hanging up. We could, of course, be more elaborate
with our dialplan; for example, we could turn this into a Macro()
or GoSub()
routine so we just needed to pass in
the name of the person we wish to call.
Unfortunately, if you’re utilizing a device that only has a number pad for dialing, you’ll need to assign extension numbers to all your favorite Skype buddies. However, we’ve come up with a clever way of reading back your online buddies to you, which we’ll describe in the section called “Calling your Skype buddies without assigning extension numbers”.
If you have a softphone,
though, you should have the ability to place calls by dialing names
directly. We can use this to our advantage by creating a pattern match
in our dialplan with the prefix of SKYPE
:
[LocalSets] exten => _SKYPE-.,1,Verbose(2,Dialing via Skype) same => n,Set(NameToDial=${FILTER(a-zA-Z0-9.,${EXTEN:6})}) same => n,Playback(silence/1&pls-wait-connect-call) same => n,Dial(Skype/${NameToDial},30) same => n,Playback(user&is-curntly-unavail) same => n,Hangup()
By dialing SKYPE-vuc.me
, we can dial the VoIP Users
Conference via Skype from our softphone. The FILTER()
function is used here to control
what we’re allowed to pass to the Dial()
application. If we didn’t do any
filtering, someone could potentially send a string like SKYPE-nobody&SIP/my_itsp/
,
replacing the number 4165551212
4165551212
with a
number that is very expensive to call. By using FILTER()
, we restrict the allowable
characters to alphanumeric characters and periods.
After that, we’re simply
passing the string to the Dial()
application and waiting for an answer for 30 seconds. If no one
answers, an audio message is played back to the caller stating that
the user is unavailable and then the call is hung up.
To receive calls, you simply
need to configure your user in the chan_skype.conf
file as described in the section called “Configuring chan_skype.conf”. Once you’ve done that, you can
configure your dialplan to answer calls like so:
[skype_incoming] exten => start,1,Verbose(2,Incoming Skype Call) same => n,Answer() same => n,Dial(SIP/0000FFFF0001,30) same => n,Playback(user&is-curntly-unavail) same => n,Hangup()
Obviously, you can change this
section of the dialplan to be more elaborate; all we’ve done is
configured the dialplan to call our SIP device at 0000FFFF0001
, wait for an answer for 30
seconds, and then (if there is no answer or the device is busy or
unavailable) play back a prompt that says the user is currently
unavailable, followed by a hangup.
We’ve just shown you how to place and receive calls via Skype. The following sections will show you how to send and receive messages via the Skype network, and how to place calls to your Skype buddies without assigning extension numbers to them.
Sending and receiving messages via Skype is similar to doing this via XMPP (Jabber), which we described in the section called “Sending messages with JabberSend()” and the section called “Receiving messages with JABBER_RECEIVE()”, so we won’t go into quite the detail in these sections as we did there. Please review the sections about XMPP messaging before continuing, as we’ll be using the same basic dialplans to accomplish sending and receiving of messages via Skype, while making adjustments to use the appropriate dialplan applications and functions.
The primary thing to remember
is that messages are sent with the dialplan application SkypeChatSend()
and received with the dialplan function SKYPE_CHAT_RECEIVE()
. Additionally, messages can only be received when the
SKYPE_CHAT_RECEIVE()
function has
been called from the dialplan, and it blocks (does not continue in the
dialplan) while waiting for a message.
Sending a message from the dialplan to a Skype buddy is relatively straightforward. Here is a simple dialplan we can use to send a message from Asterisk to someone on the Skype network:
[LocalSets]
exten => 104,1,Answer()
; *** This line should not have any line breaks
same => n,SkypeChatSend(pbx.shifteight.org,tfot.madsen,Incoming call from
${CALLERID(all)})
same => n,Dial(SIP/0000FFFF0002,30)
same => n,Hangup()
Our dialplan is simple. We
created a test extension of 104
that answers the line, then sends a message to Skype user tfot.madsen
from the pbx.shifteight.org
account (which we
configured in the chan_skype.conf
file). The message sent is “Incoming call from ${CALLERID(all)}”,
where the caller ID is provided by the CALLERID()
function. After sending our message, we then dial the device
located at 0000FFFF0002
and hang up
if no one answers within 30 seconds.
That’s it for sending messages
via Skype. Now let’s look at some of the ways we can receive messages
from Skype. Here is the simple example we explored in the section called “Receiving messages with JABBER_RECEIVE()”), with a few changes made to
reflect the technology. This time, we’ll be replacing JabberSend()
and JABBER_RECEIVE()
with the SkypeChatSend()
and SKYPE_CHAT_RECEIVE()
dialplan application
and function, respectively:
exten => 106,1,Answer()
; All text must be on a single line.
same => n,SkypeChatSend(pbx.shifteight.org,tfot.madsen,Incoming call from
${CALLERID(all)}. Press 1 to route to desk. Press 2 to send to voicemail.)
; Wait for a response for 6 seconds.
; *** This line should not have any line breaks
same => n,Set(SkypeResponse=
${SKYPE_CHAT_RECEIVE(pbx.shifteight.org,tfot.madsen,6)}
)
same => n,GotoIf($["${SkypeResponse}" = "1"]?dial,1)
same => n,GotoIf($["${SkypeResponse}" = "2"]?voicemail,1)
same => n,Goto(dial,1)
exten => dial,1,Verbose(2,Calling our desk)
same => n,Dial(SIP/0000FFFF0002,6)
same => n,Goto(voicemail,1)
exten => voicemail,1,Verbose(2,VoiceMail)
; *** This line should not have any line breaks
same => n,Set(VoiceMailStatus=${IF($[${ISNULL(${DIALSTATUS})}
| "${DIALSTATUS}" = "BUSY"]?b:u)})
same => n,Playback(silence/1)
same => n,VoiceMail(100@lmentinc,${VoiceMailStatus})
same => n,Hangup()
There you have it—sending and receiving messages via the Skype network!
You can also send and receive messages with the Asterisk Manager Interface, the topic of Chapter 20.
We’ve essentially implemented a screen pop solution for
incoming calls, but by allowing messages to be sent back to Asterisk
via Skype within a defined period of time, we’ve also created a
solution for redirecting calls prior to ringing any devices. A more
functional version of the dynamic routing dialplan we just explored
was developed in the section about JABBER_RECEIVE()
earlier in this chapter: it
used the Local channel to get around the dialplan blocking issue,
enabling calls can be routed even after a device has started to be
rung.
While working on this book, we had some issues with trying to come up with clever ways to use a text-to-speech engine. It seemed that dynamic data would need to be involved for text-to-speech to really make a lot of sense—otherwise, why not use prerecorded prompts instead? However, an idea finally came to us, based on the fact that having to assign extension numbers to each Skype user we wanted to call was not only cumbersome, but was a mental exercise we weren’t willing to take on.
The following dialplan makes
use of the SKYPE_BUDDIES()
and SKYPE_BUDDY_FETCH()
dialplan functions to retrieve all the Skype buddies in memory on the
server, and to read those buddies’ names back to you along with their
statuses. After each buddy name is read, a prompt asking if this is
who you wish to call is presented, with the option of asking for
another buddy from the list. We’ve utilized the Festival()
application for this example (the configuration and setup of which
can be found in the section called “Festival”) to read
back the users’ names. Once a buddy has been marked as selected, it is
then dialed using the Dial()
application.
Our implementation is as follows:
[LocalSets]
exten => 75973,1,Verbose(2,Read off list of Skype accounts)
same => n,Answer()
same => n,Set(ID=${SKYPE_BUDDIES(pbx.shifteight.org
)})
same => n(new_buddy),Set(ARRAY(buddy,status)=${SKYPE_BUDDY_FETCH(${ID})})
same => n,GotoIf($[${ISNULL(${buddy})}]?no_more_buddies)
same => n,Festival(${buddy} is ${status})
same => n,Read(Answer,if-correct-press&digits/1&otherwise-press&digits/2,1)
same => n,GotoIf($[${Answer} = 2]?new_buddy)
same => n,Dial(Skype/${buddy},30)
same => n,Playback(user&is-curntly-unavail)
same => n,Hangup()
exten => no_more_buddies,1,Verbose(2,No more buddies to find)
same => n,Playback(dir-nomore)
same => n,Hangup()
[163] Skype for Asterisk currently retails for $66 per license, and includes a G.729 license. Each license permits one simultaneous call.
[164] The VUC is the VoIP Users Conference, which runs weekly at 12:00 noon Eastern time (–0500 GMT). More information is available at http://vuc.me.