65.9K
CodeProject 正在变化。 阅读更多。
Home

SmartPresence for Google Talk

2013年6月3日

CPOL

3分钟阅读

viewsIcon

15374

SmartPresence for Google Talk

引言

Plantronics Spokes 开箱即用,配备我们称之为 Smart Presence 的功能,该功能可根据来自耳机的上下文信息自动更新状态。例如,如果您有 Skype,并且您的耳机已连接到您的机器和您的手机,一旦您接到手机来电,您的 Skype 状态将更改为“忙碌”,并在通话结束后恢复为“可用”。

在本文中,我将向您展示我在最近于迈阿密举办的 Hackathon 期间编写的代码,该代码展示了如何为 Google Talk 执行相同的操作。

以下是您需要的一些基本知识

  • Spokes(我们将使用 REST API,因此使用 Spokes 或 SDK) 
  • 一个 Google 帐户,并且运行 Google Talk 或 Gmail
  • 一些关于 XMPP(由 Google Talk 使用)和一些 Google 扩展的背景信息
  • 在这里,我使用的是 Python 的 XMPP 库

前 2 个很容易,如果需要,请访问 http://www.plantronics.com/us/support/software-downloads/Google 帐户

可以在这里找到 XMPP 信息:http://xmpp.org/,扩展信息在这里:http://xmpp.org/xmpp-protocols/xmpp-extensions/

默认情况下,如果您在 XMPP 客户端(例如 Pidgin)中更新状态,它不会传播到登录同一帐户的所有客户端。这就是 Google 扩展发挥作用的地方:共享状态消息 - Google Talk for Developers — Google Developers

让我们开始吧...

这是 XMPP/Google Talk 的实现

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'])]))

仅此代码就允许用户通过简单地执行以下操作来更改他在 Google Talk 和 GMail 中的状态

gt = GoogleTalk(user.name, user.password)
gt.set_busy()

其中 user.name 和 user.password 包含用于向 Google 进行身份验证的真实用户名和密码。

现在,下一部分是让 Spokes 和设备端工作。使用我之前在 关于 REST 和 Python 的文章 中的代码,并稍微扩展它以处理呼叫通知

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

并且“main”模块看起来像

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"

该应用程序将循环运行,直到它被终止,并且在它运行期间,如果您在手机、Skype 或任何其他与 Spokes 集成的软电话中接到来电,您在 Google Talk 中的状态也将与其他软电话中的状态同步。

状态也将根据耳机的佩戴状态进行更新,如果未佩戴耳机,它将显示为“离开”,如果佩戴了耳机,则显示为“可用”(主代码行 17-20)。

我希望这能激发其他想法,并为您提供有关 Spokes、REST 和 XMPP 如何协同工作的一些信息。

本文由 Ricardo de Andrade 撰写。Ricardo 是 Plantronics 的系统架构师和布道师,他帮助开发人员社区、客户和合作伙伴使用 Spokes SDK 并构建围绕当前和未来产品的解决方案。Ricardo 在软件和云分布式架构方面拥有丰富的背景,尤其是在电信方面。Ricardo 之前曾在微软工作,在那里他帮助客户和合作伙伴开发基于云的语音识别应用程序,并将他们的 Web 服务集成到 Microsoft Tellme 服务中。

© . All rights reserved.