saush

Accessing Skype APIs with Ruby

Posted in Ruby, skype by sausheong on November 21, 2006

I was fiddling around with the Skype APIs for the past few days and things seem pretty happening in the Skype developer community. The last time I looked at it was a beta of Skype’s very first release and that wasn’t so long ago. It is now at the 3.0 beta release, a release that looks pretty solid to me even though access to the ‘naked’ version of Skype (the Skype engine without actually invoking the Skype client) is still a pipe-dream.

For those who are unaware of a Skype API at all, yes, Skype actually opens up its network and APIs to the public. There is support in for Windows, Linux and Mac (though not in the Windows Mobile, as far as I know). There is also support for Java using Skype4Java and ActiveX using Skype4COM.

I won’t go into the API details but essentially the Skype API allows applications to pass commands to Skype in simple text messages. There are two sets of APIs — the phone API, which is mostly used by device developers (e.g. USB phone manufacturers) and the access API, which is mostly for the desktop developers. I’ll talk more on the access API in this post.

The access API enables external applications to control Skype functions. However before this is allowed, Skype will pop-up the name of the application and asks the user to grant permission to do this. Also, all actions that are done by the external application will be mirrored on the Skype client itself. This can be pretty annoying. The good news is that since Skype 2.6 you can use the ‘silent mode’ to mute this. However you’ll still need to get the user’s permission to execute the application.

There isn’t a Ruby binding of the Skype APIs (at least not that I know of) though you can probably try to go at it through Skype4Java via JRuby.  However there is an alternative if you’re running this on Windows. Ruby provides a very neat and powerful extension (built-in with any Ruby Windows distribution) called Win32OLE that allows a Windows automation client to command or query a Windows automation server. To cut a long story short, you can use Win32OLE to access Skype4COM.

Let me run through quickly how this can be done. Firstly you need to download Skype4COM. This contains a bunch of files, among which the most important is skype4com.dll. You will also use skype4com.chm (the Windows Help API reference file) pretty often. If you intend to run in silent mode, you’ll need to make sure you run at least Skype 2.6 and above. Try Skype 3.0 beta. Just download and install it, you don’t need to do anything else.
Now that you have the files, run this command to register the Skype library:

regsvr32 skype4com.dll

And you're done. Copy this code somewhere, save it and run it:

# This simple example echos whatever chat message that is sent to you

require 'win32ole'

# create the new Skype automation object
skype = WIN32OLE.new 'Skype4COM.Skype'

# some constants for easy viewing
$RECEIVED= skype.Convert.TextToChatMessageStatus("RECEIVED")
$SAID = skype.Convert.TextToChatMessageType("SAID")

# uncomment the below if you want to run in silent mode. Only works from Skype 2.6 and above
# skype.SilentMode = true

# attach to Skype
skype.attach

# A default handler for any events. You can use this to handle all miscellanous events or if
# you don't have any specific behaviors you want to trigger on
def default_handler(event, *args)
case event
# When someone calls
when "CallStatus"
# do nothing for now

# When any online status changes
when "OnlineStatus"
# do nothing
end

end

# Or you can use a specific method to catch this event
def message_status(msg,status)
# echo whatever is send to you in a chat message
msg.chat.SendMessage msg.body if status == $RECEIVED && msg.Type == $SAID
end

# register to receive events from Skype
event = WIN32OLE_EVENT.new(skype, '_ISkypeEvents')
# on any event at all, go to the default handler
event.on_event {|*args| default_handler(*args)}
# for this specific event
event.on_event("MessageStatus") { | *args| message_status args[0], args[1]}

# loop forever
catch(:done) do
loop do
WIN32OLE_EVENT.message_loop
end
end

This is a simple example, but you can see how powerful it can be. For instance you can grab any chat messages sent to you while you are away and send it to you via SMS. Or turning it on its tail you can set up multiple clients with Skype, and literally send command messages to the various clients to execute. Also, though mashups are more associated with APIs like Google Map or Flickr, you can imagine that Skype is a pretty powerful mashup API as well, mixing it up with the others available out there.

Skype has opened up a Pandora's box of possibilities with the release of their API. Do check it out.

About these ads

11 Responses

Subscribe to comments with RSS.

  1. Anthony said, on November 22, 2006 at 8:01 am

    Thanks this is helpful stuff.

    It really is interesting how this opens up a world of possibilities.

  2. Paolo Dona said, on December 15, 2006 at 12:10 am

    Great post man! I’ll try it out asap!

  3. andrew said, on December 29, 2006 at 1:45 am

    I had just started a C# .NET project to do some skype integration work. Then I found this post and woohoo, I did it all in Ruby.

  4. Davide said, on January 6, 2007 at 8:10 am

    Hi,
    I’ve just tried your sample with irb, but when I execute:
    skype.attach

    it returns:
    irb(main):007:0> skype.attach
    WIN32OLERuntimeError: attach
    OLE error code:80040201 in Skype4COM.Skype.1
    Wait timeout.
    HRESULT error code:0×80020009
    Exception occurred.
    from (irb):7:in `method_missing’
    from (irb):7

    Any hint?
    Thanks

  5. sausheong said, on January 6, 2007 at 9:29 am

    Strange, did you try it out in a file? I tried this under irb and it looks ok to me.

  6. Davide said, on January 7, 2007 at 5:20 am

    Now, after a restart of my pc, it works, boh.
    BTW thanks
    Davide

  7. Serge Kruppa said, on January 13, 2007 at 7:01 am

    The issue is that the WIN32OLE message loop is too tight and takes 90% of the CPU, which is hardly acceptable in any application. Does anyone knows a better solution? (please CC me on my e-mail, thanks)

  8. Philipp s said, on January 25, 2007 at 11:00 pm

    Hi,
    Do you need to run Skype client in your desktop when you use this API?
    Thanks

  9. sausheong said, on January 26, 2007 at 12:49 am

    Yes, you will always need to have the Skype client running when you use this API, unless Skype opens up their Skype engine (or their ‘naked’ version as some call it) one day.

  10. Evan Light said, on April 22, 2007 at 4:25 am

    I’ve also put together a simple Skype gem for use with Mac OS X using the Applescript Event layer: rb-skypemac (http://evan.tiggerpalace.com/?p=1). It doesn’t implement the whole Skype API but it provides the key features.

  11. Albert said, on June 21, 2010 at 2:34 pm

    where to download Skype4COM.dll ? the link given invalid


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 446 other followers

%d bloggers like this: