32
基基 XMPP 基 Gtalk 基基基 [email protected] 2010.9.4

基于XMPP的Gtalk机器人

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: 基于XMPP的Gtalk机器人

基于 XMPP 的 Gtalk 机器人[email protected]

2010.9.4

Page 2: 基于XMPP的Gtalk机器人

缘起:                 1, 手动更新测试仓库的 SVN     给同事用         2, 在 BlackBerry 上快速访问服务器 给自己用         3, 安排菜谱,讲笑话 给媳妇用 ;)

Page 3: 基于XMPP的Gtalk机器人

既然大家都有 Gtalk

那我们就来做个贴心的“小萝莉”机器人吧 ^_&

Page 4: 基于XMPP的Gtalk机器人

HOW?

当然是“可爱的 Python”   +   XMPP   了

Page 5: 基于XMPP的Gtalk机器人

Python !!! 你懂的,咱就先说 XMPP 吧 ~~

Page 6: 基于XMPP的Gtalk机器人

XMPP :原名 Jabber             eXtensible Messaging Presence Protocol 可扩展的消息状态协议 用于Gtalk 就是基于 XMPP 协议,并对协议进行了扩充Google Wave 也是,虽然“出师未捷身先死” Orz

延伸阅读 http://knb.im/67y

Page 7: 基于XMPP的Gtalk机器人

XMPP 的架构? 简单来说,就是 Client-Server , Server-Server 一个分散型的通信网络哦 复杂来说, $%^&#*#$

Page 8: 基于XMPP的Gtalk机器人

拜托,我们只是想要写一个贴心的 Bot 而已。。。Z.Q 大妈教导过我们, Python 是拿来用的,让我们快乐的朝目标前进就好 ~~~

Page 9: 基于XMPP的Gtalk机器人

出发之前的一些基础:

JID : XMPP 的 client 端和 server 端统称为XMPP 实体,用 JID 作为一个全局唯一的标识符。格式为: node@domain/resource

[email protected]/xxxx   就是我了 -_-

Page 10: 基于XMPP的Gtalk机器人

出发之前的一些基础:

xmpp 的消息传递系统包括三种内容:

1, 消息( Message ),普通的对话留言

Page 11: 基于XMPP的Gtalk机器人

出发之前的一些基础:

xmpp 的消息传递系统包括三种内容:

2, 联机状态( Presence ),用户广播的”在线状态“和可用性

Page 12: 基于XMPP的Gtalk机器人

出发之前的一些基础:

xmpp 的消息传递系统包括三种内容:

3, 信息 / 查询请求( Iq ),允许 XMPP 实体发起请求,并接受返回的响应

Page 13: 基于XMPP的Gtalk机器人

出发之前的一些基础:

xmpp stanza : xmpp 节。是以 xml 表达的最小的信息项,每个 stanza 都有以下的公共属性:from:   源 xmpp 实体的 JIDto:   目标 xmpp 实体的 JIDid:   这次对话的可选标识符type:  stanza 的可选子类型

Page 14: 基于XMPP的Gtalk机器人

从之前可以看出, XMPP 是基于 XML 流的。 Fuck~

让我们自己处理的话太繁琐,幸好 python 有众多的功能模块,我们用 xmpppy

Page 15: 基于XMPP的Gtalk机器人

import xmpp

jid = xmpp.JID('[email protected]/python')

message = xmpp.Message('say something')

presence = xmpp.Presence('I'm at NGOsoft.com ')

iq = xmpp.Iq()

对象简单明了,开工 ~

Page 16: 基于XMPP的Gtalk机器人

问题一,该如何让我的 bot 登录呢?jid = '[email protected]'pwd = 'password'jid_instance = xmpp.JID(jid)cl = xmpp.client(jid_instance.getDomain(), debug[])cl.connect()cl.auth(jid_instance.getNode(), pwd)

Page 17: 基于XMPP的Gtalk机器人

问题二,该如何让我的 bot 持续在线?status = xmpp.Presence(status=' 小萝莉 ')cl.sendInitPresence()cl.send(status)while 1:    cl.Process(1)

send 函数可以用来发送三种类型的内容

Page 18: 基于XMPP的Gtalk机器人

问题三,如何给 bot 注册 handler ?cl.RegisterHandler('message', message_handler)

cl.RegisterHandler('presence', presence_handler)

cl.RegisterHandler('iq', iq_handler)

一旦 bot 收到这三种类型的内容,就交由响应的handler 函数来处理。

Page 19: 基于XMPP的Gtalk机器人

问题四,如何让 bot 处理添加好友的请求?所谓的添加好友,其实就是两个实体的互相”订阅“。此信息为 presence 类型:cl.send(xmpp.Presence(to='[email protected]', typ='subscribe'))cl.send(xmpp.Presence(to='[email protected]', typ='subscribed'))

Page 20: 基于XMPP的Gtalk机器人

问题五,如何让 bot 处理我们发给她的信息?发给 bot 的信息 ===>   要传递的指令因此要先把这些指令和发送者提取出来def message_handler(self, conn, mess):    who = mess.getFrom()    content = mess.getBody() 处理 content ,获得 cmd 和 arguments    if cmd in commands:        cmd_xxx(arguments)    #commands 为命令列表                                              #cmd_xxx 为命令函数

Page 21: 基于XMPP的Gtalk机器人

client ==> (message)==>message_handler==>cmd_xxx

对发送信息的处理流程

Page 22: 基于XMPP的Gtalk机器人

def cmd_xxx(self, args):    # 功能部分    cl.send(xmpp.Message(who, reply))

Page 23: 基于XMPP的Gtalk机器人

出现了一个问题:选择执行 cmd_xxx() 函数的时候,由于 xxx 是一个可变化的值,改如何实现? 解决方法:使用 commands[xxx]() 来做函数的选择。 commands={'xxx':func, ...}

可是,如何能动态的生成 commands{ } ?     

Page 24: 基于XMPP的Gtalk机器人

解决办法:定义一个 register_commands() 的函数,让其在 __init__()中执行,动态的检测 class中存在的cmd_xxx 函数,并给 commands赋值。       

def register_commands(self):    self.commands={}    for name, value in inspect.getmembers(self):         if inspect.ismethod(value) and \         getattr(value, '_is_method', Falsa):             self.commands[name] = value

Page 25: 基于XMPP的Gtalk机器人

并且,我们并不在每个 cmd_ 函数中设置 "_is_command" 属性,而是使用 @修饰符来加工cmd_ 函数,为其设置属性。def botcommands(*args):    func = args[0]    setattr(func, '_is_command', True)    return func

@botcommandsdef cmd_xxx():

Page 26: 基于XMPP的Gtalk机器人

def bootcommands(*args):      func = args[0]      setattr(func, '_is_command', True)      return func

使用修饰符函数,来建立我们的 commands system

Page 27: 基于XMPP的Gtalk机器人

问题六,怎样知道 bot 的工作情况?

定义一个 log 函数,把每次 handler 的结果记录到文件中去

Page 28: 基于XMPP的Gtalk机器人

到目前为止,我们自己的 bot 小框架就算是完成了,粗略回顾一下:client-->connect-->auth-->register_handler            verify_request-->presence_handler-->log            message-->message_handler-->cmd_xx-->log 添加新的 cmd 功能:@botcommands()def cmd_xx():

Perfect   ;)

Page 29: 基于XMPP的Gtalk机器人

但杯具的是,我还有一些遗留问题没有处理完:1,log 系统因为编码的原因,暂时只能用英文凑合着2, 这个 bot没有写为 daemon 进程,退出终端后, bot会跟着”死去“。目前的解决办法是跑在 screen里 -_&!

有没有好的建议?

Page 30: 基于XMPP的Gtalk机器人

bot 的雏形搞完了,可最初的功能还没实现呢 ~~

目前只写了两个 cmd_ 函数 cmd_help     打印帮助信息cmd_server   基于 xmpp 来控制服务器cmd_work   与 server 类同,都是在 server 端执行命令,只是要用脚本配合罢了但是给媳妇用的 cmd_eat 和 cmd_joy还没想好如何来实现,是从网上抓数据,还是用本地的数据库呢? Orz

Page 31: 基于XMPP的Gtalk机器人

问题 &讨论推荐:http://xmpppy.sourceforge.nethttp://code.google.com/p/pygtalkrobot/http://www.ibm.com/developerworks/cn/xml/tutorials/x-realtimeXMPPtut/index.html

Page 32: 基于XMPP的Gtalk机器人

END 

Thanks  ;)

@[email protected]