diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendMessageToBreakoutRoomInternalMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendMessageToBreakoutRoomInternalMsgHdlr.scala index b6dd2a80c6..484e1ce5db 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendMessageToBreakoutRoomInternalMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendMessageToBreakoutRoomInternalMsgHdlr.scala @@ -20,7 +20,7 @@ trait SendMessageToBreakoutRoomInternalMsgHdlr { } yield { val groupChatMsgFromUser = GroupChatMsgFromUser(sender.id, sender.copy(name = msg.senderName), true, msg.msg) val gcm = GroupChatApp.toGroupChatMessage(sender.copy(name = msg.senderName), groupChatMsgFromUser) - val gcs = GroupChatApp.addGroupChatMessage(chat, state.groupChats, gcm) + val gcs = GroupChatApp.addGroupChatMessage(liveMeeting.props.meetingProp.intId, chat, state.groupChats, gcm) val event = buildGroupChatMessageBroadcastEvtMsg( liveMeeting.props.meetingProp.intId, diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/CreateDefaultPublicGroupChat.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/CreateDefaultPublicGroupChat.scala index 3d7620fb15..d631aec03f 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/CreateDefaultPublicGroupChat.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/CreateDefaultPublicGroupChat.scala @@ -2,6 +2,7 @@ package org.bigbluebutton.core.apps.groupchats import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.core.bus.MessageBus +import org.bigbluebutton.core.db.ChatDAO import org.bigbluebutton.core.domain.MeetingState2x import org.bigbluebutton.core.models.GroupChat import org.bigbluebutton.core.running.LiveMeeting @@ -33,6 +34,7 @@ trait CreateDefaultPublicGroupChat { bus.outGW.send(respMsg) val groupChats = state.groupChats.add(groupChat) + ChatDAO.insert(liveMeeting.props.meetingProp.intId, groupChat) state.update(groupChats) } } 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 bd72755dbc..43539868b0 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 @@ -7,6 +7,7 @@ import org.bigbluebutton.core.models.GroupChat import org.bigbluebutton.core.running.LiveMeeting import org.bigbluebutton.core.apps.PermissionCheck import org.bigbluebutton.SystemConfiguration +import org.bigbluebutton.core.db.ChatDAO import org.bigbluebutton.core.models.Users2x import org.bigbluebutton.core.models.Roles import org.bigbluebutton.core2.MeetingStatus2x @@ -66,6 +67,7 @@ trait CreateGroupChatReqMsgHdlr extends SystemConfiguration { sendMessages(msg, gc, liveMeeting, bus) val groupChats = state.groupChats.add(gc) + ChatDAO.insert(liveMeeting.props.meetingProp.intId, gc) state.update(groupChats) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/GroupChat.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/GroupChat.scala index d61cc7db67..2d5df67fa8 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/GroupChat.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/GroupChat.scala @@ -1,6 +1,7 @@ package org.bigbluebutton.core.apps.groupchats import org.bigbluebutton.common2.msgs.{ GroupChatAccess, GroupChatMsgFromUser, GroupChatMsgToUser, GroupChatUser } +import org.bigbluebutton.core.db.ChatMessageDAO import org.bigbluebutton.core.domain.MeetingState2x import org.bigbluebutton.core.models._ import org.bigbluebutton.core.running.LiveMeeting @@ -26,8 +27,9 @@ object GroupChatApp { sender = msg.sender, chatEmphasizedText = msg.chatEmphasizedText, message = msg.message) } - def addGroupChatMessage(chat: GroupChat, chats: GroupChats, + def addGroupChatMessage(meetingId: String, chat: GroupChat, chats: GroupChats, msg: GroupChatMessage): GroupChats = { + ChatMessageDAO.insert(meetingId, chat.id, msg) val c = chat.add(msg) chats.update(c) } @@ -71,7 +73,7 @@ object GroupChatApp { } yield { val gcm1 = GroupChatApp.toGroupChatMessage(sender, msg) - val gcs1 = GroupChatApp.addGroupChatMessage(chat, state.groupChats, gcm1) + val gcs1 = GroupChatApp.addGroupChatMessage(liveMeeting.props.meetingProp.intId, chat, state.groupChats, gcm1) state.update(gcs1) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SendGroupChatMessageMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SendGroupChatMessageMsgHdlr.scala index aa522c4db6..66ff671225 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SendGroupChatMessageMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SendGroupChatMessageMsgHdlr.scala @@ -49,7 +49,7 @@ trait SendGroupChatMessageMsgHdlr extends HandlerHelpers { if ((chatIsPrivate && userIsAParticipant) || !chatIsPrivate) { val gcm = GroupChatApp.toGroupChatMessage(sender, msg.body.msg) - val gcs = GroupChatApp.addGroupChatMessage(chat, state.groupChats, gcm) + val gcs = GroupChatApp.addGroupChatMessage(liveMeeting.props.meetingProp.intId, chat, state.groupChats, gcm) val event = buildGroupChatMessageBroadcastEvtMsg( liveMeeting.props.meetingProp.intId, diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatDAO.scala new file mode 100644 index 0000000000..60901fa2b1 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatDAO.scala @@ -0,0 +1,56 @@ +package org.bigbluebutton.core.db + +import slick.jdbc.PostgresProfile.api._ +import org.bigbluebutton.core.models.GroupChat + +import scala.concurrent.ExecutionContext.Implicits.global +import scala.util.{ Failure, Success } + +case class ChatDbModel( + chatId: String, + meetingId: String, + access: String, + createdBy: String, +// participants: List[String], +// users: List[String] +) + +class ChatDbTableDef(tag: Tag) extends Table[ChatDbModel](tag, None, "chat") { + val chatId = column[String]("chatId", O.PrimaryKey) + val meetingId = column[String]("meetingId", O.PrimaryKey) + val access = column[String]("access") + val createdBy = column[String]("createdBy") +// val participants = column[List[String]]("participants") +// val users = column[List[String]]("users") + // val meeting = foreignKey("chat_meeting_fk", (meetingId), ChatDbTableDef.meetings)(_.meetingId, onDelete = ForeignKeyAction.Cascade) + override def * = (chatId, meetingId, access, createdBy) <> (ChatDbModel.tupled, ChatDbModel.unapply) +} + +object ChatDAO { + def insert(meetingId: String, groupChat: GroupChat) = { + DatabaseConnection.db.run( + TableQuery[ChatDbTableDef].insertOrUpdate( + ChatDbModel( + chatId = groupChat.id, + meetingId = meetingId, + access = groupChat.access, + createdBy = groupChat.createdBy.id, +// participants = groupChat.users.map(u => u.id).toList, +// users = groupChat.users.map(u => u.id).toList + ) + ) + ).onComplete { + case Success(rowsAffected) => { + println(s"$rowsAffected row(s) inserted on Chat table!") + + for { + user <- groupChat.users + } yield { + ChatUserDAO.insert(meetingId, groupChat.id, user) + } + + } + case Failure(e) => println(s"Error inserting Chat: $e") + } + } +} \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatMessageDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatMessageDAO.scala new file mode 100644 index 0000000000..9e39c1c5d6 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatMessageDAO.scala @@ -0,0 +1,61 @@ +package org.bigbluebutton.core.db + +import slick.jdbc.PostgresProfile.api._ +import org.bigbluebutton.core.models.GroupChatMessage + +import scala.concurrent.ExecutionContext.Implicits.global +import scala.util.{ Failure, Success } + +case class ChatMessageDbModel( + messageId: String, + chatId: String, + meetingId: String, + correlationId: String, + createdTime: Long, + chatEmphasizedText: Boolean, + message: String, + senderId: String, + senderName: String, + senderRole: String +) + +class ChatMessageDbTableDef(tag: Tag) extends Table[ChatMessageDbModel](tag, None, "chat_message") { + val messageId = column[String]("messageId", O.PrimaryKey) + val chatId = column[String]("chatId") + val meetingId = column[String]("meetingId") + val correlationId = column[String]("correlationId") + val createdTime = column[Long]("createdTime") + val chatEmphasizedText = column[Boolean]("chatEmphasizedText") + val message = column[String]("message") + val senderId = column[String]("senderId") + val senderName = column[String]("senderName") + val senderRole = column[String]("senderRole") + // val chat = foreignKey("chat_message_chat_fk", (chatId, meetingId), ChatTable.chats)(c => (c.chatId, c.meetingId), onDelete = ForeignKeyAction.Cascade) + // val sender = foreignKey("chat_message_sender_fk", senderId, UserTable.users)(_.userId, onDelete = ForeignKeyAction.SetNull) + + override def * = (messageId, chatId, meetingId, correlationId, createdTime, chatEmphasizedText, message, senderId, senderName, senderRole) <> (ChatMessageDbModel.tupled, ChatMessageDbModel.unapply) +} + +object ChatMessageDAO { + def insert(meetingId: String, chatId: String, groupChatMessage: GroupChatMessage) = { + DatabaseConnection.db.run( + TableQuery[ChatMessageDbTableDef].insertOrUpdate( + ChatMessageDbModel( + messageId = groupChatMessage.id, + chatId = chatId, + meetingId = meetingId, + correlationId = groupChatMessage.correlationId, + createdTime = groupChatMessage.timestamp, + chatEmphasizedText = groupChatMessage.chatEmphasizedText, + message = groupChatMessage.message, + senderId = groupChatMessage.sender.id, + senderName = groupChatMessage.sender.name, + senderRole = groupChatMessage.sender.role, + ) + ) + ).onComplete { + case Success(rowsAffected) => println(s"$rowsAffected row(s) inserted on ChatMessage table!") + case Failure(e) => println(s"Error inserting ChatMessage: $e") + } + } +} \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatUserDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatUserDAO.scala new file mode 100644 index 0000000000..6d8a0b90d5 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatUserDAO.scala @@ -0,0 +1,49 @@ +package org.bigbluebutton.core.db + +import slick.jdbc.PostgresProfile.api._ +import org.bigbluebutton.common2.msgs.GroupChatUser + +import scala.concurrent.ExecutionContext.Implicits.global +import scala.util.{ Failure, Success } + +case class ChatUserDbModel( + chatId: String, + meetingId: String, + userId: String, + lastSeenAt: Long, + userName: String, + userRole: String +) + +class ChatUserDbTableDef(tag: Tag) extends Table[ChatUserDbModel](tag, None, "chat_user") { + val chatId = column[String]("chatId", O.PrimaryKey) + val meetingId = column[String]("meetingId", O.PrimaryKey) + val userId = column[String]("userId", O.PrimaryKey) + val lastSeenAt = column[Long]("lastSeenAt") + val userName = column[String]("userName") + val userRole = column[String]("userRole") + // val chat = foreignKey("chat_message_chat_fk", (chatId, meetingId), ChatTable.chats)(c => (c.chatId, c.meetingId), onDelete = ForeignKeyAction.Cascade) + // val sender = foreignKey("chat_message_sender_fk", senderId, UserTable.users)(_.userId, onDelete = ForeignKeyAction.SetNull) + + override def * = (chatId, meetingId, userId, lastSeenAt, userName, userRole) <> (ChatUserDbModel.tupled, ChatUserDbModel.unapply) +} + +object ChatUserDAO { + def insert(meetingId: String, chatId: String, groupChatUser: GroupChatUser) = { + DatabaseConnection.db.run( + TableQuery[ChatUserDbTableDef].insertOrUpdate( + ChatUserDbModel( + userId = groupChatUser.id, + chatId = chatId, + meetingId = meetingId, + lastSeenAt = 0, + userName = groupChatUser.name, + userRole = groupChatUser.role + ) + ) + ).onComplete { + case Success(rowsAffected) => println(s"$rowsAffected row(s) inserted on ChatUser table!") + case Failure(e) => println(s"Error inserting ChatUser: $e") + } + } +} \ No newline at end of file diff --git a/bbb-graphql-client-test/src/App.js b/bbb-graphql-client-test/src/App.js index a3e201bf93..030f722346 100644 --- a/bbb-graphql-client-test/src/App.js +++ b/bbb-graphql-client-test/src/App.js @@ -10,10 +10,14 @@ import TotalOfModerators from './TotalOfModerators'; import TotalOfViewers from './TotalOfViewers'; import TotalOfUsersTalking from './TotalOfUsersTalking'; import TotalOfUniqueNames from './TotalOfUniqueNames'; +import ChatMessages from "./ChatMessages"; +import ChatsInfo from "./ChatsInfo"; +import ChatPublicMessages from "./ChatPublicMessages"; function App() { const [sessionToken, setSessionToken] = useState(null); + const [userId, setUserId] = useState(null); const [joining, setJoining] = useState(false); const [graphqlClient, setGraphqlClient] = useState(null); const [enterApiResponse, setEnterApiResponse] = useState(''); @@ -33,6 +37,9 @@ function App() { .then((json) => { console.log(json.response); setEnterApiResponse(json.response.returncode); + if(json?.response?.internalUserID) { + setUserId(json.response.internalUserID); + } }); } @@ -80,8 +87,17 @@ function App() { }} > + User Id: {userId} +
+
+ +
+ +
+ +
diff --git a/bbb-graphql-client-test/src/ChatMessages.js b/bbb-graphql-client-test/src/ChatMessages.js new file mode 100644 index 0000000000..7c2ce016c0 --- /dev/null +++ b/bbb-graphql-client-test/src/ChatMessages.js @@ -0,0 +1,52 @@ +import {useSubscription, gql, useQuery} from '@apollo/client'; + import React, { useState } from "react"; + +export default function ChatMessages() { + const { loading, error, data } = useSubscription( + gql`subscription { + chat_message_private(order_by: {createdTime: asc}) { + chatEmphasizedText + chatId + correlationId + createdTime + createdTimeAsDate + meetingId + message + messageId + senderId + senderName + senderRole + } + }` + ); + + return !loading && !error && + ( + + + + + + + + + + + + + {data.chat_message_private.map((curr) => { + console.log('message', curr); + return ( + + {/**/} + + + + + + ); + })} + +
Private Chat Messages
ChatIdSenderMessageSent At
{user.userId}{curr.chatId}{curr.senderName}{curr.message}{curr.createdTimeAsDate} ({curr.createdTime})
); +} + diff --git a/bbb-graphql-client-test/src/ChatPublicMessages.js b/bbb-graphql-client-test/src/ChatPublicMessages.js new file mode 100644 index 0000000000..ed187f937e --- /dev/null +++ b/bbb-graphql-client-test/src/ChatPublicMessages.js @@ -0,0 +1,51 @@ +import {useSubscription, gql, useQuery} from '@apollo/client'; + import React, { useState } from "react"; + +export default function ChatPublicMessages() { + const { loading, error, data } = useSubscription( + gql`subscription { + chat_message_public(order_by: {createdTime: asc}) { + chatId + chatEmphasizedText + correlationId + createdTime + createdTimeAsDate + meetingId + message + messageId + senderId + senderName + senderRole + } + }` + ); + + return !loading && !error && + ( + + + + + + + + + + + + + {data.chat_message_public.map((curr) => { + console.log('message', curr); + return ( + + + + + + + ); + })} + +
Public Chat Messages
ChatIdSenderMessageSent At
{curr.chatId}{curr.senderName}{curr.message}{curr.createdTimeAsDate} ({curr.createdTime})
); +} + diff --git a/bbb-graphql-client-test/src/ChatsInfo.js b/bbb-graphql-client-test/src/ChatsInfo.js new file mode 100644 index 0000000000..723d2e8752 --- /dev/null +++ b/bbb-graphql-client-test/src/ChatsInfo.js @@ -0,0 +1,48 @@ +import {useSubscription, gql, useQuery} from '@apollo/client'; + import React, { useState } from "react"; + +export default function ChatsInfo() { + const { loading, error, data } = useSubscription( + gql`subscription { + chat { + chatId + meetingId + participantsId + participantsName + totalMessages + totalUnread + } + }` + ); + + return !loading && !error && + ( + + + + + + + + + + + + + + {data.chat.map((curr) => { + console.log('chat', curr); + return ( + + + + + + + + ); + })} + +
Chats available
IdMeetingParticipantsTotal MgsUnread
{curr.chatId}{curr.meetingId}{curr.participantsName}{curr.totalMessages}{curr.totalUnread}
); +} + diff --git a/bbb-graphql-server/bbb_schema.sql b/bbb-graphql-server/bbb_schema.sql index fd43938eb5..1fdb4fc5cc 100644 --- a/bbb-graphql-server/bbb_schema.sql +++ b/bbb-graphql-server/bbb_schema.sql @@ -223,3 +223,83 @@ SELECT "user_breakoutRoom" .* FROM "user_breakoutRoom" JOIN "user" u ON u."userId" = "user_breakoutRoom"."userId"; + +-- ===================== CHAT TABLES + +DROP VIEW IF EXISTS "v_chat"; +DROP VIEW IF EXISTS "v_chat_message_public"; +DROP VIEW IF EXISTS "v_chat_message_private"; +DROP TABLE IF EXISTS "chat_user"; +DROP TABLE IF EXISTS "chat_message"; +DROP TABLE IF EXISTS "chat"; + +CREATE TABLE "chat" ( + "chatId" varchar(100), + "meetingId" varchar(100) REFERENCES "meeting"("meetingId") ON DELETE CASCADE, + "access" varchar(20), + "createdBy" varchar(25), + CONSTRAINT "chat_pkey" PRIMARY KEY ("chatId","meetingId") +); + +CREATE INDEX "chat_meetingId" ON "chat"("meetingId"); + +CREATE TABLE "chat_user" ( + "chatId" varchar(100), + "meetingId" varchar(100), + "userId" varchar(100), + "userName" varchar(255), + "userRole" varchar(20), + "lastSeenAt" bigint, + CONSTRAINT "chat_user_pkey" PRIMARY KEY ("chatId","meetingId","userId"), + CONSTRAINT chat_fk FOREIGN KEY ("chatId", "meetingId") REFERENCES "chat"("chatId", "meetingId") ON DELETE CASCADE +); + +CREATE INDEX "chat_user_chatId" ON "chat_user"("chatId","meetingId"); + +CREATE TABLE "chat_message" ( + "messageId" varchar(100) PRIMARY KEY, + "chatId" varchar(100), + "meetingId" varchar(100), + "correlationId" varchar(100), + "createdTime" bigint, + "chatEmphasizedText" boolean, + "message" TEXT, + "senderId" varchar(100), + "senderName" varchar(255), + "senderRole" varchar(20), + CONSTRAINT chat_fk FOREIGN KEY ("chatId", "meetingId") REFERENCES "chat"("chatId", "meetingId") ON DELETE CASCADE +); + +CREATE INDEX "chat_message_chatId" ON "chat_message"("chatId","meetingId"); + + +CREATE OR REPLACE VIEW "v_chat" AS +SELECT cu."userId", + chat."meetingId", + chat."chatId", + array_remove(array_agg(DISTINCT chat_with."userId"),NULL) "participantsId", + string_agg(DISTINCT chat_with."userName" ,', ') AS "participantsName", + count(DISTINCT cm."messageId") "totalMessages", + sum(CASE WHEN cm."createdTime" > cu."lastSeenAt" THEN 1 ELSE 0 end) "totalUnread" +FROM "user" +LEFT JOIN "chat_user" cu ON cu."meetingId" = "user"."meetingId" AND cu."userId" = "user"."userId" +JOIN "chat" ON cu."meetingId" = chat."meetingId" AND (cu."chatId" = chat."chatId" OR chat."chatId" = 'MAIN-PUBLIC-GROUP-CHAT') +LEFT JOIN "chat_user" chat_with ON chat_with."meetingId" = chat."meetingId" AND chat_with."chatId" = chat."chatId" AND chat_with."userId" != cu."userId" +LEFT JOIN chat_message cm ON cm."meetingId" = chat."meetingId" AND cm."chatId" = chat."chatId" +GROUP BY cu."userId", chat."meetingId", chat."chatId"; + + +CREATE OR REPLACE VIEW "v_chat_message_public" AS +SELECT cm.*, to_timestamp("createdTime" / 1000) AS "createdTimeAsDate" +FROM chat_message cm +WHERE cm."chatId" = 'MAIN-PUBLIC-GROUP-CHAT'; + +CREATE OR REPLACE VIEW "v_chat_message_private" AS +SELECT cu."userId", cm.*, to_timestamp("createdTime" / 1000) AS "createdTimeAsDate" +FROM chat_message cm +JOIN chat_user cu ON cu."meetingId" = cm."meetingId" AND cu."chatId" = cm."chatId"; + + + + + diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat.yaml new file mode 100644 index 0000000000..397b88a683 --- /dev/null +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat.yaml @@ -0,0 +1,24 @@ +table: + name: v_chat + schema: public +configuration: + column_config: {} + custom_column_names: {} + custom_name: chat + custom_root_fields: {} +select_permissions: + - role: bbb_client + permission: + columns: + - chatId + - meetingId + - participantsId + - participantsName + - totalMessages + - totalUnread + filter: + _and: + - meetingId: + _eq: X-Hasura-MeetingId + - userId: + _eq: X-Hasura-UserId diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat_message_private.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat_message_private.yaml new file mode 100644 index 0000000000..e24c3b17cd --- /dev/null +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat_message_private.yaml @@ -0,0 +1,29 @@ +table: + name: v_chat_message_private + schema: public +configuration: + column_config: {} + custom_column_names: {} + custom_name: chat_message_private + custom_root_fields: {} +select_permissions: + - role: bbb_client + permission: + columns: + - chatEmphasizedText + - chatId + - correlationId + - createdTime + - createdTimeAsDate + - meetingId + - message + - messageId + - senderId + - senderName + - senderRole + filter: + _and: + - meetingId: + _eq: X-Hasura-MeetingId + - userId: + _eq: X-Hasura-UserId diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat_message_public.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat_message_public.yaml new file mode 100644 index 0000000000..c5952f9908 --- /dev/null +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat_message_public.yaml @@ -0,0 +1,26 @@ +table: + name: v_chat_message_public + schema: public +configuration: + column_config: {} + custom_column_names: {} + custom_name: chat_message_public + custom_root_fields: {} +select_permissions: + - role: bbb_client + permission: + columns: + - createdTime + - chatEmphasizedText + - chatId + - correlationId + - meetingId + - messageId + - senderId + - senderName + - senderRole + - message + - createdTimeAsDate + filter: + meetingId: + _eq: X-Hasura-MeetingId diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/tables.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/tables.yaml index 876578c484..bcfb81738a 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/tables.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/tables.yaml @@ -2,6 +2,9 @@ - "!include public_user.yaml" - "!include public_user_camera.yaml" - "!include public_user_voice.yaml" +- "!include public_v_chat.yaml" +- "!include public_v_chat_message_private.yaml" +- "!include public_v_chat_message_public.yaml" - "!include public_v_user_breakoutRoom.yaml" - "!include public_v_user_camera.yaml" - "!include public_v_user_voice.yaml"