Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

SmartPresence for Google Talk

3 Jun 2013 1  
SmartPresence for Google Talk

This article is in the Product Showcase section for our sponsors at CodeProject. These articles are intended to provide you with information on products and services that we consider useful and of value to developers.

Introduction

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:

import xmpp
'''
Simple implementation of the Shared Status Messages - Google extension to XMPP Presence
https://developers.google.com/talk/jep_extensions/shared_status
'''
class GoogleTalk:
    def __init__(self,user,password):
        self.user = user
        self.client=xmpp.Client(server='gmail.com',debug=[])
        self.client.connect(server=('talk.google.com',5222))
        self.client.auth(user,password,'gmail.com')
        self.client.sendInitPresence()
    def set_available(self):
        self.client.send(xmpp.protocol.Iq('set','google:shared-status', payload=[xmpp.Node('show',payload=['']), xmpp.Node('status',payload=[''])]))
    def set_busy(self):
        self.client.send(xmpp.protocol.Iq('set','google:shared-status', payload=[xmpp.Node('show',payload=['dnd']), xmpp.Node('status',payload=['Busy'])]))
    def set_away(self):
        self.client.send(xmpp.protocol.Iq('set','google:shared-status', payload=[xmpp.Node('show',payload=['away'])]))
    def set_in_a_call(self):
        self.client.send(xmpp.protocol.Iq('set','google:shared-status', payload=[xmpp.Node('show',payload=['dnd']), xmpp.Node('status',payload=['In a call'])]))
    
    def set_in_a_mobile_call(self):
        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)
gt.set_busy()

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:

class Spokes:
...
    def get_call_service_events(self):
        self.CallServicesEventsURL = '/Spokes/CallServices/Events'
        self.conn.request('GET', self.CallServicesEventsURL);
        r = self.conn.getresponse()
        #Call states as define in the Spokes SDK
        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)
            call_state_events=[]
            if response['Err']==None and len(response['Result'])>0:
                for c in response['Result']:
                    call_state_events.append(call_states[c])
            return call_state_events

And the 'main' module would look like:

gt = GoogleTalk(user.name, user.password)
s = Spokes()
dl = s.get_device_list()
s.register()
if len(dl)>0:
    d = dl[0]
    d.attach()
    print "Connected to: ", d.ProductName
    if d.attached:
        while True:
            gt.client.Process(1)
            evts = d.get_events()
            if evts:
                for ev in evts:
                    if 'Don' == ev['Event_Name']:
                        gt.set_available()
                    elif 'Doff' == ev['Event_Name']:
                        gt.set_away()
                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()
                print csevts
                if csevts:
                    for csev in csevts:
                        if 'CallInProgress' == csev:
                            gt.set_in_a_call()
                        if 'MobileCallInProgress' == csev:
                            gt.set_in_a_mobile_call()
                        if 'CallEnded' == csev or 'MobileCallEnded' == csev:
                            gt.set_available()
            time.sleep(.5)
else:
    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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here