XMPP Echobot

这是一个基于python-jabberbot的自动转发机器人。任何好友和它说话,都将被转发给其他好友。虽然XMPP支持群聊天,但是这种模式在我看来,提供了更加易于实现将任何一对一的加密扩展出可靠的群聊天的可能。这个机器人的代码修改自python-jabberbot的示例代码。下面进行代码解释。

This is a simple automatic forwarding bot basing on python-jabberbot. Each message sent to this bot will be forwarded to its buddies. Although XMPP supports conferencing, I think this bot’s mode provides an easier approach to extend any peer-to-peer encrypted messaging into reliable conferences. This bot’s code is modified from an example code of python-jabberbot. The following is my code’s explanation.

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

from jabberbot import JabberBot
import threading,time,logging,xmpp

# Fill in the JID + Password of your JabberBot here...
(JID, PASSWORD) = ('【用户名】','【密码】')

class BroadcastingJabberBot(JabberBot):

    def __init__( self, jid, password, res = None):
        super( BroadcastingJabberBot, self).__init__( jid, password, res)

        self.message_queue = []
        self.thread_killed = False

广播类继承自JabberBot,初始化所做的是清除消息队列等一系列操作。

The class inherits from Jabberbot. Initialize to clear up message queue and others.

    def callback_message(self, conn, mess):
    
        type = mess.getType()
        jid = mess.getFrom()
        props = mess.getProperties()
        text = mess.getBody()
        username = self.get_sender_username(mess)

        if type not in ("groupchat", "chat"):
            return

        # Ignore messages from before we joined
        if xmpp.NS_DELAY in props:
            return

        # Ignore messages from myself
        if self.jid.bareMatch(jid):
            return

        if jid == None:
            return

        sender = jid.getStripped()
        if sender == None:
            return

        self.message_queue.append(u'\n%s 说:\n%s' % (str(sender),text))

上面重写了 callback_message 方法,注意到里面一些代码用于识别聊天信息、过滤空内容。之后将消息送入消息队列中。

The above rewrites callback_message. Notice some code is used to identify chatting messages and filter out nulls. Then message is queued.

    def idle_proc( self):
        if not len(self.message_queue):
            return

        # copy the message queue, then empty it
        messages = self.message_queue
        self.message_queue = []

        for message in messages:
            for user in self.roster.getItems():#self.users:
                self.send( user, message)

空闲的时候发送消息。

Send message when idle.

    def thread_proc( self):
#        return
        while not self.thread_killed:
            self.message_queue.append('this is an automatic message, sent all 60 seconds :)')
            for i in range(60):
                time.sleep( 1)
                if self.thread_killed:
                    return

这一段定时60秒发送消息、处理退出等。似乎根据XMPP的协议,如果一定时间没动作用户会下线,所以有了这个函数。

Timed 60s to send a regular message, and handle exit events. Seems XMPP protocol requires user acting within given period to avoid being kicked offline. That’s the purpose.

bc = BroadcastingJabberBot( JID, PASSWORD)

th = threading.Thread( target = bc.thread_proc)
bc.serve_forever( connect_callback = lambda: th.start())
bc.thread_killed = True

最后,启动程序。

Fire the program finally.