A SkypeKit transport for DCBot
A couple of posts back I walked through putting together a (somewhat) decoupled bot system using ZeroMQ and a bunch of scripts in various languages.
The transports I supplied as part of the example were for IRC and a local console. At the time I had also written a very basic SkypeKit transport but had decided not to release it as I was unsure about the terms and conditions surrounding this type of use (it previously had banned "server-side" usage, and likely still does, however my interpretation of that is a little fuzzy). So while I'm still unsure about it I figure there's no harm in releasing it with a disclaimer that you use this at your own risk.
A quick intro to SkypeKit
The SkypeKit SDK is essentially a headless version of Skype that is designed to be embedded into client applications. Anyone can gain access to the SDK by visiting developer.skype.com and paying a small fee.
The download essentially consists of a binary blob that runs and interfaces with the Skype network, while providing an IPC for the SkypeKit API to send and receive messages. The bundled API covers a few different languages but I found the easiest to get started with is the Python binding. This is what the "transport" will use.
Configuration.
SkypeKit requires an account name/password, as well as a private key file in order to connect to the network. We will define these in a separate file to keep these away from the implementation itself.
skypeconfig.py
accountName = "your-bot-name"
accountPassword = "bot-password"
keyFileName = "/path/to/your/keyfile.pem"
distroRoot = "/path/to/the/skypekit/sdk"
The code.
With the configuration ready to go, now it's on to the implementation itself, this is very similar to the example provided only with added ZeroMQ.
skype.py
#!/usr/bin/env python2
import sys
from time import sleep
# Import the skypeconfig.py values.
import skypeconfig
# Import modules for JSON and ZeroMQ, needed for our bot.
import simplejson as json
import zmq
# SkypeKit setup.
sys.path.append(skypeconfig.distroRoot + '/ipc/python')
sys.path.append(skypeconfig.distroRoot + '/interfaces/skype/python')
try:
import Skype
except ImportError:
raise SystemExit('Requires Skype and skypekit modules')
# Declare a couple of callbacks.
def OnMessage(self, message, changesInboxTimestamp, supersedesHistoryMessage, conversation):
global core
if message.author != skypeconfig.accountName:
print(message.author_displayname + ': ' + message.body_xml)
core.send(json.dumps({ "type": "message", "nick": message.author_displayname, "msg": message.body_xml }))
lines = json.loads(core.recv())
for line in lines:
conversation.PostText(line, False)
def AccountOnChange (self, property_name):
if property_name == "logoutreason":
print(self.logoutreason)
if property_name == 'status':
print(self.status)
if self.status == 'LOGGED_IN':
print('Logged in')
# Connect them up.
Skype.Skype.OnMessage = OnMessage
Skype.Account.OnPropertyChange = AccountOnChange
# Start up SkypeKit.
try:
SkypeHandle = Skype.GetSkype(skypeconfig.keyFileName)
SkypeHandle.Start()
except Exception:
raise SystemExit('Unable to create skype instance')
# Set up ZeroMQ
DCBOT_CORE = "tcp://localhost:5555"
context = zmq.Context()
core = context.socket(zmq.REQ)
core.connect(DCBOT_CORE)
# Time to tell SkypeKit to log in.
account = SkypeHandle.GetAccount(skypeconfig.accountName)
account.LoginWithPassword(skypeconfig.accountPassword, False, False)
# Wait for input before stopping the transport.
print("Hit enter to stop transport.")
raw_input('')
# Logout and stop SkypeKit.
SkypeHandle.stop();
Running this along with the SkypeKit binary and the rest of the bot should allow you to query your bot over Skype :)