SleekXMPP (Slixmpp) Server Component not receiving all MUC messages from ejabberd - xmpp

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

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.

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.

Related

How to get know, if the configuration is loaded

I am using akka http websocket client and would like to keep the client alive.
On the section Automatic keep-alive Ping support it says, to put the configuration into application.conf as the following:
akka.http.client.websocket.periodic-keep-alive-mode = pong
I've done as:
akka.http {
websocket {
# periodic keep alive may be implemented using by sending Ping frames
# upon which the other side is expected to reply with a Pong frame,
# or by sending a Pong frame, which serves as unidirectional heartbeat.
# Valid values:
# ping - default, for bi-directional ping/pong keep-alive heartbeating
# pong - for uni-directional pong keep-alive heartbeating
#
# See https://tools.ietf.org/html/rfc6455#section-5.5.2
# and https://tools.ietf.org/html/rfc6455#section-5.5.3 for more information
periodic-keep-alive-mode = ping
# Interval for sending periodic keep-alives
# The frame sent will be the onne configured in akka.http.server.websocket.periodic-keep-alive-mode
# `infinite` by default, or a duration that is the max idle interval after which an keep-alive frame should be sent
periodic-keep-alive-max-idle = infinite
}
}
How to figure out, if the configuration was taken or not?
I'm not sure I really understand your question, but you can show the complete configuration (including overrides etc.) when the actor system is loaded by setting akka.log-config-on-start to on.
Akka Docs on Logging the Configuration
related stackoverflow

ejabberd configuration - unknown listen option 'timeout' for 'ejabberd_c2s'

In Ejabberd 18, the parameter timeout under ejabberd_c2s in configuration seems like not working. When I checked the Log,
unknown listen option 'timeout' for 'ejabberd_c2s'
Now the problem I am facing is, the client connections are getting closed immediately.
Looking at https://docs.ejabberd.im/admin/configuration/#listening-ports right now I see that the ejabberd_c2s listener does not support any option named timeout.
See:
ejabberd_c2s: Handles c2s connections.
Options: access, certfile, ciphers, dhfile, protocol_options, max_fsm_queue, max_stanza_size, shaper, starttls, starttls_required, tls, zlib, tls_compression
Where did you read about such an option for that listener?

ejabberd register from specific ip's

I am trying to setup my ejabberd server to allow user registration from a specific ip adress. So far the only time I can register a user is when I change ip_access value to all. But thats not what I want.
Here is part of my config file:
...
acl:
...
loopback:
ip:
- "127.0.0.0/8"
- "xx.xx.xx.xx"
register_networks:
ip:
- "xx.xx.xx.xx"
...
access:
...
register:
all: allow
trusted_network:
loopback: allow
register_network:
register_networks: allow
...
registration_timeout: infinity
...
modules:
...
mod_register:
ip_access: register_network
access: register
...
Neither trusted_network or register_network work. I always get 403 Forbidden error. I am using ejabberd 16.01
you have defined register_networks: in acl but you referred to register_network as the ip_access value.
It might be the issue there.
Regards,

Configure mod_rest module for the ejabberd server

I am in the process of configuring the ejabber server for one of our project.In this we need to configure the mod_rest module (https://github.com/processone/ejabberd-contrib) from ejabberd-contrib. Below are my configuration (YAML)
in listen
port: 5280
module: ejabberd_http
request_handlers:
"/rest": mod_rest
web_admin: true
http_poll: true
http_bind: true
## register: true
captcha: true
modules:
mod_rest:
allowed_ips:
- "host_one_ip"
- "host_one_ip"
access_commands:
- "registered_users"
- "connected_users"
allowed_destinations:
- "all"
But whenever i am trying to hit the ejabberd command using the rest (curl call) its giving me "TryPOSTING Stanza"
prompt# curl --data 'registered_users domain' -X POST http://host:5280/rest/
Try POSTing a stanza.
I tried to go though the forum but couldn't find ...anything helpful
I am new to ejabber and erlang. Any pointer in this direction will be very helpful. Please let me know if any more details are required.
Guys i have figured out the issue for this. I have installed Ejabberd 14.05 version. The mod_rest module
was including the ejabberd_http.hrl file for its dev_include directories.In the Ejabberd 14.05 the record for ejabberd_http.hrl are changed. "opts = [] :: list()," is an extra header in the ejabber-contrib`s include folder. I adjusted the header location accordingly and compile the module. It worked for me :) with this i got the ejabberd commands working using the mod_rest.
Now my i facing problem to consumes Stanzas using mod_rest :(. If anyone have any thoughts on the same please let me know.
I try this, and worked:
In my case I use ejabberd binary installation, and the installation folder in
/lib/ejabberd/xxxx
Compile the mod_rest.erl from ejabberd-contrib, here is the reference, https://www.ejabberd.im/ejabberd-contrib
I compiled using this command :
erlc -I /lib/ejabberd/include your_mod_rest_source_file
if success, you will have .beam file, after that copy the mod_rest.beam to ejabberd installation folder
cp ~/ejabberd-contrib/mod_rest/src/mod_rest.beam /lib/ejabberd/ebin/
than configure ejabberd.yml in my case the yml reside in (/etc/ejabberd/ejabberd.yml) like this:
https://github.com/processone/ejabberd-contrib/issues/45#issuecomment-69767670
I think you misunderstand the purpose of the ReST module.
From the doc, you are supposed to send XMPP stanza to it:
https://github.com/processone/ejabberd-contrib/tree/master/mod_rest
However, you are sending plain text, not XMPP stanza (not even XML).

XMPP traffic logging (ejabberd 13.12)

It seems that mod_logxml module is not compatible with ejabberd 13.12 version. Ejabberd fails to start when this module is installed.
My question is - is there another way how to log (file, database, etc) all the XMPP packets send and received by ejabberd?
Yes, you can make your own log module if you cannot find anything that fits your needs.
You can use a module I developed as a reference. This module which would intercept stanza with the type "chat" or "groupchat" and send a acknowledgement back to the sender.
You can modify this module by removing the type so it intercepts all stanza types and log whatever you want into a DB instead of sending a message back to the sender.
https://github.com/Mingism/ejabberd-stanza-ack
I've changed mod_logxml.erl that it will work with eJabberd 13.12. You have to put in
ejabberd/src/
Configs are for ejabberd.yml format:
mod_logxml:
stanza: [message, other]
direction: [external]
orientation: [send, recv]
logdir: "/var/jabber/logs/"
timezone: universal
rotate_days: 1
rotate_megs: 100
rotate_kpackets: no
check_rotate_kpackets: 1
Repository