api.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import log from "@converse/log";
  2. import _converse from '../../shared/_converse.js';
  3. import api from '../../shared/api/index.js';
  4. import converse from '../../shared/api/public.js';
  5. import { parseCommandResult, parseForCommands } from './utils.js';
  6. const { Strophe, $iq, u, stx } = converse.env;
  7. export default {
  8. /**
  9. * @typedef {import('./types').AdHocCommandResult} AdHocCommandResult
  10. */
  11. /**
  12. * The XEP-0050 Ad-Hoc Commands API
  13. *
  14. * This API lets you discover ad-hoc commands available for an entity in the XMPP network.
  15. *
  16. * @namespace api.adhoc
  17. * @memberOf api
  18. */
  19. adhoc: {
  20. /**
  21. * @method api.adhoc.getCommands
  22. * @param {string} to_jid
  23. */
  24. async getCommands (to_jid) {
  25. try {
  26. return parseForCommands(await api.disco.items(to_jid, Strophe.NS.ADHOC));
  27. } catch (e) {
  28. if (e === null) {
  29. log.error(`Error: timeout while fetching ad-hoc commands for ${to_jid}`);
  30. } else {
  31. log.error(`Error while fetching ad-hoc commands for ${to_jid}`);
  32. log.error(e);
  33. }
  34. return [];
  35. }
  36. },
  37. /**
  38. * @method api.adhoc.fetchCommandForm
  39. * @param {string} jid
  40. * @param {string} node
  41. * @returns {Promise<AdHocCommandResult>}
  42. */
  43. async fetchCommandForm (jid, node) {
  44. const stanza = $iq({
  45. type: 'set',
  46. to: jid
  47. }).c('command', {
  48. xmlns: Strophe.NS.ADHOC,
  49. action: 'execute',
  50. node,
  51. });
  52. return parseCommandResult(await api.sendIQ(stanza));
  53. },
  54. /**
  55. * @method api.adhoc.runCommand
  56. * @param {String} jid
  57. * @param {String} sessionid
  58. * @param {import('./types').AdHocCommandAction} action
  59. * @param {String} node
  60. * @param {Array<{ [k:string]: string }>} inputs
  61. */
  62. async runCommand (jid, sessionid, node, action, inputs) {
  63. const iq =
  64. stx`<iq type="set" to="${jid}" xmlns="jabber:client">
  65. <command sessionid="${sessionid}" node="${node}" action="${action}" xmlns="${Strophe.NS.ADHOC}">
  66. ${ !['cancel', 'prev'].includes(action) ? stx`
  67. <x xmlns="${Strophe.NS.XFORM}" type="submit">
  68. ${ inputs.map(({ name, value }) => stx`<field var="${name}"><value>${value}</value></field>`) }
  69. </x>` : '' }
  70. </command>
  71. </iq>`;
  72. const result = await api.sendIQ(iq, null, false);
  73. if (result === null) {
  74. log.warn(`A timeout occurred while trying to run an ad-hoc command`);
  75. const { __ } = _converse;
  76. return {
  77. status: 'error',
  78. note: __('A timeout occurred'),
  79. }
  80. } else if (u.isErrorStanza(result)) {
  81. log.error('Error while trying to execute an ad-hoc command');
  82. log.error(result);
  83. }
  84. const command = result.querySelector('command');
  85. const status = command?.getAttribute('status');
  86. return {
  87. status,
  88. ...(status === 'executing' ? parseCommandResult(result) : {}),
  89. note: result.querySelector('note')?.textContent
  90. }
  91. }
  92. }
  93. }