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 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /* global APP, getConfigParamsFromUrl */
  2. const logger = require("jitsi-meet-logger").getLogger(__filename);
  3. /**
  4. * Implements API class that communicates with external api class
  5. * and provides interface to access Jitsi Meet features by external
  6. * applications that embed Jitsi Meet
  7. */
  8. import postisInit from 'postis';
  9. /**
  10. * List of the available commands.
  11. * @type {{
  12. * displayName: inputDisplayNameHandler,
  13. * toggleAudio: toggleAudio,
  14. * toggleVideo: toggleVideo,
  15. * toggleFilmStrip: toggleFilmStrip,
  16. * toggleChat: toggleChat,
  17. * toggleContactList: toggleContactList
  18. * }}
  19. */
  20. let commands = {};
  21. let hashParams = getConfigParamsFromUrl();
  22. /**
  23. * JitsiMeetExternalAPI id - unique for a webpage.
  24. */
  25. let jitsi_meet_external_api_id = hashParams.jitsi_meet_external_api_id;
  26. /**
  27. * Object that will execute sendMessage
  28. */
  29. let target = window.opener ? window.opener : window.parent;
  30. /**
  31. * Postis instance. Used to communicate with the external application.
  32. */
  33. let postis;
  34. /**
  35. * Current status (enabled/disabled) of API.
  36. */
  37. let enabled = false;
  38. function initCommands() {
  39. commands = {
  40. "display-name": APP.UI.inputDisplayNameHandler,
  41. "toggle-audio": APP.conference.toggleAudioMuted.bind(APP.conference),
  42. "toggle-video": APP.conference.toggleVideoMuted.bind(APP.conference),
  43. "toggle-film-strip": APP.UI.toggleFilmStrip,
  44. "toggle-chat": APP.UI.toggleChat,
  45. "toggle-contact-list": APP.UI.toggleContactList,
  46. "toggle-share-screen":
  47. APP.conference.toggleScreenSharing.bind(APP.conference),
  48. "video-hangup": () => APP.conference.hangup()
  49. };
  50. Object.keys(commands).forEach(function (key) {
  51. postis.listen(key, commands[key]);
  52. });
  53. }
  54. /**
  55. * Maps the supported events and their status
  56. * (true it the event is enabled and false if it is disabled)
  57. * @type {{
  58. * incoming-message: boolean,
  59. * outgoing-message: boolean,
  60. * display-name-change: boolean,
  61. * participant-left: boolean,
  62. * participant-joined: boolean,
  63. * video-conference-left: boolean,
  64. * video-conference-joined: boolean
  65. * }}
  66. */
  67. const events = {
  68. "incoming-message": false,
  69. "outgoing-message":false,
  70. "display-name-change": false,
  71. "participant-joined": false,
  72. "participant-left": false,
  73. "video-conference-joined": false,
  74. "video-conference-left": false,
  75. "video-ready-to-close": false
  76. };
  77. /**
  78. * Sends message to the external application.
  79. * @param message {object}
  80. * @param method {string}
  81. * @param params {object} the object that will be sent as JSON string
  82. */
  83. function sendMessage(message) {
  84. if(enabled)
  85. postis.send(message);
  86. }
  87. /**
  88. * Check whether the API should be enabled or not.
  89. * @returns {boolean}
  90. */
  91. function isEnabled () {
  92. return (typeof jitsi_meet_external_api_id === "number");
  93. }
  94. /**
  95. * Checks whether the event is enabled ot not.
  96. * @param name the name of the event.
  97. * @returns {*}
  98. */
  99. function isEventEnabled (name) {
  100. return events[name];
  101. }
  102. /**
  103. * Sends event object to the external application that has been subscribed
  104. * for that event.
  105. * @param name the name event
  106. * @param object data associated with the event
  107. */
  108. function triggerEvent (name, object) {
  109. if(isEventEnabled(name))
  110. sendMessage({method: name, params: object});
  111. }
  112. /**
  113. * Handles system messages. (for example: enable/disable events)
  114. * @param message {object} the message
  115. */
  116. function onSystemMessage(message) {
  117. switch (message.type) {
  118. case "eventStatus":
  119. if(!message.name || !message.value) {
  120. logger.warn("Unknown system message format", message);
  121. break;
  122. }
  123. events[message.name] = message.value;
  124. break;
  125. default:
  126. logger.warn("Unknown system message type", message);
  127. }
  128. }
  129. export default {
  130. /**
  131. * Initializes the APIConnector. Setups message event listeners that will
  132. * receive information from external applications that embed Jitsi Meet.
  133. * It also sends a message to the external application that APIConnector
  134. * is initialized.
  135. * @param options {object}
  136. * @param forceEnable {boolean} if true the module will be enabled.
  137. * @param enabledEvents {array} array of events that should be enabled.
  138. */
  139. init (options = {}) {
  140. if(!isEnabled() && !options.forceEnable)
  141. return;
  142. enabled = true;
  143. if(options.enabledEvents)
  144. options.enabledEvents.forEach(function (eventName) {
  145. events[eventName] = true;
  146. });
  147. let postisOptions = {
  148. window: target
  149. };
  150. if(typeof jitsi_meet_external_api_id === "number")
  151. postisOptions.scope
  152. = "jitsi_meet_external_api_" + jitsi_meet_external_api_id;
  153. postis = postisInit(postisOptions);
  154. postis.listen("jitsiSystemMessage", onSystemMessage);
  155. initCommands();
  156. },
  157. /**
  158. * Notify external application (if API is enabled) that message was sent.
  159. * @param {string} body message body
  160. */
  161. notifySendingChatMessage (body) {
  162. triggerEvent("outgoing-message", {"message": body});
  163. },
  164. /**
  165. * Notify external application (if API is enabled) that
  166. * message was received.
  167. * @param {string} id user id
  168. * @param {string} nick user nickname
  169. * @param {string} body message body
  170. * @param {number} ts message creation timestamp
  171. */
  172. notifyReceivedChatMessage (id, nick, body, ts) {
  173. if (APP.conference.isLocalId(id)) {
  174. return;
  175. }
  176. triggerEvent(
  177. "incoming-message",
  178. {"from": id, "nick": nick, "message": body, "stamp": ts}
  179. );
  180. },
  181. /**
  182. * Notify external application (if API is enabled) that
  183. * user joined the conference.
  184. * @param {string} id user id
  185. */
  186. notifyUserJoined (id) {
  187. triggerEvent("participant-joined", {id});
  188. },
  189. /**
  190. * Notify external application (if API is enabled) that
  191. * user left the conference.
  192. * @param {string} id user id
  193. */
  194. notifyUserLeft (id) {
  195. triggerEvent("participant-left", {id});
  196. },
  197. /**
  198. * Notify external application (if API is enabled) that
  199. * user changed their nickname.
  200. * @param {string} id user id
  201. * @param {string} displayName user nickname
  202. */
  203. notifyDisplayNameChanged (id, displayName) {
  204. triggerEvent("display-name-change", {id, displayname: displayName});
  205. },
  206. /**
  207. * Notify external application (if API is enabled) that
  208. * user changed their nickname.
  209. * @param {string} id user id
  210. * @param {string} displayName user nickname
  211. */
  212. notifyConferenceJoined (room) {
  213. triggerEvent("video-conference-joined", {roomName: room});
  214. },
  215. /**
  216. * Notify external application (if API is enabled) that
  217. * user changed their nickname.
  218. * @param {string} id user id
  219. * @param {string} displayName user nickname
  220. */
  221. notifyConferenceLeft (room) {
  222. triggerEvent("video-conference-left", {roomName: room});
  223. },
  224. /**
  225. * Notify external application (if API is enabled) that
  226. * we are ready to be closed.
  227. */
  228. notifyReadyToClose () {
  229. triggerEvent("video-ready-to-close", {});
  230. },
  231. /**
  232. * Removes the listeners.
  233. */
  234. dispose: function () {
  235. if(enabled)
  236. postis.destroy();
  237. }
  238. };