diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala index 525a368fd2..b984dbc95c 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala @@ -109,7 +109,7 @@ case class EjectUserFromBreakoutInternalMsg(parentId: String, breakoutId: String * @param userId * @param parentMeetingId */ -case class CaptureSharedNotesReqInternalMsg(userId: String, parentMeetingId: String) extends InMessage +case class CaptureSharedNotesReqInternalMsg(parentMeetingId: String) extends InMessage // DeskShare case class DeskShareStartedRequest(conferenceName: String, callerId: String, callerIdName: String) extends InMessage diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/EndBreakoutRoomInternalMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/EndBreakoutRoomInternalMsgHdlr.scala index 23f85c93f8..e023b21b4e 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/EndBreakoutRoomInternalMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/EndBreakoutRoomInternalMsgHdlr.scala @@ -14,7 +14,7 @@ trait EndBreakoutRoomInternalMsgHdlr extends HandlerHelpers { def handleEndBreakoutRoomInternalMsg(msg: EndBreakoutRoomInternalMsg): Unit = { if (liveMeeting.props.breakoutProps.captureNotes) { - val event = BigBlueButtonEvent(msg.breakoutId, CaptureSharedNotesReqInternalMsg("system", msg.parentId)) + val event = BigBlueButtonEvent(msg.breakoutId, CaptureSharedNotesReqInternalMsg(msg.parentId)) eventBus.publish(event) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/CreateGroupChatReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/CreateGroupChatReqMsgHdlr.scala index 479f3b7894..bd72755dbc 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/CreateGroupChatReqMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/CreateGroupChatReqMsgHdlr.scala @@ -84,10 +84,12 @@ trait CreateGroupChatReqMsgHdlr extends SystemConfiguration { BbbCoreEnvelope(name, routing) } - def makeBody(chatId: String, - access: String, correlationId: String, - createdBy: GroupChatUser, users: Vector[GroupChatUser], - msgs: Vector[GroupChatMsgToUser]): GroupChatCreatedEvtMsgBody = { + def makeBody( + chatId: String, + access: String, correlationId: String, + createdBy: GroupChatUser, users: Vector[GroupChatUser], + msgs: Vector[GroupChatMsgToUser] + ): GroupChatCreatedEvtMsgBody = { GroupChatCreatedEvtMsgBody(correlationId, chatId, createdBy, access, users, msgs) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationWithAnnotationsMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationWithAnnotationsMsgHdlr.scala index 33a8c676c7..a2fb4fa25d 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationWithAnnotationsMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationWithAnnotationsMsgHdlr.scala @@ -1,7 +1,7 @@ package org.bigbluebutton.core.apps.presentationpod import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.api.{ CaptureSharedNotesReqInternalMsg } +import org.bigbluebutton.core.api.CaptureSharedNotesReqInternalMsg import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait } import org.bigbluebutton.core.bus.MessageBus import org.bigbluebutton.core.domain.MeetingState2x @@ -184,10 +184,38 @@ trait PresentationWithAnnotationsMsgHdlr extends RightsManagementTrait { log.info("Received NewPresAnnFileAvailableMsg meetingId={} presId={} fileUrl={}", liveMeeting.props.meetingProp.intId, m.body.presId, m.body.fileURI) bus.outGW.send(buildBroadcastNewPresAnnFileAvailable(m, liveMeeting)) - } - def handle(m: CaptureSharedNotesReqInternalMsg, state: MeetingState2x, liveMeeting: LiveMeeting, bus: MessageBus): Unit = { - log.info("Received CaptureSharedNotesReqInternalMsg") + def handle(m: CaptureSharedNotesReqInternalMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = { + val meetingId = liveMeeting.props.meetingProp.intId + + log.info("Received CaptureSharedNotesReqInternalMsg meetingId={} parentMeetingId={}", meetingId, m.parentMeetingId) + + val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used") + val envelope = BbbCoreEnvelope(PresentationPageConversionStartedEventMsg.NAME, routing) + val header = BbbClientMsgHeader(CaptureSharedNotesReqEvtMsg.NAME, meetingId, "not-used") + val body = CaptureSharedNotesReqEvtMsgBody(m.parentMeetingId) + val event = CaptureSharedNotesReqEvtMsg(header, body) + + bus.outGW.send(BbbCommonEnvCoreMsg(envelope, event)) + } + + def handle(m: PadCapturePubMsg, state: MeetingState2x, liveMeeting: LiveMeeting, bus: MessageBus): Unit = { + + val meetingId = liveMeeting.props.meetingProp.intId + val userId: String = "system" + val jobId: String = RandomStringGenerator.randomAlphanumericString(16); + val jobType = "PadCaptureJob" + val filename = s"${liveMeeting.props.meetingProp.name}-notes" + + val presId = m.body.padId + val presentationUploadToken: String = PresentationPodsApp.generateToken("DEFAULT_PRESENTATION_POD", userId) + + bus.outGW.send(buildPresentationUploadTokenSysPubMsg(m.body.parentMeetingId, userId, presentationUploadToken, filename)) + + val exportJob: ExportJob = new ExportJob(jobId, jobType, filename, presId, "", true, List[Int](), m.body.parentMeetingId, presentationUploadToken) + val job = buildStoreExportJobInRedisSysMsg(exportJob, liveMeeting) + + bus.outGW.send(job) } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala index 92f40e3fc9..dcc6d12177 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala @@ -175,6 +175,8 @@ class ReceivedJsonMsgHandlerActor( routePadMsg[PadPatchSysMsg](envelope, jsonNode) case PadUpdatePubMsg.NAME => routeGenericMsg[PadUpdatePubMsg](envelope, jsonNode) + case PadCapturePubMsg.NAME => + routePadMsg[PadCapturePubMsg](envelope, jsonNode) // Voice case RecordingStartedVoiceConfEvtMsg.NAME => diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala index 4234ab0a6b..247370ba70 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala @@ -283,7 +283,7 @@ class MeetingActor( case msg: SendMessageToBreakoutRoomInternalMsg => state = handleSendMessageToBreakoutRoomInternalMsg(msg, state, liveMeeting, msgBus) case msg: SendBreakoutTimeRemainingInternalMsg => handleSendBreakoutTimeRemainingInternalMsg(msg) - case msg: CaptureSharedNotesReqInternalMsg => presentationPodsApp.handle(msg, state, liveMeeting, msgBus) + case msg: CaptureSharedNotesReqInternalMsg => presentationPodsApp.handle(msg, liveMeeting, msgBus) case msg: SendRecordingTimerInternalMsg => state = usersApp.handleSendRecordingTimerInternalMsg(msg, state) @@ -448,9 +448,9 @@ class MeetingActor( case m: UserTalkingInVoiceConfEvtMsg => updateVoiceUserLastActivity(m.body.voiceUserId) handleUserTalkingInVoiceConfEvtMsg(m) - case m: VoiceConfCallStateEvtMsg => handleVoiceConfCallStateEvtMsg(m) + case m: VoiceConfCallStateEvtMsg => handleVoiceConfCallStateEvtMsg(m) - case m: RecordingStartedVoiceConfEvtMsg => handleRecordingStartedVoiceConfEvtMsg(m) + case m: RecordingStartedVoiceConfEvtMsg => handleRecordingStartedVoiceConfEvtMsg(m) case m: AudioFloorChangedVoiceConfEvtMsg => handleAudioFloorChangedVoiceConfEvtMsg(m) audioCaptionsApp2x.handle(m, liveMeeting) @@ -492,6 +492,7 @@ class MeetingActor( case m: PadContentSysMsg => padsApp2x.handle(m, liveMeeting, msgBus) case m: PadPatchSysMsg => padsApp2x.handle(m, liveMeeting, msgBus) case m: PadUpdatePubMsg => padsApp2x.handle(m, liveMeeting, msgBus) + case m: PadCapturePubMsg => presentationPodsApp.handle(m, state, liveMeeting, msgBus) // Lock Settings case m: ChangeLockSettingsInMeetingCmdMsg => diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala index ca6bc9f171..372e105dae 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala @@ -201,6 +201,7 @@ class AnalyticsActor(val includeChat: Boolean) extends Actor with ActorLogging { case m: PadUpdatedEvtMsg => logMessage(msg) case m: PadUpdatePubMsg => logMessage(msg) case m: PadUpdateCmdMsg => logMessage(msg) + case m: PadCapturePubMsg => logMessage(msg) case _ => // ignore message } diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PadsMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PadsMsgs.scala index d42255b7ab..0be6609e71 100644 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PadsMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PadsMsgs.scala @@ -113,3 +113,8 @@ case class PadUpdatePubMsgBody(externalId: String, text: String) object PadUpdateCmdMsg { val NAME = "PadUpdateCmdMsg" } case class PadUpdateCmdMsg(header: BbbCoreHeaderWithMeetingId, body: PadUpdateCmdMsgBody) extends BbbCoreMsg case class PadUpdateCmdMsgBody(groupId: String, name: String, text: String) + +// pads -> apps +object PadCapturePubMsg { val NAME = "PadCapturePubMsg" } +case class PadCapturePubMsg(header: BbbCoreHeaderWithMeetingId, body: PadCapturePubMsgBody) extends PadStandardMsg +case class PadCapturePubMsgBody(parentMeetingId: String, padId: String) \ No newline at end of file diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PresentationMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PresentationMsgs.scala index b2ed8f7a01..ccb02e7803 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PresentationMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PresentationMsgs.scala @@ -22,10 +22,6 @@ object NewPresAnnFileAvailableMsg { val NAME = "NewPresAnnFileAvailableMsg" } case class NewPresAnnFileAvailableMsg(header: BbbClientMsgHeader, body: NewPresAnnFileAvailableMsgBody) extends StandardMsg case class NewPresAnnFileAvailableMsgBody(fileURI: String, presId: String) -object NewPresAnnFileAvailableEvtMsg { val NAME = "NewPresAnnFileAvailableEvtMsg" } -case class NewPresAnnFileAvailableEvtMsg(header: BbbClientMsgHeader, body: NewPresAnnFileAvailableEvtMsgBody) extends BbbCoreMsg -case class NewPresAnnFileAvailableEvtMsgBody(fileURI: String, presId: String) - // ------------ bbb-common-web to akka-apps ------------ // ------------ akka-apps to client ------------ @@ -40,4 +36,13 @@ case class PresenterUnassignedEvtMsgBody(intId: String, name: String, assignedBy object NewPresentationEvtMsg { val NAME = "NewPresentationEvtMsg" } case class NewPresentationEvtMsg(header: BbbClientMsgHeader, body: NewPresentationEvtMsgBody) extends BbbCoreMsg case class NewPresentationEvtMsgBody(presentation: PresentationVO) + +object NewPresAnnFileAvailableEvtMsg { val NAME = "NewPresAnnFileAvailableEvtMsg" } +case class NewPresAnnFileAvailableEvtMsg(header: BbbClientMsgHeader, body: NewPresAnnFileAvailableEvtMsgBody) extends BbbCoreMsg +case class NewPresAnnFileAvailableEvtMsgBody(fileURI: String, presId: String) + +object CaptureSharedNotesReqEvtMsg { val NAME = "CaptureSharedNotesReqEvtMsg" } +case class CaptureSharedNotesReqEvtMsg(header: BbbClientMsgHeader, body: CaptureSharedNotesReqEvtMsgBody) extends BbbCoreMsg +case class CaptureSharedNotesReqEvtMsgBody(parentMeetingId: String) + // ------------ akka-apps to client ------------ diff --git a/bigbluebutton-html5/imports/api/pads/server/eventHandlers.js b/bigbluebutton-html5/imports/api/pads/server/eventHandlers.js index fb14a79f99..482ab80c0a 100644 --- a/bigbluebutton-html5/imports/api/pads/server/eventHandlers.js +++ b/bigbluebutton-html5/imports/api/pads/server/eventHandlers.js @@ -6,6 +6,7 @@ import padUpdated from './handlers/padUpdated'; import padContent from './handlers/padContent'; import padTail from './handlers/padTail'; import sessionDeleted from './handlers/sessionDeleted'; +import captureSharedNotes from './handlers/captureSharedNotes'; RedisPubSub.on('PadGroupCreatedRespMsg', groupCreated); RedisPubSub.on('PadCreatedRespMsg', padCreated); @@ -14,3 +15,4 @@ RedisPubSub.on('PadUpdatedEvtMsg', padUpdated); RedisPubSub.on('PadContentEvtMsg', padContent); RedisPubSub.on('PadTailEvtMsg', padTail); RedisPubSub.on('PadSessionDeletedEvtMsg', sessionDeleted); +RedisPubSub.on('CaptureSharedNotesReqEvtMsg', captureSharedNotes); diff --git a/bigbluebutton-html5/imports/api/pads/server/handlers/captureSharedNotes.js b/bigbluebutton-html5/imports/api/pads/server/handlers/captureSharedNotes.js new file mode 100644 index 0000000000..b147bf4521 --- /dev/null +++ b/bigbluebutton-html5/imports/api/pads/server/handlers/captureSharedNotes.js @@ -0,0 +1,13 @@ +import { check } from 'meteor/check'; +import padCapture from '../methods/padCapture'; + +export default function captureSharedNotes({ body }, meetingId) { + check(body, Object); + check(meetingId, String); + + const { parentMeetingId } = body; + + check(parentMeetingId, String); + + padCapture(meetingId, parentMeetingId); +} diff --git a/bigbluebutton-html5/imports/api/pads/server/methods/padCapture.js b/bigbluebutton-html5/imports/api/pads/server/methods/padCapture.js new file mode 100644 index 0000000000..5f60ece7d5 --- /dev/null +++ b/bigbluebutton-html5/imports/api/pads/server/methods/padCapture.js @@ -0,0 +1,43 @@ +import { check } from 'meteor/check'; +import Pads from '/imports/api/pads'; +import RedisPubSub from '/imports/startup/server/redis'; +import Logger from '/imports/startup/server/logger'; + +export default function padCapture(meetingId, parentMeetingId) { + const REDIS_CONFIG = Meteor.settings.private.redis; + const CHANNEL = REDIS_CONFIG.channels.toAkkaApps; + const EVENT_NAME = 'PadCapturePubMsg'; + const EXTERNAL_ID = Meteor.settings.public.notes.id; + try { + check(meetingId, String); + check(parentMeetingId, String); + + const pad = Pads.findOne( + { + meetingId, + externalId: EXTERNAL_ID, + }, + { + fields: { + padId: 1, + }, + }, + ); + + const payload = { + parentMeetingId, + padId: pad.padId, + }; + + Logger.info(`Sending PadCapturePubMsg for meetingId=${meetingId} parentMeetingId=${parentMeetingId} padId=${pad.padId}`); + + if (pad && pad.padId) { + return RedisPubSub.publishMeetingMessage(CHANNEL, EVENT_NAME, parentMeetingId, payload); + } + + return null; + } catch (err) { + Logger.error(`Exception while invoking method padCapture ${err.stack}`); + return null; + } +}