/**
* @module converse-pubsub
* @copyright The Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
import "./disco/index.js";
import { _converse, api, converse } from "../core.js";
import log from "../log.js";
const { Strophe, $iq } = converse.env;
Strophe.addNamespace('PUBSUB_ERROR', Strophe.NS.PUBSUB+"#errors");
converse.plugins.add('converse-pubsub', {
dependencies: ["converse-disco"],
initialize () {
/************************ BEGIN API ************************/
// We extend the default converse.js API to add methods specific to MUC groupchats.
Object.assign(_converse.api, {
/**
* The "pubsub" namespace groups methods relevant to PubSub
*
* @namespace _converse.api.pubsub
* @memberOf _converse.api
*/
'pubsub': {
/**
* Publshes an item to a PubSub node
*
* @method _converse.api.pubsub.publish
* @param { string } jid The JID of the pubsub service where the node resides.
* @param { string } node The node being published to
* @param {Strophe.Builder} item The Strophe.Builder representation of the XML element being published
* @param { object } options An object representing the publisher options
* (see https://xmpp.org/extensions/xep-0060.html#publisher-publish-options)
* @param { boolean } strict_options Indicates whether the publisher
* options are a strict requirement or not. If they're NOT
* strict, then Converse will publish to the node even if
* the publish options precondication cannot be met.
*/
async 'publish' (jid, node, item, options, strict_options=true) {
const stanza = $iq({
'from': _converse.bare_jid,
'type': 'set',
'to': jid
}).c('pubsub', {'xmlns': Strophe.NS.PUBSUB})
.c('publish', {'node': node})
.cnode(item.tree()).up().up();
if (options) {
jid = jid || _converse.bare_jid;
if (await api.disco.supports(Strophe.NS.PUBSUB + '#publish-options', jid)) {
stanza.c('publish-options')
.c('x', {'xmlns': Strophe.NS.XFORM, 'type': 'submit'})
.c('field', {'var': 'FORM_TYPE', 'type': 'hidden'})
.c('value').t(`${Strophe.NS.PUBSUB}#publish-options`).up().up()
Object.keys(options).forEach(k => stanza.c('field', {'var': k}).c('value').t(options[k]).up().up());
} else {
log.warn(`_converse.api.publish: ${jid} does not support #publish-options, `+
`so we didn't set them even though they were provided.`)
}
}
try {
await api.sendIQ(stanza);
} catch (iq) {
if (iq instanceof Element &&
strict_options &&
iq.querySelector(`precondition-not-met[xmlns="${Strophe.NS.PUBSUB_ERROR}"]`)) {
// The publish-options precondition couldn't be
// met. We re-publish but without publish-options.
const el = stanza.tree();
el.querySelector('publish-options').outerHTML = '';
log.warn(`PubSub: Republishing without publish options. ${el.outerHTML}`);
await api.sendIQ(el);
} else {
throw iq;
}
}
}
}
});
/************************ END API ************************/
}
});