0
votes

we want to build a simple server component for ejabberd which receives all messages sent to MUC rooms (we have many rooms and new ones are being created all the time) and, after processing some of these messages, performs some operations.

We don't want our server component to act like a bot, so we don't want it to reply to messages or things like that, we just want it to receive copies of all messages in order to process some of them.

To do so, we have followed the tutorial available here: https://sleekxmpp.readthedocs.io/en/latest/getting_started/component.html

The problem is that the component seems to receive only some of the messages (approximately 1 out of 5).

Also, we are observing a weird behavior: message delivery seems to be "exclusive", meaning that a message is delivered either to clients connected to the room or to the server component, which is weird to be honest. In other words, 1 message out of 5 is delivered to the server component, and the other 4 are delivered to clients as usual.

Here's our component code (we have tried with both sleekxmpp and slixmpp but we always have the same behavior):

import sys

import logging

#import sleekxmpp

#from sleekxmpp.componentxmpp import ComponentXMPP

import slixmpp

from slixmpp.componentxmpp import ComponentXMPP



if sys.version_info < (3, 0):

        from sleekxmpp.util.misc_ops import setdefaultencoding

        setdefaultencoding('utf8')

else:

        raw_input = input



class NotificationsComponent(ComponentXMPP):



        def __init__(self):

                ComponentXMPP.__init__(self, "muc.ourservice.it", "secret", "jabber.ourservice.it", 5233)

                # add handler

                self.add_event_handler("message", self.message)

                #self.add_event_handler("groupchat_message", self.message)



        def message(self, msg):

                if msg['type'] == 'groupchat':

                        print('Received group chat message')

                        print(msg)

                        #msg.reply('Well received').send()

                else:

                        print('Received another message')



if __name__ == '__main__':



        logging.basicConfig(level=logging.DEBUG,format='%(levelname)-8s %(message)s')



        xmpp = NotificationsComponent()

        xmpp.register_plugin('xep_0030') # Service Discovery

        #xmpp.register_plugin('xep_0004') # Data Forms

        #xmpp.register_plugin('xep_0060') # PubSub

        xmpp.register_plugin('xep_0199') # XMPP Ping

        #xmpp.register_plugin('xep_0045') # MUC



        # Connect to the XMPP server and start processing XMPP stanzas.

        xmpp.connect()

        xmpp.process()

and here's a snippet of our ejabberd 18.03 configuration:

listen:

  - 

    port: 5222

    ip: "::"

    module: ejabberd_c2s

    starttls: true

    certfile: 'CERTFILE'

    protocol_options: 'TLSOPTS'

    ## dhfile: 'DHFILE'

    ## ciphers: 'CIPHERS'

    ##

    ## To enforce TLS encryption for client connections,

    ## use this instead of the "starttls" option:

    ##

    starttls_required: true

    ##

    ## Stream compression

    ##

    zlib: true

    ##

    max_stanza_size: 65536

    shaper: none

    access: c2s

  - 

    port: 5280

    ip: "::"

    module: ejabberd_http

    request_handlers:

      "/admin": ejabberd_web_admin

      "/bosh": mod_bosh

    #request_handlers:

    #  "/ws": ejabberd_http_ws

    #  "/bosh": mod_bosh

    #  "/api": mod_http_api

    ##  "/pub/archive": mod_http_fileserver

    web_admin: true

    http_bind: true

    ## register: true

    captcha: false

    certfile: 'CERTFILE'


    tls: true

  -

    port: 5233

    ip: "::"

    module: ejabberd_service

    access: all

    privilege_access:

      message: "outgoing"

    password: "secret"


    shaper: none

we have also tried to play with access, privilege_access and things like that but no luck.

Do you have any idea what might cause this weird behavior? Is there any particular plugin or module that should be enabled?

Of course, we have enabled debug logs on both sleekxmpp and ejabberd, but we don't see any errors, it's just that messages are missing.

We also did one more test. Even by using the official "echo component" example available in the slixmpp repository, we have the same issue. So it looks like there is some issue at our server, maybe on the message routing part, we don't know.

Thanks

2

2 Answers

1
votes

I think you mixed a couple of things here. The component you created here seems to connect to ejabber as External Component (see https://xmpp.org/extensions/xep-0114.html or https://xmpp.org/extensions/xep-0225.html) judging from http://sleekxmpp.com/getting_started/component.html which means that ejabber (seems to at least) routes some messages to it's internal component and some to your (external) component. This would explain why your component receives only certain messages.

You have two options:

  • use SleekXMPP but connect as regular user (you can use "bot" example and simply listen for messages without responding)
  • create dedicated component/handler within ejabberd that would receive all messages and process them accordingly.

Both options has pros and cons:

  • client-in-room - easier (for you, it seems) development, but require to be constantly connected and may loose some messages if connection is dropped
  • dedicated handler in ejabberd - most likely slightly more difficult to implement.
0
votes

It turns out I totally misunderstood the purpose of Jabber external components.

I was expecting to receive a "copy" of all events occurring within ejabberd, but I was wrong.

To achieve the result I was expecting, I'm using a module called "mod_post_log" which sends an HTTP request for every message sent by user. That works for me.