diff --git a/react/features/reactions/functions.any.js b/react/features/reactions/functions.any.js index 36ea78600..023aa5355 100644 --- a/react/features/reactions/functions.any.js +++ b/react/features/reactions/functions.any.js @@ -1,5 +1,11 @@ // @flow +import { getLocalParticipant } from '../base/participants'; +import { extractFqnFromPath } from '../dynamic-branding/functions'; + +import { REACTIONS } from './constants'; +import logger from './logger'; + /** * Returns the queue of reactions. * @@ -9,3 +15,74 @@ export function getReactionsQueue(state: Object) { return state['features/reactions'].queue; } + +/** + * Returns reaction key from the reaction message. + * + * @param {string} message - The reaction message. + * @returns {string} + */ +export function getReactionKeyByMessage(message: string): ?string { + return Object.keys(REACTIONS).find(key => REACTIONS[key].message === `:${message}:`); +} + +/** + * Gets reactions key array from concatenated message. + * + * @param {string} message - The reaction message. + * @returns {Array} + */ +export function messageToKeyArray(message: string) { + let formattedMessage = message.replace(/::/g, '-'); + + formattedMessage = formattedMessage.replace(/:/g, ''); + const messageArray = formattedMessage.split('-'); + + return messageArray.map(getReactionKeyByMessage); +} + +/** + * Sends reactions to the backend. + * + * @param {Object} state - The redux state object. + * @param {Array} reactions - Reactions array to be sent. + * @returns {void} + */ +export async function sendReactionsWebhook(state: Object, reactions: Array) { + const { webhookProxyUrl: url } = state['features/base/config']; + const { conference } = state['features/base/conference']; + const { jwt } = state['features/base/jwt']; + const { locationURL } = state['features/base/connection']; + const localParticipant = getLocalParticipant(state); + + const headers = { + 'Authorization': `Bearer ${jwt}`, + 'Content-Type': 'application/json' + }; + + + const reqBody = { + meetingFqn: extractFqnFromPath(locationURL.pathname), + sessionId: conference.sessionId, + submitted: Date.now(), + reactions, + participantId: localParticipant.id, + participantName: localParticipant.name + }; + + if (url) { + try { + const res = await fetch(`${url}/reactions`, { + method: 'POST', + headers, + body: JSON.stringify(reqBody) + }); + + if (!res.ok) { + logger.error('Status error:', res.status); + } + } catch (err) { + logger.error('Could not send request', err); + } + } +} diff --git a/react/features/reactions/logger.js b/react/features/reactions/logger.js new file mode 100644 index 000000000..dab71f218 --- /dev/null +++ b/react/features/reactions/logger.js @@ -0,0 +1,5 @@ +// @flow + +import { getLogger } from '../base/logging/functions'; + +export default getLogger('features/base/reactions'); diff --git a/react/features/reactions/middleware.js b/react/features/reactions/middleware.js index 0c928e025..aefbeb183 100644 --- a/react/features/reactions/middleware.js +++ b/react/features/reactions/middleware.js @@ -2,6 +2,7 @@ import { ENDPOINT_REACTION_NAME } from '../../../modules/API/constants'; import { MiddlewareRegistry } from '../base/redux'; +import { isVpaasMeeting } from '../billing-counter/functions'; import { SET_REACTIONS_MESSAGE, @@ -17,6 +18,7 @@ import { setReactionQueue } from './actions.any'; import { REACTIONS } from './constants'; +import { messageToKeyArray, sendReactionsWebhook } from './functions.any'; declare var APP: Object; @@ -46,7 +48,12 @@ MiddlewareRegistry.register(store => next => action => { } case CLEAR_REACTIONS_MESSAGE: { - const { message } = getState()['features/reactions']; + const state = getState(); + const { message } = state['features/reactions']; + + if (isVpaasMeeting(state)) { + sendReactionsWebhook(state, messageToKeyArray(message)); + } dispatch(addReactionsMessageToChat(message));