This file is indexed.

/usr/share/doc/python-slixmpp-doc/html/getting_started/muc.html is in python-slixmpp-doc 1.2.2-1.1build2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>Mulit-User Chat (MUC) Bot &#8212; slixmpp</title>
    
    <link rel="stylesheet" href="../_static/haiku.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../',
        VERSION:     '1.1',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true,
        SOURCELINK_SUFFIX: '.txt'
      };
    </script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="next" title="Enable HTTP Proxy Support" href="proxy.html" />
    <link rel="prev" title="Manage Presence Subscriptions" href="presence.html" /> 
  </head>
  <body role="document">
      <div class="header" role="banner"><h1 class="heading"><a href="../index.html">
          <span>1.1 Documentation</span></a></h1>
        <h2 class="heading"><span>Mulit-User Chat (MUC) Bot</span></h2>
      </div>
      <div class="topnav" role="navigation" aria-label="top navigation">
      
        <p>
        «&#160;&#160;<a href="presence.html">Manage Presence Subscriptions</a>
        &#160;&#160;::&#160;&#160;
        <a class="uplink" href="../index.html">Contents</a>
        &#160;&#160;::&#160;&#160;
        <a href="proxy.html">Enable HTTP Proxy Support</a>&#160;&#160;»
        </p>

      </div>
      <div class="content">
        
        
  <div class="section" id="mulit-user-chat-muc-bot">
<span id="mucbot"></span><h1>Mulit-User Chat (MUC) Bot<a class="headerlink" href="#mulit-user-chat-muc-bot" title="Permalink to this headline"></a></h1>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you have any issues working through this quickstart guide
join the chat room at <a class="reference external" href="xmpp:slixmpp&#64;muc.poez.io?join">slixmpp&#64;muc.poez.io</a>.</p>
</div>
<p>If you have not yet installed Slixmpp, do so now by either checking out a version
from <a class="reference external" href="http://git.poez.io/slixmpp">Git</a>.</p>
<p>Now that you&#8217;ve got the basic gist of using Slixmpp by following the
echobot example (<a class="reference internal" href="echobot.html#echobot"><span class="std std-ref">Slixmpp Quickstart - Echo Bot</span></a>), we can use one of the bundled plugins
to create a very popular XMPP starter project: a <a class="reference external" href="http://xmpp.org/extensions/xep-0045.html">Multi-User Chat</a>
(MUC) bot. Our bot will login to an XMPP server, join an MUC chat room
and &#8220;lurk&#8221; indefinitely, responding with a generic message to anyone
that mentions its nickname. It will also greet members as they join the
chat room.</p>
<div class="section" id="joining-the-room">
<h2>Joining The Room<a class="headerlink" href="#joining-the-room" title="Permalink to this headline"></a></h2>
<p>As usual, our code will be based on the pattern explained in <a class="reference internal" href="echobot.html#echobot"><span class="std std-ref">Slixmpp Quickstart - Echo Bot</span></a>.
To start, we create an <code class="docutils literal"><span class="pre">MUCBot</span></code> class based on
<a class="reference internal" href="../api/clientxmpp.html#slixmpp.clientxmpp.ClientXMPP" title="slixmpp.clientxmpp.ClientXMPP"><code class="xref py py-class docutils literal"><span class="pre">ClientXMPP</span></code></a> 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
<a class="reference internal" href="../glossary.html#term-event-handler"><span class="xref std std-term">event handler</span></a> for the <a class="reference internal" href="../event_index.html#term-session-start"><span class="xref std std-term">session_start</span></a> event.</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">slixmpp</span>

<span class="k">class</span> <span class="nc">MUCBot</span><span class="p">(</span><span class="n">slixmpp</span><span class="o">.</span><span class="n">ClientXMPP</span><span class="p">):</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">jid</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">room</span><span class="p">,</span> <span class="n">nick</span><span class="p">):</span>
        <span class="n">slixmpp</span><span class="o">.</span><span class="n">ClientXMPP</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">jid</span><span class="p">,</span> <span class="n">password</span><span class="p">)</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">room</span> <span class="o">=</span> <span class="n">room</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">nick</span> <span class="o">=</span> <span class="n">nick</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">add_event_handler</span><span class="p">(</span><span class="s2">&quot;session_start&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">start</span><span class="p">)</span>
</pre></div>
</div>
<p>After initialization, we also need to register the MUC (XEP-0045) plugin
so that we can make use of the group chat plugin&#8217;s methods and events.</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">xmpp</span><span class="o">.</span><span class="n">register_plugin</span><span class="p">(</span><span class="s1">&#39;xep_0045&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>Finally, we can make our bot join the chat room once an XMPP session
has been established:</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">event</span><span class="p">):</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">get_roster</span><span class="p">()</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">send_presence</span><span class="p">()</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">plugin</span><span class="p">[</span><span class="s1">&#39;xep_0045&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">join_muc</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">room</span><span class="p">,</span>
                                     <span class="bp">self</span><span class="o">.</span><span class="n">nick</span><span class="p">,</span>
                                     <span class="n">wait</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
</pre></div>
</div>
<p>Note that as in <a class="reference internal" href="echobot.html#echobot"><span class="std std-ref">Slixmpp Quickstart - Echo Bot</span></a>, we need to include send an initial presence and request
the roster. Next, we want to join the group chat, so we call the
<code class="docutils literal"><span class="pre">join_muc</span></code> method of the MUC plugin.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The <a class="reference internal" href="../api/basexmpp.html#slixmpp.basexmpp.BaseXMPP.plugin" title="slixmpp.basexmpp.BaseXMPP.plugin"><code class="xref py py-attr docutils literal"><span class="pre">plugin</span></code></a> attribute is
dictionary that maps to instances of plugins that we have previously
registered, by their names.</p>
</div>
</div>
<div class="section" id="adding-functionality">
<h2>Adding Functionality<a class="headerlink" href="#adding-functionality" title="Permalink to this headline"></a></h2>
<p>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&#8217;s nickname inside the chat room, and when a member
joins the chat room.</p>
<div class="section" id="responding-to-mentions">
<h3>Responding to Mentions<a class="headerlink" href="#responding-to-mentions" title="Permalink to this headline"></a></h3>
<p>Whenever a user mentions our bot&#8217;s nickname in chat, our bot will
respond with a generic message resembling <em>&#8220;I heard that, user.&#8221;</em> We do
this by examining all of the messages sent inside the chat and looking
for the ones which contain the nickname string.</p>
<p>First, we register an event handler for the <a class="reference internal" href="../event_index.html#term-groupchat-message"><span class="xref std std-term">groupchat_message</span></a>
event inside the bot&#8217;s <code class="docutils literal"><span class="pre">__init__</span></code> function.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">We do not register a handler for the <a class="reference internal" href="../event_index.html#term-message"><span class="xref std std-term">message</span></a> event in this
bot, but if we did, the group chat message would have been sent to
both handlers.</p>
</div>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">jid</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">room</span><span class="p">,</span> <span class="n">nick</span><span class="p">):</span>
    <span class="n">slixmpp</span><span class="o">.</span><span class="n">ClientXMPP</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">jid</span><span class="p">,</span> <span class="n">password</span><span class="p">)</span>

    <span class="bp">self</span><span class="o">.</span><span class="n">room</span> <span class="o">=</span> <span class="n">room</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">nick</span> <span class="o">=</span> <span class="n">nick</span>

    <span class="bp">self</span><span class="o">.</span><span class="n">add_event_handler</span><span class="p">(</span><span class="s2">&quot;session_start&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">start</span><span class="p">)</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">add_event_handler</span><span class="p">(</span><span class="s2">&quot;groupchat_message&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">muc_message</span><span class="p">)</span>
</pre></div>
</div>
<p>Then, we can send our generic message whenever the bot&#8217;s nickname gets
mentioned.</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">Always check that a message is not from yourself,
otherwise you will create an infinite loop responding
to your own messages.</p>
</div>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">muc_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">msg</span><span class="p">[</span><span class="s1">&#39;mucnick&#39;</span><span class="p">]</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">nick</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">nick</span> <span class="ow">in</span> <span class="n">msg</span><span class="p">[</span><span class="s1">&#39;body&#39;</span><span class="p">]:</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">send_message</span><span class="p">(</span><span class="n">mto</span><span class="o">=</span><span class="n">msg</span><span class="p">[</span><span class="s1">&#39;from&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">bare</span><span class="p">,</span>
                          <span class="n">mbody</span><span class="o">=</span><span class="s2">&quot;I heard that, </span><span class="si">%s</span><span class="s2">.&quot;</span> <span class="o">%</span> <span class="n">msg</span><span class="p">[</span><span class="s1">&#39;mucnick&#39;</span><span class="p">],</span>
                          <span class="n">mtype</span><span class="o">=</span><span class="s1">&#39;groupchat&#39;</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="greeting-members">
<h3>Greeting Members<a class="headerlink" href="#greeting-members" title="Permalink to this headline"></a></h3>
<p>Now we want to greet member whenever they join the group chat. To
do this we will use the dynamic <code class="docutils literal"><span class="pre">muc::room&#64;server::got_online</span></code> <a class="footnote-reference" href="#id2" id="id1">[1]</a>
event so it&#8217;s a good idea to register an event handler for it.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">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 <code class="docutils literal"><span class="pre">muc::room&#64;server::presence</span></code>,
<code class="docutils literal"><span class="pre">muc::room&#64;server::got_online</span></code>, or <code class="docutils literal"><span class="pre">muc::room&#64;server::got_offline</span></code>.</p>
</div>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">jid</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">room</span><span class="p">,</span> <span class="n">nick</span><span class="p">):</span>
    <span class="n">slixmpp</span><span class="o">.</span><span class="n">ClientXMPP</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">jid</span><span class="p">,</span> <span class="n">password</span><span class="p">)</span>

    <span class="bp">self</span><span class="o">.</span><span class="n">room</span> <span class="o">=</span> <span class="n">room</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">nick</span> <span class="o">=</span> <span class="n">nick</span>

    <span class="bp">self</span><span class="o">.</span><span class="n">add_event_handler</span><span class="p">(</span><span class="s2">&quot;session_start&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">start</span><span class="p">)</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">add_event_handler</span><span class="p">(</span><span class="s2">&quot;groupchat_message&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">muc_message</span><span class="p">)</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">add_event_handler</span><span class="p">(</span><span class="s2">&quot;muc::</span><span class="si">%s</span><span class="s2">::got_online&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">room</span><span class="p">,</span>
                           <span class="bp">self</span><span class="o">.</span><span class="n">muc_online</span><span class="p">)</span>
</pre></div>
</div>
<p>Now all that&#8217;s left to do is to greet them:</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">muc_online</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">presence</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">presence</span><span class="p">[</span><span class="s1">&#39;muc&#39;</span><span class="p">][</span><span class="s1">&#39;nick&#39;</span><span class="p">]</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">nick</span><span class="p">:</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">send_message</span><span class="p">(</span><span class="n">mto</span><span class="o">=</span><span class="n">presence</span><span class="p">[</span><span class="s1">&#39;from&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">bare</span><span class="p">,</span>
                          <span class="n">mbody</span><span class="o">=</span><span class="s2">&quot;Hello, </span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">presence</span><span class="p">[</span><span class="s1">&#39;muc&#39;</span><span class="p">][</span><span class="s1">&#39;role&#39;</span><span class="p">],</span>
                                                  <span class="n">presence</span><span class="p">[</span><span class="s1">&#39;muc&#39;</span><span class="p">][</span><span class="s1">&#39;nick&#39;</span><span class="p">]),</span>
                          <span class="n">mtype</span><span class="o">=</span><span class="s1">&#39;groupchat&#39;</span><span class="p">)</span>
</pre></div>
</div>
<table class="docutils footnote" frame="void" id="id2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>this is similar to the <a class="reference internal" href="../event_index.html#term-got-online"><span class="xref std std-term">got_online</span></a> event and is sent by
the xep_0045 plugin whenever a member joins the referenced
MUC chat room.</td></tr>
</tbody>
</table>
</div>
</div>
<div class="section" id="final-product">
<h2>Final Product<a class="headerlink" href="#final-product" title="Permalink to this headline"></a></h2>
<div class="compound">
<p class="compound-first">The final step is to create a small runner script for initialising our <code class="docutils literal"><span class="pre">MUCBot</span></code> class and adding some
basic configuration options. By following the basic boilerplate pattern in <a class="reference internal" href="echobot.html#echobot"><span class="std std-ref">Slixmpp Quickstart - Echo Bot</span></a>, we arrive
at the code below. To experiment with this example, you can use:</p>
<div class="compound-middle highlight-sh"><div class="highlight"><pre><span></span>python muc.py -d -j jid@example.com -r room@muc.example.net -n lurkbot
</pre></div>
</div>
<p class="compound-last">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 <code class="docutils literal"><span class="pre">lurkbot</span></code> as one of the members in the group chat, and that it greeted
you upon entry. Send a message with the string &#8220;lurkbot&#8221; inside the body text, and you
will also see that it responds with our pre-programmed customized message.</p>
</div>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/env python3</span>
<span class="c1"># -*- coding: utf-8 -*-</span>

<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Slixmpp: The Slick XMPP Library</span>
<span class="sd">    Copyright (C) 2010  Nathanael C. Fritz</span>
<span class="sd">    This file is part of Slixmpp.</span>

<span class="sd">    See the file LICENSE for copying permission.</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">import</span> <span class="nn">logging</span>
<span class="kn">from</span> <span class="nn">getpass</span> <span class="k">import</span> <span class="n">getpass</span>
<span class="kn">from</span> <span class="nn">argparse</span> <span class="k">import</span> <span class="n">ArgumentParser</span>

<span class="kn">import</span> <span class="nn">slixmpp</span>


<span class="k">class</span> <span class="nc">MUCBot</span><span class="p">(</span><span class="n">slixmpp</span><span class="o">.</span><span class="n">ClientXMPP</span><span class="p">):</span>

    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A simple Slixmpp bot that will greets those</span>
<span class="sd">    who enter the room, and acknowledge any messages</span>
<span class="sd">    that mentions the bot&#39;s nickname.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">jid</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">room</span><span class="p">,</span> <span class="n">nick</span><span class="p">):</span>
        <span class="n">slixmpp</span><span class="o">.</span><span class="n">ClientXMPP</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">jid</span><span class="p">,</span> <span class="n">password</span><span class="p">)</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">room</span> <span class="o">=</span> <span class="n">room</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">nick</span> <span class="o">=</span> <span class="n">nick</span>

        <span class="c1"># The session_start event will be triggered when</span>
        <span class="c1"># the bot establishes its connection with the server</span>
        <span class="c1"># and the XML streams are ready for use. We want to</span>
        <span class="c1"># listen for this event so that we we can initialize</span>
        <span class="c1"># our roster.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">add_event_handler</span><span class="p">(</span><span class="s2">&quot;session_start&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">start</span><span class="p">)</span>

        <span class="c1"># The groupchat_message event is triggered whenever a message</span>
        <span class="c1"># stanza is received from any chat room. If you also also</span>
        <span class="c1"># register a handler for the &#39;message&#39; event, MUC messages</span>
        <span class="c1"># will be processed by both handlers.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">add_event_handler</span><span class="p">(</span><span class="s2">&quot;groupchat_message&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">muc_message</span><span class="p">)</span>

        <span class="c1"># The groupchat_presence event is triggered whenever a</span>
        <span class="c1"># presence stanza is received from any chat room, including</span>
        <span class="c1"># any presences you send yourself. To limit event handling</span>
        <span class="c1"># to a single room, use the events muc::room@server::presence,</span>
        <span class="c1"># muc::room@server::got_online, or muc::room@server::got_offline.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">add_event_handler</span><span class="p">(</span><span class="s2">&quot;muc::</span><span class="si">%s</span><span class="s2">::got_online&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">room</span><span class="p">,</span>
                               <span class="bp">self</span><span class="o">.</span><span class="n">muc_online</span><span class="p">)</span>


    <span class="k">def</span> <span class="nf">start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">event</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Process the session_start event.</span>

<span class="sd">        Typical actions for the session_start event are</span>
<span class="sd">        requesting the roster and broadcasting an initial</span>
<span class="sd">        presence stanza.</span>

<span class="sd">        Arguments:</span>
<span class="sd">            event -- An empty dictionary. The session_start</span>
<span class="sd">                     event does not provide any additional</span>
<span class="sd">                     data.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">get_roster</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">send_presence</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">plugin</span><span class="p">[</span><span class="s1">&#39;xep_0045&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">join_muc</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">room</span><span class="p">,</span>
                                         <span class="bp">self</span><span class="o">.</span><span class="n">nick</span><span class="p">,</span>
                                         <span class="c1"># If a room password is needed, use:</span>
                                         <span class="c1"># password=the_room_password,</span>
                                         <span class="n">wait</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">muc_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Process incoming message stanzas from any chat room. Be aware</span>
<span class="sd">        that if you also have any handlers for the &#39;message&#39; event,</span>
<span class="sd">        message stanzas may be processed by both handlers, so check</span>
<span class="sd">        the &#39;type&#39; attribute when using a &#39;message&#39; event handler.</span>

<span class="sd">        Whenever the bot&#39;s nickname is mentioned, respond to</span>
<span class="sd">        the message.</span>

<span class="sd">        IMPORTANT: Always check that a message is not from yourself,</span>
<span class="sd">                   otherwise you will create an infinite loop responding</span>
<span class="sd">                   to your own messages.</span>

<span class="sd">        This handler will reply to messages that mention</span>
<span class="sd">        the bot&#39;s nickname.</span>

<span class="sd">        Arguments:</span>
<span class="sd">            msg -- The received message stanza. See the documentation</span>
<span class="sd">                   for stanza objects and the Message stanza to see</span>
<span class="sd">                   how it may be used.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="n">msg</span><span class="p">[</span><span class="s1">&#39;mucnick&#39;</span><span class="p">]</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">nick</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">nick</span> <span class="ow">in</span> <span class="n">msg</span><span class="p">[</span><span class="s1">&#39;body&#39;</span><span class="p">]:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">send_message</span><span class="p">(</span><span class="n">mto</span><span class="o">=</span><span class="n">msg</span><span class="p">[</span><span class="s1">&#39;from&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">bare</span><span class="p">,</span>
                              <span class="n">mbody</span><span class="o">=</span><span class="s2">&quot;I heard that, </span><span class="si">%s</span><span class="s2">.&quot;</span> <span class="o">%</span> <span class="n">msg</span><span class="p">[</span><span class="s1">&#39;mucnick&#39;</span><span class="p">],</span>
                              <span class="n">mtype</span><span class="o">=</span><span class="s1">&#39;groupchat&#39;</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">muc_online</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">presence</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Process a presence stanza from a chat room. In this case,</span>
<span class="sd">        presences from users that have just come online are</span>
<span class="sd">        handled by sending a welcome message that includes</span>
<span class="sd">        the user&#39;s nickname and role in the room.</span>

<span class="sd">        Arguments:</span>
<span class="sd">            presence -- The received presence stanza. See the</span>
<span class="sd">                        documentation for the Presence stanza</span>
<span class="sd">                        to see how else it may be used.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="n">presence</span><span class="p">[</span><span class="s1">&#39;muc&#39;</span><span class="p">][</span><span class="s1">&#39;nick&#39;</span><span class="p">]</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">nick</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">send_message</span><span class="p">(</span><span class="n">mto</span><span class="o">=</span><span class="n">presence</span><span class="p">[</span><span class="s1">&#39;from&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">bare</span><span class="p">,</span>
                              <span class="n">mbody</span><span class="o">=</span><span class="s2">&quot;Hello, </span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">presence</span><span class="p">[</span><span class="s1">&#39;muc&#39;</span><span class="p">][</span><span class="s1">&#39;role&#39;</span><span class="p">],</span>
                                                      <span class="n">presence</span><span class="p">[</span><span class="s1">&#39;muc&#39;</span><span class="p">][</span><span class="s1">&#39;nick&#39;</span><span class="p">]),</span>
                              <span class="n">mtype</span><span class="o">=</span><span class="s1">&#39;groupchat&#39;</span><span class="p">)</span>


<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="c1"># Setup the command line arguments.</span>
    <span class="n">parser</span> <span class="o">=</span> <span class="n">ArgumentParser</span><span class="p">()</span>

    <span class="c1"># Output verbosity options.</span>
    <span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-q&quot;</span><span class="p">,</span> <span class="s2">&quot;--quiet&quot;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s2">&quot;set logging to ERROR&quot;</span><span class="p">,</span>
                        <span class="n">action</span><span class="o">=</span><span class="s2">&quot;store_const&quot;</span><span class="p">,</span> <span class="n">dest</span><span class="o">=</span><span class="s2">&quot;loglevel&quot;</span><span class="p">,</span>
                        <span class="n">const</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">ERROR</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span>
    <span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-d&quot;</span><span class="p">,</span> <span class="s2">&quot;--debug&quot;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s2">&quot;set logging to DEBUG&quot;</span><span class="p">,</span>
                        <span class="n">action</span><span class="o">=</span><span class="s2">&quot;store_const&quot;</span><span class="p">,</span> <span class="n">dest</span><span class="o">=</span><span class="s2">&quot;loglevel&quot;</span><span class="p">,</span>
                        <span class="n">const</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span>

    <span class="c1"># JID and password options.</span>
    <span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-j&quot;</span><span class="p">,</span> <span class="s2">&quot;--jid&quot;</span><span class="p">,</span> <span class="n">dest</span><span class="o">=</span><span class="s2">&quot;jid&quot;</span><span class="p">,</span>
                        <span class="n">help</span><span class="o">=</span><span class="s2">&quot;JID to use&quot;</span><span class="p">)</span>
    <span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-p&quot;</span><span class="p">,</span> <span class="s2">&quot;--password&quot;</span><span class="p">,</span> <span class="n">dest</span><span class="o">=</span><span class="s2">&quot;password&quot;</span><span class="p">,</span>
                        <span class="n">help</span><span class="o">=</span><span class="s2">&quot;password to use&quot;</span><span class="p">)</span>
    <span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-r&quot;</span><span class="p">,</span> <span class="s2">&quot;--room&quot;</span><span class="p">,</span> <span class="n">dest</span><span class="o">=</span><span class="s2">&quot;room&quot;</span><span class="p">,</span>
                        <span class="n">help</span><span class="o">=</span><span class="s2">&quot;MUC room to join&quot;</span><span class="p">)</span>
    <span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-n&quot;</span><span class="p">,</span> <span class="s2">&quot;--nick&quot;</span><span class="p">,</span> <span class="n">dest</span><span class="o">=</span><span class="s2">&quot;nick&quot;</span><span class="p">,</span>
                        <span class="n">help</span><span class="o">=</span><span class="s2">&quot;MUC nickname&quot;</span><span class="p">)</span>

    <span class="n">args</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span>

    <span class="c1"># Setup logging.</span>
    <span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span><span class="n">level</span><span class="o">=</span><span class="n">args</span><span class="o">.</span><span class="n">loglevel</span><span class="p">,</span>
                        <span class="nb">format</span><span class="o">=</span><span class="s1">&#39;</span><span class="si">%(levelname)-8s</span><span class="s1"> </span><span class="si">%(message)s</span><span class="s1">&#39;</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">jid</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">args</span><span class="o">.</span><span class="n">jid</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">&quot;Username: &quot;</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">password</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">args</span><span class="o">.</span><span class="n">password</span> <span class="o">=</span> <span class="n">getpass</span><span class="p">(</span><span class="s2">&quot;Password: &quot;</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">room</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">args</span><span class="o">.</span><span class="n">room</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">&quot;MUC room: &quot;</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">nick</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">args</span><span class="o">.</span><span class="n">nick</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">&quot;MUC nickname: &quot;</span><span class="p">)</span>

    <span class="c1"># Setup the MUCBot and register plugins. Note that while plugins may</span>
    <span class="c1"># have interdependencies, the order in which you register them does</span>
    <span class="c1"># not matter.</span>
    <span class="n">xmpp</span> <span class="o">=</span> <span class="n">MUCBot</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">jid</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">password</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">room</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">nick</span><span class="p">)</span>
    <span class="n">xmpp</span><span class="o">.</span><span class="n">register_plugin</span><span class="p">(</span><span class="s1">&#39;xep_0030&#39;</span><span class="p">)</span> <span class="c1"># Service Discovery</span>
    <span class="n">xmpp</span><span class="o">.</span><span class="n">register_plugin</span><span class="p">(</span><span class="s1">&#39;xep_0045&#39;</span><span class="p">)</span> <span class="c1"># Multi-User Chat</span>
    <span class="n">xmpp</span><span class="o">.</span><span class="n">register_plugin</span><span class="p">(</span><span class="s1">&#39;xep_0199&#39;</span><span class="p">)</span> <span class="c1"># XMPP Ping</span>

    <span class="c1"># Connect to the XMPP server and start processing XMPP stanzas.</span>
    <span class="n">xmpp</span><span class="o">.</span><span class="n">connect</span><span class="p">()</span>
    <span class="n">xmpp</span><span class="o">.</span><span class="n">process</span><span class="p">()</span>
</pre></div>
</div>
</div>
</div>


      </div>
      <div class="bottomnav" role="navigation" aria-label="bottom navigation">
      
        <p>
        «&#160;&#160;<a href="presence.html">Manage Presence Subscriptions</a>
        &#160;&#160;::&#160;&#160;
        <a class="uplink" href="../index.html">Contents</a>
        &#160;&#160;::&#160;&#160;
        <a href="proxy.html">Enable HTTP Proxy Support</a>&#160;&#160;»
        </p>

      </div>

    <div class="footer" role="contentinfo">
        &#169; Copyright 2017, Nathan Fritz, Lance Stout.
      Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.5.6.
    </div>
  </body>
</html>