Giter Club home page Giter Club logo

openfire-pushnotification-plugin's Introduction

Build Status

The Push Notification Plugin is a plugin for the Openfire XMPP server, which adds support sending push notifications to client software, as described in XEP-0357: "Push Notifications".

Building

This project is using the Maven-based Openfire build process, as introduced in Openfire 4.2.0. To build this plugin locally, ensure that the following are available on your local host:

  • A Java Development Kit, version 7 or (preferably) 8
  • Apache Maven 3

To build this project, invoke on a command shell:

$ mvn clean package

Upon completion, the openfire plugin will be available in target/pushnotification-openfire-plugin-assembly.jar. This file should be renamed to pushnotification.jar

Installation

Copy pushnotification.jar into the plugins directory of your Openfire server, or use the Openfire Admin Console to upload the plugin. The plugin will then be automatically deployed.

To upgrade to a new version, copy the new pushnotification.jar file over the existing file.

openfire-pushnotification-plugin's People

Contributors

akrherz avatar fishbowler avatar guusdk avatar transifex-integration[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openfire-pushnotification-plugin's Issues

AbstractMethodError with version 0.8.0 on Openfire 4.7.0-SNAPSHOT.

Observed on Ignite, which was running version 0.8.0 of this plugin on a SNAPSHOT build of Openfire 4.7.0 at the time.

java.util.concurrent.ExecutionException: java.lang.AbstractMethodError: org.igniterealtime.openfire.plugins.pushnotification.PushInterceptor.messageStored(Lorg/jivesoftware/openfire/OfflineMessage;)V
        at java.util.concurrent.FutureTask.report(FutureTask.java:122) ~[?:1.8.0_302]
        at java.util.concurrent.FutureTask.get(FutureTask.java:192) ~[?:1.8.0_302]
        at org.jivesoftware.openfire.plugin.DemoPlugin.lambda$sendMessageToAdmins$1(DemoPlugin.java:62) ~[demo-1.0.0-SNAPSHOT.jar!/:?]
        at java.util.ArrayList.forEach(ArrayList.java:1259) [?:1.8.0_302]
        at org.jivesoftware.openfire.plugin.DemoPlugin.sendMessageToAdmins(DemoPlugin.java:48) [demo-1.0.0-SNAPSHOT.jar!/:?]
        at org.jivesoftware.openfire.plugin.DemoPlugin.initializePlugin(DemoPlugin.java:32) [demo-1.0.0-SNAPSHOT.jar!/:?]
        at org.jivesoftware.openfire.container.PluginManager.loadPlugin(PluginManager.java:659) [xmppserver-4.7.0-SNAPSHOT.jar:4.7.0-SNAPSHOT]
        at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask$4.call(PluginMonitor.java:375) [xmppserver-4.7.0-SNAPSHOT.jar:4.7.0-SNAPSHOT]
        at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask$4.call(PluginMonitor.java:363) [xmppserver-4.7.0-SNAPSHOT.jar:4.7.0-SNAPSHOT]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_302]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_302]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_302]
        at java.lang.Thread.run(Thread.java:748) [?:1.8.0_302]
Caused by: java.lang.AbstractMethodError: org.igniterealtime.openfire.plugins.pushnotification.PushInterceptor.messageStored(Lorg/jivesoftware/openfire/OfflineMessage;)V
        at org.jivesoftware.openfire.OfflineMessageStrategy.store(OfflineMessageStrategy.java:196) ~[xmppserver-4.7.0-SNAPSHOT.jar:4.7.0-SNAPSHOT]
        at org.jivesoftware.openfire.OfflineMessageStrategy.storeOffline(OfflineMessageStrategy.java:144) ~[xmppserver-4.7.0-SNAPSHOT.jar:4.7.0-SNAPSHOT]
        at org.jivesoftware.openfire.MessageRouter.routingFailed(MessageRouter.java:268) ~[xmppserver-4.7.0-SNAPSHOT.jar:4.7.0-SNAPSHOT]
        at org.jivesoftware.openfire.spi.RoutingTableImpl.routePacket(RoutingTableImpl.java:378) ~[xmppserver-4.7.0-SNAPSHOT.jar:4.7.0-SNAPSHOT]
        at org.jivesoftware.openfire.MessageRouter.route(MessageRouter.java:134) ~[xmppserver-4.7.0-SNAPSHOT.jar:4.7.0-SNAPSHOT]
        at org.jivesoftware.openfire.plugin.DemoPlugin.lambda$sendMessageToAdmins$0(DemoPlugin.java:57) ~[demo-1.0.0-SNAPSHOT.jar!/:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_302]
        ... 4 more

Trigger push notifications for other data than messages

Currently, push notifications are only sent when processing message stanzas that have a non-empty body. This is not covering all use-cases where it's desirable to have a push notification. For example, when a device is the intended target of an audio/video call, then a push notification is desirable.

Prosody and eJabberd follow the business rules summed up here: https://hg.prosody.im/prosody-modules/file/tip/mod_cloud_notify/business_rules.markdown

Openfire should take inspiration from these business rules.

Add content to push notifications that allow them to wake up an IOS app

As explained in https://github.com/anurodhp/Monal/issues/354#issuecomment-614556811:

iOS is a special plattform and apps can not be woken up in the brackground by normal (silent) pushes.
Because of this an informal standard emerged which is not codified in the push xep:
The push has to be a push summary and the last-message-body field has to be set for pushes that were triggered by a message stanza containing a body (or was e2e encrypted!).
This way the push server can generate a non-silent push containing a general "New Message" which finally will start the app when the user opens the notification.

Example from prosody:

<iq id="id-1" type="set" from="xmpp.eightysoft.de" to="ios13push.monal.im">
   <pubsub xmlns="http://jabber.org/protocol/pubsub">
      <publish node="NODE">
         <item>
            <notification xmlns="urn:xmpp:push:0">
               <x xmlns="jabber:x:data" type="form">
                  <field var="FORM_TYPE" type="hidden">
                     <value>urn:xmpp:push:summary</value>
                  </field>
                  <field var="message-count" type="text-single">
                     <value>1</value>
                  </field>
                  <field var="pending-subscription-count" type="text-single" />
                  <field var="last-message-sender" type="jid-single" />
                  <field var="last-message-body" type="text-single">
                     <value>Neue Nachricht</value>
                  </field>
               </x>
            </notification>
         </item>
      </publish>
      <publish-options>
         <x xmlns="jabber:x:data" type="submit">
            <field var="FORM_TYPE">
               <value>http://jabber.org/protocol/pubsub#publish-options</value>
            </field>
            <field var="secret">
               <value>SECRET</value>
            </field>
         </x>
      </publish-options>
   </pubsub>
</iq>

Unable to send push notification on android

Below log is showing in Openfire error log-

2020.05.06 21:40:56 ERROR [socket_c2s-thread-4]: org.jivesoftware.openfire.spi.RoutingTableImpl - Primary packet routing failed
org.jivesoftware.openfire.PacketException: Cannot route packet of type IQ or Presence to bare JID:

<iq type="set" id="319-60639" to="[email protected]" from="domain.com"><pubsub xmlns="http://jabber.org/protocol/pubsub"><publish node="[email protected]"><item><notification xmlns="urn:xmpp:push:0"><x xmlns="jabber:x:data" type="form"><field var="FORM_TYPE" type="hidden"><value>urn:xmpp:push:summary</value></field><field var="message-count" type="text-single"><value>1</value></field><field var="last-message-sender" type="text-single"/><field var="last-message-body" type="text-single"><value>New Message</value></field></x></notification></item></publish><publish-options><x xmlns="jabber:x:data" type="submit"><field var="FORM_TYPE"><value>http://jabber.org/protocol/pubsub#publish-options</value></field><field var="secret"><value>eruio234vzxc2kla-91</value></field></x></publish-options></pubsub></iq>

at org.jivesoftware.openfire.spi.RoutingTableImpl.routeToLocalDomain(RoutingTableImpl.java:306) ~[xmppserver-4.5.1.jar:4.5.1]
at org.jivesoftware.openfire.spi.RoutingTableImpl.routePacket(RoutingTableImpl.java:239) [xmppserver-4.5.1.jar:4.5.1]
at org.igniterealtime.openfire.plugins.pushnotification.PushInterceptor.tryPushNotification(PushInterceptor.java:208) [pushnotification-0.7.0.jar!/:?]
at org.igniterealtime.openfire.plugins.pushnotification.PushInterceptor.interceptPacket(PushInterceptor.java:121) [pushnotification-0.7.0.jar!/:?]
at org.jivesoftware.openfire.interceptor.InterceptorManager.invokeInterceptors(InterceptorManager.java:268) [xmppserver-4.5.1.jar:4.5.1]
at org.jivesoftware.openfire.interceptor.InterceptorManager.invokeInterceptors(InterceptorManager.java:230) [xmppserver-4.5.1.jar:4.5.1]
at org.jivesoftware.openfire.session.LocalSession.process(LocalSession.java:397) [xmppserver-4.5.1.jar:4.5.1]
at org.jivesoftware.openfire.spi.RoutingTableImpl.routeToBareJID(RoutingTableImpl.java:608) [xmppserver-4.5.1.jar:4.5.1]
at org.jivesoftware.openfire.spi.RoutingTableImpl.routeToLocalDomain(RoutingTableImpl.java:303) [xmppserver-4.5.1.jar:4.5.1]
at org.jivesoftware.openfire.spi.RoutingTableImpl.routePacket(RoutingTableImpl.java:239) [xmppserver-4.5.1.jar:4.5.1]
at org.jivesoftware.openfire.MessageRouter.route(MessageRouter.java:134) [xmppserver-4.5.1.jar:4.5.1]
at org.jivesoftware.openfire.spi.PacketRouterImpl.route(PacketRouterImpl.java:79) [xmppserver-4.5.1.jar:4.5.1]
at org.jivesoftware.openfire.net.StanzaHandler.processMessage(StanzaHandler.java:402) [xmppserver-4.5.1.jar:4.5.1]
at org.jivesoftware.openfire.net.ClientStanzaHandler.processMessage(ClientStanzaHandler.java:109) [xmppserver-4.5.1.jar:4.5.1]
at org.jivesoftware.openfire.net.StanzaHandler.process(StanzaHandler.java:240) [xmppserver-4.5.1.jar:4.5.1]
at org.jivesoftware.openfire.net.StanzaHandler.process(StanzaHandler.java:203) [xmppserver-4.5.1.jar:4.5.1]
at org.jivesoftware.openfire.nio.ConnectionHandler.messageReceived(ConnectionHandler.java:183) [xmppserver-4.5.1.jar:4.5.1]
at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.messageReceived(DefaultIoFilterChain.java:1015) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:650) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:49) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1128) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:122) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:650) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:49) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1128) [mina-core-2.1.3.jar:?]
at org.apache.mina.filter.codec.ProtocolCodecFilter$ProtocolDecoderOutputImpl.flush(ProtocolCodecFilter.java:413) [mina-core-2.1.3.jar:?]
at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:257) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:650) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:49) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1128) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.IoFilterEvent.fire(IoFilterEvent.java:106) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.session.IoEvent.run(IoEvent.java:89) [mina-core-2.1.3.jar:?]
at org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.runTask(OrderedThreadPoolExecutor.java:766) [mina-core-2.1.3.jar:?]
at org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.runTasks(OrderedThreadPoolExecutor.java:758) [mina-core-2.1.3.jar:?]
at org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.run(OrderedThreadPoolExecutor.java:697) [mina-core-2.1.3.jar:?]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_202]

Avoid push notifications for anonymous users

Anonymous users can't have the configuration needed for push notifications. Evaluating their eligibility generates verbose errors, that can be avoided by explicitly checking for (and ignoring) anonymous sessions.

Make compatible with Openfire 4.8

Code changes that have gone into Openfire 4.8 are conflicting with this plugin. This needs to be resolved.

2023.08.31 14:13:11 ERROR [nioEventLoopGroup-4-2]: org.jivesoftware.openfire.nio.NettyConnectionHandler - Closing connection due to error while processing message: <iq type="set" id="gFJqfxwYoItJ" from="[email protected]/Conversations.4iSH"><enable jid="p2.siacs.eu" node="SDG+FSHiSr5" xmlns="urn:xmpp:push:0"><x type="sub
java.lang.NoSuchMethodError: 'boolean org.jivesoftware.openfire.user.UserManager.isRegisteredUser(org.xmpp.packet.JID)'
        at org.igniterealtime.openfire.plugins.pushnotification.Push0IQHandler.handleIQ(Push0IQHandler.java:108) ~[?:?]
        at org.jivesoftware.openfire.handler.IQHandler.process(IQHandler.java:62) ~[xmppserver-4.8.0-SNAPSHOT.jar:4.8.0-SNAPSHOT]
        at org.jivesoftware.openfire.IQRouter.handle(IQRouter.java:394) ~[xmppserver-4.8.0-SNAPSHOT.jar:4.8.0-SNAPSHOT]
        at org.jivesoftware.openfire.IQRouter.route(IQRouter.java:106) ~[xmppserver-4.8.0-SNAPSHOT.jar:4.8.0-SNAPSHOT]
        at org.jivesoftware.openfire.spi.PacketRouterImpl.route(PacketRouterImpl.java:74) ~[xmppserver-4.8.0-SNAPSHOT.jar:4.8.0-SNAPSHOT]
        at org.jivesoftware.openfire.net.StanzaHandler.processIQ(StanzaHandler.java:396) ~[xmppserver-4.8.0-SNAPSHOT.jar:4.8.0-SNAPSHOT]
        at org.jivesoftware.openfire.net.ClientStanzaHandler.processIQ(ClientStanzaHandler.java:89) ~[xmppserver-4.8.0-SNAPSHOT.jar:4.8.0-SNAPSHOT]
        at org.jivesoftware.openfire.net.StanzaHandler.process(StanzaHandler.java:338) ~[xmppserver-4.8.0-SNAPSHOT.jar:4.8.0-SNAPSHOT]
        at org.jivesoftware.openfire.net.StanzaHandler.processStanza(StanzaHandler.java:226) ~[xmppserver-4.8.0-SNAPSHOT.jar:4.8.0-SNAPSHOT]
        at org.jivesoftware.openfire.net.StanzaHandler.process(StanzaHandler.java:120) ~[xmppserver-4.8.0-SNAPSHOT.jar:4.8.0-SNAPSHOT]
        at org.jivesoftware.openfire.nio.NettyConnectionHandler.channelRead0(NettyConnectionHandler.java:140) [xmppserver-4.8.0-SNAPSHOT.jar:4.8.0-SNAPSHOT]
        at org.jivesoftware.openfire.nio.NettyConnectionHandler.channelRead0(NettyConnectionHandler.java:48) [xmppserver-4.8.0-SNAPSHOT.jar:4.8.0-SNAPSHOT]
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286) [netty-handler-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) [netty-codec-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) [netty-codec-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.handler.traffic.AbstractTrafficShapingHandler.channelRead(AbstractTrafficShapingHandler.java:506) [netty-handler-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1383) [netty-handler-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1246) [netty-handler-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1295) [netty-handler-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529) [netty-codec-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468) [netty-codec-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290) [netty-codec-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) [netty-transport-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) [netty-common-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) [netty-common-4.1.94.Final.jar:4.1.94.Final]
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-common-4.1.94.Final.jar:4.1.94.Final]
        at java.lang.Thread.run(Thread.java:829) [?:?]

Make iOS more responsive

As explained in https://github.com/anurodhp/Monal/issues/354#issuecomment-614562560:
If a stream management ack is not received for a certain time (in prosody I use 30 seconds as default), send pushes for all messages in the smacks queue (but only once!) and directly trigger pushes for all messages coming after this until an ack is finally received or the session gets hibernated.

If you don't do this, depending on the TCP timeout (up to 8 minutes) the conversation will be disrupted for that long (or even longer if you don't handle pushes for stanzas still in the queue when a session gets hibernated).

Do not push when sender is on privacy list

When the sender of a message is being blocked by the intended recipient, push notifications should not be sent.

At the very least, this scenario needs to be tested (and likely, requires fixing).

ClassCastException after plugin gets reloaded

When the plugin gets reloaded (or reinstalled, upgraded), then ClassCastExceptions are very likely to occur (if the plugin has seen usage).

Exceptions relate to the class that's used to store instances of in a cache, as shown below

java.lang.ClassCastException: class org.igniterealtime.openfire.plugins.pushnotification.PushInterceptor$SentNotification cannot be cast to class org.igniterealtime.openfire.plugins.pushnotification.PushInterceptor$SentNotification (org.igniterealtime.openfire.plugins.pushnotification.PushInterceptor$SentNotification is in unnamed module of loader org.jivesoftware.openfire.container.PluginClassLoader @446907d7; org.igniterealtime.openfire.plugins.pushnotification.PushInterceptor$SentNotification is in unnamed module of loader org.jivesoftware.openfire.container.PluginClassLoader @531905e3)
at java.util.Collection.removeIf(Collection.java:576) ~[?:?]
at org.igniterealtime.openfire.plugins.pushnotification.PushInterceptor.wasPushAttemptedFor(PushInterceptor.java:263) ~[?:?]
at org.igniterealtime.openfire.plugins.pushnotification.PushInterceptor.tryPushNotification(PushInterceptor.java:144) ~[?:?]
at org.igniterealtime.openfire.plugins.pushnotification.PushInterceptor.messageStored(PushInterceptor.java:247) ~[?:?]
at org.jivesoftware.openfire.OfflineMessageStrategy.store(OfflineMessageStrategy.java:196) [xmppserver-4.6.1.jar:4.6.1]
at org.jivesoftware.openfire.OfflineMessageStrategy.storeOffline(OfflineMessageStrategy.java:140) [xmppserver-4.6.1.jar:4.6.1]
at org.jivesoftware.openfire.MessageRouter.routingFailed(MessageRouter.java:268) [xmppserver-4.6.1.jar:4.6.1]
at org.jivesoftware.openfire.spi.RoutingTableImpl.routePacket(RoutingTableImpl.java:290) [xmppserver-4.6.1.jar:4.6.1]
at org.jivesoftware.openfire.MessageRouter.route(MessageRouter.java:134) [xmppserver-4.6.1.jar:4.6.1]
at org.jivesoftware.openfire.spi.PacketRouterImpl.route(PacketRouterImpl.java:79) [xmppserver-4.6.1.jar:4.6.1]
at org.jivesoftware.openfire.net.StanzaHandler.processMessage(StanzaHandler.java:422) [xmppserver-4.6.1.jar:4.6.1]
at org.jivesoftware.openfire.net.ClientStanzaHandler.processMessage(ClientStanzaHandler.java:109) [xmppserver-4.6.1.jar:4.6.1]
at org.jivesoftware.openfire.net.StanzaHandler.process(StanzaHandler.java:246) [xmppserver-4.6.1.jar:4.6.1]
at org.jivesoftware.openfire.net.StanzaHandler.process(StanzaHandler.java:209) [xmppserver-4.6.1.jar:4.6.1]
at org.jivesoftware.openfire.nio.ConnectionHandler.messageReceived(ConnectionHandler.java:183) [xmppserver-4.6.1.jar:4.6.1]
at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.messageReceived(DefaultIoFilterChain.java:1015) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:650) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:49) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1128) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:122) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:650) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:49) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1128) [mina-core-2.1.3.jar:?]
at org.apache.mina.filter.codec.ProtocolCodecFilter$ProtocolDecoderOutputImpl.flush(ProtocolCodecFilter.java:413) [mina-core-2.1.3.jar:?]
at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:257) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:650) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:49) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1128) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.filterchain.IoFilterEvent.fire(IoFilterEvent.java:106) [mina-core-2.1.3.jar:?]
at org.apache.mina.core.session.IoEvent.run(IoEvent.java:89) [mina-core-2.1.3.jar:?]
at org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.runTask(OrderedThreadPoolExecutor.java:766) [mina-core-2.1.3.jar:?]
at org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.runTasks(OrderedThreadPoolExecutor.java:758) [mina-core-2.1.3.jar:?]
at org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.run(OrderedThreadPoolExecutor.java:697) [mina-core-2.1.3.jar:?]
at java.lang.Thread.run(Thread.java:832) [?:?]

NPE encountered if there are no "options" specified for the Push node for a user.

Steps to reproduce:

  1. "Enable" the push notification by sending the IQ packet to the server:
      <enable xmlns='urn:xmpp:push:0' jid='testuser1@openfire' node='pusher@openfire'/>
    </iq>
  1. Try sending a message to testuser1 while it is offline.

Result:
NPE Observered, with the following trace:

2021.03.30 16:16:11 org.igniterealtime.openfire.plugins.pushnotification.PushServiceManager - Unable to process database row content while obtaining push service configuration for user 'testuser2'.
java.lang.NullPointerException: null
at java.io.StringReader.(StringReader.java:50) ~[?:1.8.0_251]
at org.igniterealtime.openfire.plugins.pushnotification.PushServiceManager.getServiceNodes(PushServiceManager.java:160) [pushnotification-0.8.0.jar!/:?]
at org.igniterealtime.openfire.plugins.pushnotification.Push0IQHandler.handleIQ(Push0IQHandler.java:137) [pushnotification-0.8.0.jar!/:?]

Enable-request without options fails

The Push Notification plugin should not fail processing a request to enable push notifications, when that request does not contain optional publication options.

Currently, the plugin incorrectly states that, in such cases, the push service for the specified node / user was already registered.

Don't send out too much pushes at once

As explained on https://github.com/anurodhp/Monal/issues/354#issuecomment-614562560:

But: don't send too much of this pushes in a row (for example when XEP-0198 stream management decides to hibernate the stream having multiple messages still being unacked) because every push will create a visible notification on iOS.

This scenario is something you should consider, because TCP needs some time to timeout and all stanzas sent into an already dead but not timed out TCP session must trigger a push, otherwise messages will be seen only when the user opens the app eventually.

Followed up in https://github.com/anurodhp/Monal/issues/354#issuecomment-614964197

your server is sending too many pushes for this token. I searched the logs and i see it hitting the rate limit. The limit max 5 pushes for an account per second and i am seeing way more than that.

Apr 16 05:41:46 ios13push.monal.im:push_appserver warn Rate limit for node '4B179F90-77E4-4EE9-A7B2-' reached, ignoring push request (and returning 'wait' error)
Apr 16 05:41:46 ios13push.monal.im:push_appserver warn Rate limit for node '4B179F90-77E4-4EE9-A7B2-' reached, ignoring push request (and returning 'wait' error)
Apr 16 05:41:46 ios13push.monal.im:push_appserver warn Rate limit for node '4B179F90-77E4-4EE9-A7B2-' reached, ignoring push request (and returning 'wait' error)
Apr 16 05:41:46 ios13push.monal.im:push_appserver warn Rate limit for node '4B179F90-77E4-4EE9-A7B2-' reached, ignoring push request (and returning 'wait' error)
Apr 16 05:41:46 ios13push.monal.im:push_appserver warn Rate limit for node '4B179F90-77E4-4EE9-A7B2-' reached, ignoring push request (and returning 'wait' error)
Apr 16 05:41:46 ios13push.monal.im:push_appserver warn Rate limit for node '4B179F90-77E4-4EE9-A7B2-' reached, ignoring push request (and returning 'wait' error)

Unable to get the plugin running on Openfire < 4.3.0

I've been trying to get the plugin in version 0.7 running on my local OpenFire installation. I've installed it via the OpenFire admin console. The jar-file is in the plugin directory and so it should be deployed automatically as stated in the readme.

But when I retrieve the discovery info from the server, features don't contain "urn:xmpp:push:0" and if I try to enable push notifications I also just get an error back from the server.
What also is odd is that in the plugins section of the OpenFire admin console I can restart every installed plugin - except the pushnotification plugin. Is this normal?

I'm using OpenFire 4.2.3. Yes, I know it's outdated, but that's the version provided by my OpenSuse 15.1 installation and I don't wanted to waste time building the current version.

not working with Openfire 4.5.1

I have been trying to get this module to work for a week now. I am not sure if the issues is the plugin or a bug in Openfire 4.5.1 with s2s connections. I even had the developer at Monal.im confirm that it is not opening the s2s connection on a push as it should. S2s is working to other servers.

Thank for your hard work on this project.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.