Monday, October 27, 2008

skype + dbus + mono

Once again, in effort to create yet another plugin for nGhost I've tread where no man has trodden before, skype + dbus + mono. Once again, because ndesk.dbus has excellent support for dbus, c# was chosen.

The skype API is a set of string commands that you send to skype to do various functions. You can do a lot through the API including sending SMS messages.

At the time of writing this, the dbus documentation for skype was definitely lacking. I was particularly confused on whether the method "Notify" was a dbus-signal, or a service that I had to implement myself. It ended up being the latter. Here are the interfaces:


[Interface("com.Skype.API")]
public interface SkypeSend: Introspectable
{
string Invoke(string message);
}

[Interface("com.Skype.API.Client")]
public interface SkypeResponse: Introspectable
{
void Notify(string message);
}


The "Invoke" method is for Client to Skype communication. Answers to queries are returned back from "Invoke"

Notify, as discussed earlier, is for Skype to client messages. Messages such as Call ... Ringing, or Chat messages are received here. This is a dbus service you have to register yourself using the same dbus connection as you created for "Invoke".

Here is the classes that implement the interfaces:


public class nSkypeDbus
{
public nSkypeDbus()
{
init();
}

public void init()
{
dbus = Bus.Session;
skype = dbus.GetObject("com.Skype.API", new ObjectPath("/com/Skype"));
send("NAME nskype");
send("PROTOCOL 7");
}

public string send(string message)
{
return skype.Invoke(message);
}

private SkypeSend skype;
public Connection dbus;
}


And the implementation of the Client interface:

public class SkypeClient: SkypeResponse
{
private Connection dbus;

public SkypeClient(Connection d)
{
dbus = d;

dbus.Register("com.Skype.API",new ObjectPath("/com/Skype/Client"), this);
NotifyEvent += new NotifyEventHandler(InterpretNotify);
}

public void Notify(string message)
{
System.Console.WriteLine(message);
if(NotifyEvent!=null)
NotifyEvent(message);
}

public void loop()
{
dbus.Iterate();
}


public string Introspect()
{
return "\n \n \n \n \n\n";
}

public void InterpretNotify(string message)
{
if(message.Contains("STATUS RINGING"))
///sample message: CALL 1412 STATUS RINGING
{
if(IncomingCall!=null)
{
string [] p = message.Split(' ');
string caller = p[1];
IncomingCall(this, caller);
}
}
}
public event NotifyEventHandler NotifyEvent;
public event IncomingCallHandler IncomingCall;
}

In the Client implementation, I am trying to catch incoming call notifications.

There's plenty of stuff you can do with skype. Here's the link to the API: http://share.skype.com/sites/devzone/2006/01/api_reference_for_skype_20_bet.html

Hope to see more skype goodies for Linux....

1 comment:

Stuart said...

Thank for this, saved me a lot of time.