converse.js
Version:
Browser based XMPP chat client
102 lines (93 loc) • 3.59 kB
JavaScript
import log from "@converse/log";
import _converse from '../../shared/_converse.js';
import api from '../../shared/api/index.js';
import converse from '../../shared/api/public.js';
import { parseCommandResult, parseForCommands } from './utils.js';
const { Strophe, $iq, u, stx } = converse.env;
export default {
/**
* @typedef {import('./types').AdHocCommandResult} AdHocCommandResult
*/
/**
* The XEP-0050 Ad-Hoc Commands API
*
* This API lets you discover ad-hoc commands available for an entity in the XMPP network.
*
* @namespace api.adhoc
* @memberOf api
*/
adhoc: {
/**
* @method api.adhoc.getCommands
* @param {string} to_jid
*/
async getCommands (to_jid) {
try {
return parseForCommands(await api.disco.items(to_jid, Strophe.NS.ADHOC));
} catch (e) {
if (e === null) {
log.error(`Error: timeout while fetching ad-hoc commands for ${to_jid}`);
} else {
log.error(`Error while fetching ad-hoc commands for ${to_jid}`);
log.error(e);
}
return [];
}
},
/**
* @method api.adhoc.fetchCommandForm
* @param {string} jid
* @param {string} node
* @returns {Promise<AdHocCommandResult>}
*/
async fetchCommandForm (jid, node) {
const stanza = $iq({
type: 'set',
to: jid
}).c('command', {
xmlns: Strophe.NS.ADHOC,
action: 'execute',
node,
});
return parseCommandResult(await api.sendIQ(stanza));
},
/**
* @method api.adhoc.runCommand
* @param {String} jid
* @param {String} sessionid
* @param {import('./types').AdHocCommandAction} action
* @param {String} node
* @param {Array<{ [k:string]: string }>} inputs
*/
async runCommand (jid, sessionid, node, action, inputs) {
const iq =
stx`<iq type="set" to="${jid}" xmlns="jabber:client">
<command sessionid="${sessionid}" node="${node}" action="${action}" xmlns="${Strophe.NS.ADHOC}">
${ !['cancel', 'prev'].includes(action) ? stx`
<x xmlns="${Strophe.NS.XFORM}" type="submit">
${ inputs.map(({ name, value }) => stx`<field var="${name}"><value>${value}</value></field>`) }
</x>` : '' }
</command>
</iq>`;
const result = await api.sendIQ(iq, null, false);
if (result === null) {
log.warn(`A timeout occurred while trying to run an ad-hoc command`);
const { __ } = _converse;
return {
status: 'error',
note: __('A timeout occurred'),
}
} else if (u.isErrorStanza(result)) {
log.error('Error while trying to execute an ad-hoc command');
log.error(result);
}
const command = result.querySelector('command');
const status = command?.getAttribute('status');
return {
status,
...(status === 'executing' ? parseCommandResult(result) : {}),
note: result.querySelector('note')?.textContent
}
}
}
}