summaryrefslogtreecommitdiff
path: root/examples/mix.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/mix.py')
-rwxr-xr-xexamples/mix.py162
1 files changed, 162 insertions, 0 deletions
diff --git a/examples/mix.py b/examples/mix.py
new file mode 100755
index 00000000..1c3a34ae
--- /dev/null
+++ b/examples/mix.py
@@ -0,0 +1,162 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2021 Mathieu Pasquet
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+import logging
+from getpass import getpass
+from argparse import ArgumentParser
+
+import slixmpp
+
+
+class MIXBot(slixmpp.ClientXMPP):
+
+ """
+ A simple Slixmpp bot that will greets those
+ who enter the room, and acknowledge any messages
+ that mentions the bot's nickname.
+ """
+
+ def __init__(self, jid, password, room, nick):
+ slixmpp.ClientXMPP.__init__(self, jid, password)
+
+ self.room = room
+ self.rooms = set()
+ self.nick = nick
+
+ # The session_start event will be triggered when
+ # the bot establishes its connection with the server
+ # and the XML streams are ready for use. We want to
+ # listen for this event so that we we can initialize
+ # our roster.
+ self.add_event_handler("session_start", self.start)
+
+ # The mix_message event is triggered whenever a message
+ # stanza is received from any chat room.
+ self.add_event_handler("mix_message", self.mix_message)
+
+ # The mix_participant_info_publish event is triggered whenever
+ # an occupant joins or leaves the channel (not linked to
+ # actual presence)
+ self.add_event_handler("mix_participant_info_publish",
+ self.mix_joined)
+
+
+ async def start(self, event):
+ """
+ Process the session_start event.
+
+ Typical actions for the session_start event are
+ requesting the roster and broadcasting an initial
+ presence stanza.
+ """
+ # The goal here is to fetch the already joined MIX channels
+ # which are present in the roster.
+ _, mix_rooms = await self.plugin['xep_0405'].get_mix_roster()
+ for room in mix_rooms:
+ self.rooms.add(room['jid'])
+ self.send_presence()
+ if self.room not in self.rooms:
+ # If we are not joined, we need to. This will carry over
+ # the next restarts
+ await self.plugin['xep_0405'].join_channel(
+ self.room,
+ self.nick,
+ )
+
+ def mix_message(self, msg):
+ """
+ Process incoming message stanzas from any chat room. Be aware
+ that if you also have any handlers for the 'message' event,
+ message stanzas may be processed by both handlers, so check
+ the 'type' attribute when using a 'message' event handler.
+
+ Whenever the bot's nickname is mentioned, respond to
+ the message.
+
+ IMPORTANT: Always check that a message is not from yourself,
+ otherwise you will create an infinite loop responding
+ to your own messages.
+
+ This handler will reply to messages that mention
+ the bot's nickname.
+
+ Arguments:
+ msg -- The received message stanza. See the documentation
+ for stanza objects and the Message stanza to see
+ how it may be used.
+ """
+ if msg['mix']['nick'] != self.nick and self.nick in msg['body']:
+ self.send_message(mto=msg['from'].bare,
+ mbody="I heard that, %s." % msg['mix']['nick'],
+ mtype='groupchat')
+
+ def mix_joined(self, event):
+ """
+ We receive a publish event whenever someone joins the MIX channel.
+ It contains the nickname of the new participant, and the JID when
+ the channel is not a "JID Hidden channel".
+ """
+ participant = event['pubsub_event']['items']['item']['mix_participant']
+ if participant['nick'] != self.nick:
+ self.send_message(mto=event['from'].bare,
+ mbody="Hello, %s" % participant['nick'],
+ mtype='groupchat')
+
+
+if __name__ == '__main__':
+ # Setup the command line arguments.
+ parser = ArgumentParser()
+
+ # Output verbosity options.
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
+
+ # JID and password options.
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
+ parser.add_argument("-r", "--room", dest="room",
+ help="MIX channel to join")
+ parser.add_argument("-n", "--nick", dest="nick",
+ help="MIX nickname")
+
+ args = parser.parse_args()
+
+ # Setup logging.
+ logging.basicConfig(level=args.loglevel,
+ format='%(levelname)-8s %(message)s')
+
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
+ if args.room is None:
+ args.room = input("MIX channel: ")
+ if args.nick is None:
+ args.nick = input("MIX nickname: ")
+
+ # Setup the MIXBot and register plugins. Note that while plugins may
+ # have interdependencies, the order in which you register them does
+ # not matter.
+ xmpp = MIXBot(args.jid, args.password, args.room, args.nick)
+ xmpp.register_plugin('xep_0030') # Service Discovery
+ xmpp.register_plugin('xep_0199') # XMPP Ping
+ xmpp.register_plugin('xep_0369') # MIX Core
+ xmpp.register_plugin('xep_0405') # MIX PAM
+
+ # Connect to the XMPP server and start processing XMPP stanzas.
+ xmpp.connect()
+ xmpp.process()