Skype Integration

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.

Installation of Skype for Asterisk

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.

Using Skype for Asterisk

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.

Configuring chan_skype.conf

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.

Note

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 and receiving calls via Skype

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/4165551212, replacing the number 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

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!

Tip

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.

Calling your Skype buddies without assigning extension numbers

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.