Unable to publish PubSub item

I’m having problems to publish an Item to a PubSub service. I need to publish an item without payload to the service but I’m always getting payload-required error from the server even if I try to publish PayloadItem.
I followed examples from this page:
https://github.com/igniterealtime/Smack/blob/master/documentation/extensions/pubsub.md
but as I said, I never succeeded to publish an Item to the PubSub service.

Smack version I’m using is 4.2.1 (I’ve also tried 4.2.2) and the XMPP server is eJabberd version 1711 (I’ve also tested on 1701 with the same issues). eJabberd server has it’s default PubSub configuration. Can someone help me and tell me where I’m doing wrong things or is there some bug in Smack library or eJabberd server because I’m unable to figure out what’s going wrong?

Code I’m using is this:

BareJid pubsubJID = null;
try {
    pubsubJID = JidCreate.bareFrom("pubsub.fm.ch");
} catch (XmppStringprepException ex) {
}
pubsub = PubSubManager.getInstance(this.conn, pubsubJID);

try {
    LeafNode node;
    try {
        node = pubsub.getNode("testNode");
    } catch (PubSubException.NotAPubSubNodeException | XMPPException.XMPPErrorException ex) {
        ConfigureForm form = new ConfigureForm(DataForm.Type.submit);
        form.setAccessModel(AccessModel.open);
        form.setDeliverPayloads(false);
        form.setPersistentItems(false);
        form.setPublishModel(PublishModel.publishers);
        
        node = pubsub.createNode("testNode");
        node.sendConfigurationForm(form);
    }

    node.send(new Item());
    
} catch (SmackException.NoResponseException | XMPPException.XMPPErrorException | SmackException.NotConnectedException | InterruptedException ex) {
    System.out.println(ex);
}

PubSub node is created and configured successfully which I check with calling node.getNodeConfiguration().toString() function with next trace:
org.jivesoftware.smackx.pubsub.ConfigureForm Content [(FORM_TYPE:http://jabber.org/protocol/pubsub#node_config)(pubsub#deliver_payloads:0)(pubsub#notify_config:0)(pubsub#notify_delete:0)(pubsub#notify_retract:1)(pubsub#purge_offline:0)(pubsub#persist_items:0)(pubsub#max_items:10)(pubsub#subscribe:1)(pubsub#access_model:open)(pubsub#roster_groups_allowed:NOT SET)(pubsub#publish_model:publishers)(pubsub#notification_type:headline)(pubsub#max_payload_size:60000)(pubsub#send_last_published_item:on_sub_and_presence)(pubsub#deliver_notifications:1)(pubsub#presence_based_delivery:0)(pubsub#itemreply:none)]

Smack debug trace I’m getting when executing send command is:

14:52:57 SENT (0):
<iq to='pubsub.fm.ch' id='3abh7-29' type='set'>
	<pubsub xmlns='http://jabber.org/protocol/pubsub'>
		<publish node='testNode'>
			<item/>
		</publish>
	</pubsub>
</iq>

14:52:57 RECV (0):
<iq xml:lang='en' to='***@fm.ch/***' from='pubsub.fm.ch' type='error' id='3abh7-29'>
	<pubsub xmlns='http://jabber.org/protocol/pubsub'>
		<publish node='testNode'>
			<item/>
		</publish>
	</pubsub>
	<error code='400' type='modify'>
		<payload-required xmlns='http://jabber.org/protocol/pubsub#errors'/>
		<bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
	</error>
</iq>

I’ve also tried different node configurations (changing setDeliverPayloads and setPersistentItems) butI’m always getting the same error. I’ve tried as well to send different Items like:

node.send()
node.send(new Item())
node.send(new Item("testItem"))
node.send(new PayloadItem("testItem", new SimplePayload("testPayload", "pubsub.test", "test")))

and as I said, the result is always the same, payload-required error except in the first case (send()) where I’m getting item-required error.

I think your SimplePayloadItem is not valid. As far as I know the last parameter must be valid XML and “test” is not.

Thanks for your reply Paul!
I’ve updated my SimplePayload with correct XML by putting something like <payloadValue>test</payloadValue> as the last parameter, but this time I get item-forbidden error, which is actually correct error by the XEP-0060 specification.

If the event type is notification + transient and the publisher provides an item, the service MUST bounce the publication request with a <bad-request/> error and a pubsub-specific error condition of <item-forbidden/>.

From this definition you can see that if event type is notification + transient (which is configured by setting setDeliverPayloads and setPersistentItems both to false), publisher should not send any item at all. This means that calling only node.send() function should do the job.
But as I wrote above, with other function calls I’m getting payload-required error. If you look at next definition from XEP-0060 specification:

If the event type is payload (either persistent or transient) and the publisher does not include a payload, the service SHOULD bounce the publication request with a <bad-request/> error and a pubsub-specific error condition of <payload-required/>.

you can see that other use cases (send(), send(new Item()),…) are considered as Payload items which is not good.

This is eJabberd bug. Problem reported here:
https://github.com/processone/ejabberd/issues/2267

2 Likes

Thanks for reporting this to the ejabberd developers. :slight_smile: