Plantronics Spokes comes out of the box with a feature that we call Smart Presence, which enables automatic presence updates based on the contextual information from the headsets. For example, if you have Skype and your headset is connected to your machine and to your cell phone, once you get a mobile call, your Skype status will change to Busy, and will revert back to Available once the call is done.
In this article I'll show you the code I wrote during a recent Hackathon in Miami on how to do the same for Google Talk.
Here are some basics that you'll need:
- Spokes (we'll be using the REST API, so either Spokes or the SDK)
- an account with Google and either Google Talk or Gmail running
- some background information on XMPP (used by Google Talk) and some of the Google extensions
- in my case here, I'm using an XMPP library for Python
The first 2 are easy, go to http://www.plantronics.com/us/support/software-downloads/ and Google Accounts if you need them.
XMPP info can be found here: http://xmpp.org/ and the extensions here:http://xmpp.org/xmpp-protocols/xmpp-extensions/
By default, if you update the presence in an XMPP client (such as Pidgin, for example), it will not propagate across to all clients logged in the same account. This is where the Google extension comes into play: Shared Status Messages - Google Talk for Developers — Google Developers
Let's get busy...
Here's the XMPP/Google Talk implementation:
Simple implementation of the Shared Status Messages - Google extension to XMPP Presence
self.user = user
self.client.send(xmpp.protocol.Iq('set','google:shared-status', payload=[xmpp.Node('show',payload=['']), xmpp.Node('status',payload=[''])]))
self.client.send(xmpp.protocol.Iq('set','google:shared-status', payload=[xmpp.Node('show',payload=['dnd']), xmpp.Node('status',payload=['Busy'])]))
self.client.send(xmpp.protocol.Iq('set','google:shared-status', payload=[xmpp.Node('show',payload=['dnd']), xmpp.Node('status',payload=['In a call'])]))
self.client.send(xmpp.protocol.Iq('set','google:shared-status', payload=[xmpp.Node('show',payload=['dnd']), xmpp.Node('status',payload=['In a mobile call'])]))
This code alone allows a user to change his/her presence in Google Talk and GMail by simply doing something like:
gt = GoogleTalk(user.name, user.password)
Where user.name and user.password contain the real user and password for authenticating with Google.
The next part now is to get the Spokes and device side of things working. Using the code from my previous post on REST and Python, and expanding it a little to also handle call notifications:
self.CallServicesEventsURL = '/Spokes/CallServices/Events'
r = self.conn.getresponse()
call_states=['Unknown', 'AcceptCall', 'TerminateCall', 'HoldCall', 'Resumecall', 'Flash', 'CallInProgress',
'CallRinging', 'CallEnded', 'TransferToHeadSet','TransferToSpeaker', 'MuteON', 'MuteOFF', 'MobileCallRinging',
'MobileCallInProgress', 'MobileCallEnded', 'Don', 'Doff','CallIdle', 'Play', 'Pause', 'Stop', 'DTMFKey', 'RejectCall']
if r.status == 200:
response = r.read()
response = json.loads(response)
if response['Err']==None and len(response['Result'])>0:
for c in response['Result']:
And the 'main' module would look like:
gt = GoogleTalk(user.name, user.password)
s = Spokes()
dl = s.get_device_list()
d = dl
print "Connected to: ", d.ProductName
evts = d.get_events()
for ev in evts:
if 'Don' == ev['Event_Name']:
elif 'Doff' == ev['Event_Name']:
cms = s.get_call_manager_state()
print "Number of active calls: ", len(cms)
print "Calls: "
for call in cms: print call
csevts = s.get_call_service_events()
for csev in csevts:
if 'CallInProgress' == csev:
if 'MobileCallInProgress' == csev:
if 'CallEnded' == csev or 'MobileCallEnded' == csev:
print "No devices found"
The application will loop until it is terminated and while it is running, if you get a call in your cell, skype or any other softphone integrated with Spokes, your presence in Google Talk will also be in sync with that in the other soft phones.
The presence will also be updated depending the wearing state of the headset, and it'll show as 'Away' if the headset is not being worn, and as 'Available' of the headset is being worn (main code lines 17-20).
I hope this sparks some other ideas and gives you some information on how Spokes, REST and XMPP can work together.
This article was written by Ricardo de Andrade. Ricardo is a Systems Architect and Evangelist at Plantronics helping the developer community, clients and partners with the Spokes SDK and building solutions around current and future offerings. Ricardo has an extensive background in software and cloud distributed architectures, and in specific telecommunications. Ricardo previously worked for Microsoft where he helped clients and partners to develop cloud based speech recognition applications and integrate their web services into the Microsoft Tellme services.