简单的Python XMPP机器人

2 投票
1 回答
8674 浏览
提问于 2025-04-16 17:21

我有一段用Python写的简单XMPP机器人代码,使用的是http://xmpppy.sourceforge.net/

#!/usr/bin/python
# -*- coding: utf-8 -*-

import xmpp
import urllib2
import ConfigParser

config = ConfigParser.ConfigParser()
config.read('ipbot.conf')

##########################
user= (config.get('account', 'login'))
password=(config.get('account', 'password'))
presence=(config.get('presence','presence'))
##########################

jid=xmpp.protocol.JID(user)
client=xmpp.Client(jid.getDomain())
client.connect()
client.auth(jid.getNode(),password)

################Parse IP##################
strURL='http://api.wipmania.com/'
f = urllib2.urlopen(urllib2.Request(strURL))
response = f.read()
ipget= response.split("<br>")
f.close()
#############################################

def status(xstatus):
    status=xmpp.Presence(status=xstatus,show=presence,priority='1')
    client.send(msging)

def message(conn,mess):

  global client

  if ( mess.getBody() == "ip" ):
    client.send(xmpp.protocol.Message(mess.getFrom(),ipget[1]+" => "+ipget[0]))#Send IP

client.RegisterHandler('message',message)

client.sendInitPresence()

while True:
    client.Process(1)

请告诉我,怎么把这段代码转换成使用http://wokkel.ik.nu/和twistedmatrix.com/的方式。非常感谢。

1 个回答

5

下面的代码应该可以实现这个功能。这里有几点需要注意:

  • Wokkel使用了一种叫做子协议处理器的东西,来支持特定的子协议,通常是根据概念特性、命名空间或每个XEP来划分的。
  • XMPPClient是一个流管理器,它负责建立连接,并处理与服务器的身份验证。它与连接的子协议处理器一起工作,处理它管理的XML流中的数据。如果连接断开,它会自动重新连接。
  • 这个例子定义了一个新的处理器,用来处理接收到的消息。
  • 与原来的代码不同,这里每当收到一条消息时,都会请求获取消息体中的ip地址。
  • 在原来的代码中,status从来没有被调用过。现在我使用PresenceProtocol子协议处理器,每次建立连接并完成身份验证时,都会发送状态信息。

这个例子是一个叫做Twisted的应用程序,可以通过twistd来启动,正如文档中提到的那样。这会将进程转为后台运行,日志会记录到twisted.log中。如果你在-y之前指定-n,它就不会转为后台运行,而是将日志输出到控制台。

#!/usr/bin/python

"""
XMPP example client that replies with its IP address upon request.

Usage:

    twistd -y ipbot.tac
"""

import ConfigParser

from twisted.application import service
from twisted.python import log
from twisted.web.client import getPage
from twisted.words.protocols.jabber.jid import JID
from twisted.words.protocols.jabber.xmlstream import toResponse

from wokkel.client import XMPPClient
from wokkel.xmppim import PresenceProtocol, MessageProtocol

class IPHandler(MessageProtocol):
    """
    Message handler that sends presence and returns its IP upon request.

    @ivar presenceHandler: Presence subprotocol handler.
    @type presenceHandler: L{PresenceProtocol}

    @ivar show: Presence show value to send upon connecting.
    @type show: C{unicode} or C{NoneType}
    """

    def __init__(self, presenceHandler, show=None):
        self.presenceHandler = presenceHandler
        self.show = show


    def connectionInitialized(self):
        """
        Connection established and authenticated.

        Use the given presence handler to send presence.
        """
        MessageProtocol.connectionInitialized(self)
        self.presenceHandler.available(show=self.show, priority=1)


    def onMessage(self, message):
        """
        A message has been received.

        If the body of the incoming message equals C{"ip"}, retrieve our
        IP address and format the response message in the callback.
        """
        def onPage(page):
            address, location = page.split(u"<br>")
            body = u"%s => %s" % (location, address)
            response = toResponse(message, stanzaType=message['type'])
            response.addElement("body", content=body)
            self.send(response)

        if unicode(message.body) != u"ip":
            return

        d = getPage("http://api.wipmania.com")
        d.addCallback(onPage)
        d.addErrback(log.err)



# Read the configuration file
config = ConfigParser.ConfigParser()
config.read('ipbot.conf')

user =  config.get('account', 'login')
password = config.get('account', 'password')
presence = config.get('presence','presence')

# Set up a Twisted application.
application = service.Application('XMPP client')

# Set up an XMPP Client.
jid = JID(user)
client = XMPPClient(jid, password)
client.logTraffic = True
client.setServiceParent(application)

# Add a presence handler.
presenceHandler = PresenceProtocol()
presenceHandler.setHandlerParent(client)

# Add our custom handler
ipHandler = IPHandler(presenceHandler, presence)
ipHandler.setHandlerParent(client)

撰写回答