summaryrefslogtreecommitdiff
path: root/docs/getting_started/muc.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/getting_started/muc.rst')
-rw-r--r--docs/getting_started/muc.rst206
1 files changed, 206 insertions, 0 deletions
diff --git a/docs/getting_started/muc.rst b/docs/getting_started/muc.rst
index 08f721f7..26e1fa57 100644
--- a/docs/getting_started/muc.rst
+++ b/docs/getting_started/muc.rst
@@ -1,2 +1,208 @@
+.. _mucbot:
+
+=========================
Mulit-User Chat (MUC) Bot
=========================
+
+.. note::
+
+ If you have any issues working through this quickstart guide
+ or the other tutorials here, please either send a message to the
+ `mailing list <http://groups.google.com/group/sleekxmpp-discussion>`_
+ or join the chat room at `sleek@conference.jabber.org
+ <xmpp:sleek@conference.jabber.org?join>`_.
+
+If you have not yet installed SleekXMPP, do so now by either checking out a version
+from `Github <http://github.com/fritzy/SleekXMPP>`_, or installing it using ``pip``
+or ``easy_install``.
+
+.. code-block:: sh
+
+ pip install sleekxmpp # Or: easy_install sleekxmpp
+
+
+Now that you've got the basic gist of using SleekXMPP by following the
+echobot example (:ref:`echobot`), we can use one of the bundled plugins
+to create a very popular XMPP starter project: a `Multi-User Chat`_
+(MUC) bot. Our bot will login to an XMPP server, join an MUC chat room
+and "lurk" indefinitely, responding with a generic message to anyone
+that mentions its nickname. It will also greet members as they join the
+chat room.
+
+.. _`multi-user chat`: http://xmpp.org/extensions/xep-0045.html
+
+Joining The Room
+----------------
+
+As usual, our code will be based on the pattern explained in :ref:`echobot`.
+To start, we create an ``MUCBot`` class based on
+:class:`ClientXMPP <sleekxmpp.clientxmpp.ClientXMPP>` and which accepts
+parameters for the JID of the MUC room to join, and the nick that the
+bot will use inside the chat room. We also register an
+:term:`event handler` for the :term:`session_start` event.
+
+
+.. code-block:: python
+
+ import sleekxmpp
+
+ class MUCBot(sleekxmpp.ClientXMPP):
+
+ def __init__(self, jid, password, room, nick):
+ sleekxmpp.ClientXMPP.__init__(self, jid, password)
+
+ self.room = room
+ self.nick = nick
+
+ self.add_event_handler("session_start", self.start)
+
+After initialization, we also need to register the MUC (XEP-0045) plugin
+so that we can make use of the group chat plugin's methods and events.
+
+.. code-block:: python
+
+ xmpp.register_plugin('xep_0045')
+
+Finally, we can make our bot join the chat room once an XMPP session
+has been established:
+
+.. code-block:: python
+
+ def start(self, event):
+ self.get_roster()
+ self.send_presence()
+ self.plugin['xep_0045'].joinMUC(self.room,
+ self.nick,
+ wait=True)
+
+Note that as in :ref:`echobot`, we need to include send an initial presence and request
+the roster. Next, we want to join the group chat, so we call the
+``joinMUC`` method of the MUC plugin.
+
+.. note::
+
+ The :attr:`plugin <sleekxmpp.basexmpp.BaseXMPP.plugin>` attribute is
+ dictionary that maps to instances of plugins that we have previously
+ registered, by their names.
+
+
+Adding Functionality
+--------------------
+
+Currently, our bot just sits dormantly inside the chat room, but we
+would like it to respond to two distinct events by issuing a generic
+message in each case to the chat room. In particular, when a member
+mentions the bot's nickname inside the chat room, and when a member
+joins the chat room.
+
+Responding to Mentions
+~~~~~~~~~~~~~~~~~~~~~~
+
+Whenever a user mentions our bot's nickname in chat, our bot will
+respond with a generic message resembling *"I heard that, user."* We do
+this by examining all of the messages sent inside the chat and looking
+for the ones which contain the nickname string.
+
+First, we register an event handler for the :term:`groupchat_message`
+event inside the bot's ``__init__`` function.
+
+.. note::
+
+ We do not register a handler for the :term:`message` event in this
+ bot, but if we did, the group chat message would have been sent to
+ both handlers.
+
+.. code-block:: python
+
+ def __init__(self, jid, password, room, nick):
+ sleekxmpp.ClientXMPP.__init__(self, jid, password)
+
+ self.room = room
+ self.nick = nick
+
+ self.add_event_handler("session_start", self.start)
+ self.add_event_handler("groupchat_message", self.muc_message)
+
+Then, we can send our generic message whenever the bot's nickname gets
+mentioned.
+
+.. warning::
+
+ Always check that a message is not from yourself,
+ otherwise you will create an infinite loop responding
+ to your own messages.
+
+.. code-block:: python
+
+ def muc_message(self, msg):
+ if msg['mucnick'] != self.nick and self.nick in msg['body']:
+ self.send_message(mto=msg['from'].bare,
+ mbody="I heard that, %s." % msg['mucnick'],
+ mtype='groupchat')
+
+
+Greeting Members
+~~~~~~~~~~~~~~~~
+
+Now we want to greet member whenever they join the group chat. To
+do this we will use the dynamic ``muc::room@server::got_online`` [1]_
+event so it's a good idea to register an event handler for it.
+
+.. note::
+
+ The groupchat_presence event is triggered whenever a
+ presence stanza is received from any chat room, including
+ any presences you send yourself. To limit event handling
+ to a single room, use the events ``muc::room@server::presence``,
+ ``muc::room@server::got_online``, or ``muc::room@server::got_offline``.
+
+.. code-block:: python
+
+ def __init__(self, jid, password, room, nick):
+ sleekxmpp.ClientXMPP.__init__(self, jid, password)
+
+ self.room = room
+ self.nick = nick
+
+ self.add_event_handler("session_start", self.start)
+ self.add_event_handler("groupchat_message", self.muc_message)
+ self.add_event_handler("muc::%s::got_online" % self.room,
+ self.muc_online)
+
+Now all that's left to do is to greet them:
+
+.. code-block:: python
+
+ def muc_online(self, presence):
+ if presence['muc']['nick'] != self.nick:
+ self.send_message(mto=presence['from'].bare,
+ mbody="Hello, %s %s" % (presence['muc']['role'],
+ presence['muc']['nick']),
+ mtype='groupchat')
+
+.. [1] this is similar to the :term:`got_online` event and is sent by
+ the xep_0045 plugin whenever a member joins the referenced
+ MUC chat room.
+
+
+Final Product
+-------------
+
+.. compound::
+
+ The final step is to create a small runner script for initialising our ``MUCBot`` class and adding some
+ basic configuration options. By following the basic boilerplate pattern in :ref:`echobot`, we arrive
+ at the code below. To experiment with this example, you can use:
+
+ .. code-block:: sh
+
+ python muc.py -d -j jid@example.com -r room@muc.example.net -n lurkbot
+
+ which will prompt for the password, log in, and join the group chat. To test, open
+ your regular IM client and join the same group chat that you sent the bot to. You
+ will see ``lurkbot`` as one of the members in the group chat, and that it greeted
+ you upon entry. Send a message with the string "lurkbot" inside the body text, and you
+ will also see that it responds with our pre-programmed customized message.
+
+.. include:: ../../examples/muc.py
+ :literal: