[156] | 1 | """ |
---|
| 2 | An XMPP MUC client. |
---|
| 3 | |
---|
| 4 | This XMPP Client logs in as C{user@example.org}, joins the room |
---|
| 5 | C{'room@muc.example.org'} using the nick C{'greeter'} and responds to |
---|
| 6 | greetings addressed to it. If another occupant writes C{'greeter: hello'}, it |
---|
| 7 | will return the favor. |
---|
| 8 | |
---|
| 9 | This example uses L{MUCClient} instead of the protocol-only |
---|
| 10 | L{MUCClientProtocol<wokkel.muc.MUCClientProtocol>} so that it can hook into |
---|
| 11 | its C{receivedGroupChat}. L{MUCClient} implements C{groupChatReceived} and |
---|
| 12 | makes a distinction between messages setting the subject, messages that a |
---|
| 13 | part of the room's conversation history, and 'live' messages. In this case, |
---|
| 14 | we only want to inspect and respond to the 'live' messages. |
---|
| 15 | """ |
---|
| 16 | |
---|
| 17 | from twisted.application import service |
---|
[162] | 18 | from twisted.python import log |
---|
[156] | 19 | from twisted.words.protocols.jabber.jid import JID |
---|
| 20 | from wokkel.client import XMPPClient |
---|
| 21 | from wokkel.muc import MUCClient |
---|
| 22 | |
---|
| 23 | # Configuration parameters |
---|
| 24 | |
---|
| 25 | THIS_JID = JID('user@example.org') |
---|
| 26 | ROOM_JID = JID('room@muc.example.org') |
---|
| 27 | NICK = u'greeter' |
---|
| 28 | SECRET = 'secret' |
---|
| 29 | LOG_TRAFFIC = True |
---|
| 30 | |
---|
| 31 | class MUCGreeter(MUCClient): |
---|
| 32 | """ |
---|
| 33 | I join a room and respond to greetings. |
---|
| 34 | """ |
---|
| 35 | |
---|
| 36 | def __init__(self, roomJID, nick): |
---|
| 37 | MUCClient.__init__(self) |
---|
| 38 | self.roomJID = roomJID |
---|
| 39 | self.nick = nick |
---|
| 40 | |
---|
| 41 | |
---|
| 42 | def connectionInitialized(self): |
---|
| 43 | """ |
---|
| 44 | Once authorized, join the room. |
---|
[162] | 45 | |
---|
| 46 | If the join action causes a new room to be created, the room will be |
---|
| 47 | locked until configured. Here we will just accept the default |
---|
| 48 | configuration by submitting an empty form using L{configure}, which |
---|
| 49 | usually results in a public non-persistent room. |
---|
| 50 | |
---|
| 51 | Alternatively, you would use L{getConfiguration} to retrieve the |
---|
| 52 | configuration form, and then submit the filled in form with the |
---|
| 53 | required settings using L{configure}, possibly after presenting it to |
---|
| 54 | an end-user. |
---|
[156] | 55 | """ |
---|
[162] | 56 | def joinedRoom(room): |
---|
| 57 | if room.locked: |
---|
| 58 | # Just accept the default configuration. |
---|
| 59 | return self.configure(room.roomJID, {}) |
---|
| 60 | |
---|
[156] | 61 | MUCClient.connectionInitialized(self) |
---|
[162] | 62 | |
---|
| 63 | d = self.join(self.roomJID, self.nick) |
---|
| 64 | d.addCallback(joinedRoom) |
---|
| 65 | d.addCallback(lambda _: log.msg("Joined room")) |
---|
| 66 | d.addErrback(log.err, "Join failed") |
---|
| 67 | |
---|
[156] | 68 | |
---|
| 69 | def receivedGroupChat(self, room, user, message): |
---|
| 70 | """ |
---|
| 71 | Called when a groupchat message was received. |
---|
| 72 | |
---|
| 73 | Check if the message was addressed to my nick and if it said |
---|
| 74 | C{'hello'}. Respond by sending a message to the room addressed to |
---|
| 75 | the sender. |
---|
| 76 | """ |
---|
| 77 | if message.body.startswith(self.nick + u":"): |
---|
| 78 | nick, text = message.body.split(':', 1) |
---|
| 79 | text = text.strip().lower() |
---|
| 80 | if text == u'hello': |
---|
| 81 | body = u"%s: Hi!" % (user.nick) |
---|
| 82 | self.groupChat(self.roomJID, body) |
---|
| 83 | |
---|
| 84 | |
---|
| 85 | # Set up the Twisted application |
---|
| 86 | |
---|
| 87 | application = service.Application("MUC Client") |
---|
| 88 | |
---|
| 89 | client = XMPPClient(THIS_JID, SECRET) |
---|
| 90 | client.logTraffic = LOG_TRAFFIC |
---|
| 91 | client.setServiceParent(application) |
---|
| 92 | |
---|
| 93 | mucHandler = MUCGreeter(ROOM_JID, NICK) |
---|
| 94 | mucHandler.setHandlerParent(client) |
---|