You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

API.js 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /**
  2. * Implements API class that communicates with external api class
  3. * and provides interface to access Jitsi Meet features by external
  4. * applications that embed Jitsi Meet
  5. */
  6. /**
  7. * List of the available commands.
  8. * @type {{
  9. * displayName: inputDisplayNameHandler,
  10. * muteAudio: toggleAudio,
  11. * muteVideo: toggleVideo,
  12. * filmStrip: toggleFilmStrip
  13. * }}
  14. */
  15. var commands =
  16. {
  17. displayName: UI.inputDisplayNameHandler,
  18. muteAudio: UI.toggleAudio,
  19. muteVideo: UI.toggleVideo,
  20. toggleFilmStrip: UI.toggleFilmStrip,
  21. toggleChat: UI.toggleChat,
  22. toggleContactList: UI.toggleContactList
  23. };
  24. /**
  25. * Maps the supported events and their status
  26. * (true it the event is enabled and false if it is disabled)
  27. * @type {{
  28. * incomingMessage: boolean,
  29. * outgoingMessage: boolean,
  30. * displayNameChange: boolean,
  31. * participantJoined: boolean,
  32. * participantLeft: boolean
  33. * }}
  34. */
  35. var events =
  36. {
  37. incomingMessage: false,
  38. outgoingMessage:false,
  39. displayNameChange: false,
  40. participantJoined: false,
  41. participantLeft: false
  42. };
  43. var displayName = {};
  44. /**
  45. * Processes commands from external applicaiton.
  46. * @param message the object with the command
  47. */
  48. function processCommand(message)
  49. {
  50. if(message.action != "execute")
  51. {
  52. console.error("Unknown action of the message");
  53. return;
  54. }
  55. for(var key in message)
  56. {
  57. if(commands[key])
  58. commands[key].apply(null, message[key]);
  59. }
  60. }
  61. /**
  62. * Processes events objects from external applications
  63. * @param event the event
  64. */
  65. function processEvent(event) {
  66. if(!event.action)
  67. {
  68. console.error("Event with no action is received.");
  69. return;
  70. }
  71. var i = 0;
  72. switch(event.action)
  73. {
  74. case "add":
  75. for(; i < event.events.length; i++)
  76. {
  77. events[event.events[i]] = true;
  78. }
  79. break;
  80. case "remove":
  81. for(; i < event.events.length; i++)
  82. {
  83. events[event.events[i]] = false;
  84. }
  85. break;
  86. default:
  87. console.error("Unknown action for event.");
  88. }
  89. }
  90. /**
  91. * Sends message to the external application.
  92. * @param object
  93. */
  94. function sendMessage(object) {
  95. window.parent.postMessage(JSON.stringify(object), "*");
  96. }
  97. /**
  98. * Processes a message event from the external application
  99. * @param event the message event
  100. */
  101. function processMessage(event)
  102. {
  103. var message;
  104. try {
  105. message = JSON.parse(event.data);
  106. } catch (e) {}
  107. if(!message.type)
  108. return;
  109. switch (message.type)
  110. {
  111. case "command":
  112. processCommand(message);
  113. break;
  114. case "event":
  115. processEvent(message);
  116. break;
  117. default:
  118. console.error("Unknown type of the message");
  119. return;
  120. }
  121. }
  122. function setupListeners() {
  123. xmpp.addListener(XMPPEvents.MUC_ENTER, function (from) {
  124. API.triggerEvent("participantJoined", {jid: from});
  125. });
  126. xmpp.addListener(XMPPEvents.MESSAGE_RECEIVED, function (from, nick, txt, myjid) {
  127. if (from != myjid)
  128. API.triggerEvent("incomingMessage",
  129. {"from": from, "nick": nick, "message": txt});
  130. });
  131. xmpp.addListener(XMPPEvents.MUC_LEFT, function (jid) {
  132. API.triggerEvent("participantLeft", {jid: jid});
  133. });
  134. xmpp.addListener(XMPPEvents.DISPLAY_NAME_CHANGED, function (jid, newDisplayName) {
  135. name = displayName[jid];
  136. if(!name || name != newDisplayName) {
  137. API.triggerEvent("displayNameChange", {jid: jid, displayname: newDisplayName});
  138. displayName[jid] = newDisplayName;
  139. }
  140. });
  141. xmpp.addListener(XMPPEvents.SENDING_CHAT_MESSAGE, function (body) {
  142. API.triggerEvent("outgoingMessage", {"message": body});
  143. });
  144. }
  145. var API = {
  146. /**
  147. * Check whether the API should be enabled or not.
  148. * @returns {boolean}
  149. */
  150. isEnabled: function () {
  151. var hash = location.hash;
  152. if(hash && hash.indexOf("external") > -1 && window.postMessage)
  153. return true;
  154. return false;
  155. },
  156. /**
  157. * Initializes the APIConnector. Setups message event listeners that will
  158. * receive information from external applications that embed Jitsi Meet.
  159. * It also sends a message to the external application that APIConnector
  160. * is initialized.
  161. */
  162. init: function () {
  163. if (window.addEventListener)
  164. {
  165. window.addEventListener('message',
  166. processMessage, false);
  167. }
  168. else
  169. {
  170. window.attachEvent('onmessage', processMessage);
  171. }
  172. sendMessage({type: "system", loaded: true});
  173. setupListeners();
  174. },
  175. /**
  176. * Checks whether the event is enabled ot not.
  177. * @param name the name of the event.
  178. * @returns {*}
  179. */
  180. isEventEnabled: function (name) {
  181. return events[name];
  182. },
  183. /**
  184. * Sends event object to the external application that has been subscribed
  185. * for that event.
  186. * @param name the name event
  187. * @param object data associated with the event
  188. */
  189. triggerEvent: function (name, object) {
  190. if(this.isEnabled() && this.isEventEnabled(name))
  191. sendMessage({
  192. type: "event", action: "result", event: name, result: object});
  193. },
  194. /**
  195. * Removes the listeners.
  196. */
  197. dispose: function () {
  198. if(window.removeEventListener)
  199. {
  200. window.removeEventListener("message",
  201. processMessage, false);
  202. }
  203. else
  204. {
  205. window.detachEvent('onmessage', processMessage);
  206. }
  207. }
  208. };
  209. module.exports = API;