mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
Add notifications web module (#28983)
* Add notifications web module * implement getThreadMessage in chat * Save comment mention notification * check if recipient is a real user * move commentMentionDelay * use module-hooks types * remove router * updated collection name GitOrigin-RevId: cf8240c88aac7d7e4de4bf51cfe2608b6b7e7918
This commit is contained in:
committed by
Copybot
parent
387ef81a31
commit
71457d74cb
@@ -62,6 +62,10 @@ export async function getThread(context) {
|
||||
return await callMessageHttpController(context, _getThread)
|
||||
}
|
||||
|
||||
export async function getThreadMessage(context) {
|
||||
return await callMessageHttpController(context, _getThreadMessage)
|
||||
}
|
||||
|
||||
export async function resolveThread(context) {
|
||||
return await callMessageHttpController(context, _resolveThread)
|
||||
}
|
||||
@@ -208,6 +212,30 @@ const _getThread = async (req, res) => {
|
||||
}
|
||||
}
|
||||
|
||||
const _getThreadMessage = async (req, res) => {
|
||||
const { projectId, threadId, messageId } = req.params
|
||||
logger.debug(
|
||||
{ projectId, threadId, messageId },
|
||||
'getting single thread message'
|
||||
)
|
||||
try {
|
||||
const room = await ThreadManager.findThread(projectId, threadId)
|
||||
const message = await MessageManager.getMessage(room._id, messageId)
|
||||
const formattedMsg = MessageFormatter.formatMessageForClientSide(message)
|
||||
|
||||
res.status(200).setBody(formattedMsg)
|
||||
} catch (error) {
|
||||
if (
|
||||
error instanceof ThreadManager.MissingThreadError ||
|
||||
error instanceof MessageManager.MissingMessageError
|
||||
) {
|
||||
res.status(404)
|
||||
return
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
const _resolveThread = async (req, res) => {
|
||||
const { projectId, threadId } = req.params
|
||||
const { user_id: userId } = req.body
|
||||
|
||||
@@ -243,6 +243,20 @@ paths:
|
||||
name: messageId
|
||||
in: path
|
||||
required: true
|
||||
get:
|
||||
summary: Get thread message
|
||||
tags: []
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Message'
|
||||
'404':
|
||||
description: Message not found
|
||||
operationId: getThreadMessage
|
||||
description: Get a specific message by message ID from the thread with Thread ID and Project ID provided
|
||||
delete:
|
||||
summary: Delete message
|
||||
operationId: deleteMessage
|
||||
|
||||
@@ -8,6 +8,12 @@ async function getThread(projectId, threadId) {
|
||||
return await fetchJson(chatApiUrl(`/project/${projectId}/thread/${threadId}`))
|
||||
}
|
||||
|
||||
async function getThreadMessage(projectId, threadId, messageId) {
|
||||
return await fetchJson(
|
||||
chatApiUrl(`/project/${projectId}/thread/${threadId}/messages/${messageId}`)
|
||||
)
|
||||
}
|
||||
|
||||
async function getThreads(projectId) {
|
||||
return await fetchJson(chatApiUrl(`/project/${projectId}/threads`))
|
||||
}
|
||||
@@ -161,6 +167,7 @@ function chatApiUrl(path) {
|
||||
|
||||
module.exports = {
|
||||
getThread: callbackify(getThread),
|
||||
getThreadMessage: callbackify(getThreadMessage),
|
||||
getThreads: callbackify(getThreads),
|
||||
destroyProject: callbackify(destroyProject),
|
||||
sendGlobalMessage: callbackify(sendGlobalMessage),
|
||||
@@ -180,6 +187,7 @@ module.exports = {
|
||||
generateThreadData: callbackify(generateThreadData),
|
||||
promises: {
|
||||
getThread,
|
||||
getThreadMessage,
|
||||
getThreads,
|
||||
destroyProject,
|
||||
sendGlobalMessage,
|
||||
|
||||
@@ -54,6 +54,7 @@ const db = {
|
||||
messages: internalDb.collection('messages'),
|
||||
migrations: internalDb.collection('migrations'),
|
||||
notifications: internalDb.collection('notifications'),
|
||||
emailNotifications: internalDb.collection('emailNotifications'),
|
||||
oauthAccessTokens: internalDb.collection('oauthAccessTokens'),
|
||||
oauthApplications: internalDb.collection('oauthApplications'),
|
||||
oauthAuthorizationCodes: internalDb.collection('oauthAuthorizationCodes'),
|
||||
|
||||
@@ -715,6 +715,10 @@ module.exports = {
|
||||
parseInt(process.env.OVERLEAF_PROJECT_HARD_DELETION_DELAY, 10) ||
|
||||
1000 * 60 * 60 * 24 * 90, // 90 days
|
||||
|
||||
// Delay before sending comment mention notifications
|
||||
commentMentionDelay:
|
||||
parseInt(process.env.COMMENT_MENTION_DELAY_MINUTES) || 30 * 60 * 1000, // 30 minutes
|
||||
|
||||
// Maximum JSON size in HTTP requests
|
||||
// We should be able to process twice the max doc length, to allow for
|
||||
// - the doc content
|
||||
|
||||
@@ -58,6 +58,20 @@ class MockChatApi extends AbstractMockApi {
|
||||
res.json(this.getThread(req.params.project_id, req.params.thread_id))
|
||||
}
|
||||
)
|
||||
this.app.get(
|
||||
'/project/:project_id/thread/:thread_id/messages/:message_id',
|
||||
(req, res) => {
|
||||
const projectId = req.params.project_id
|
||||
const threadId = req.params.thread_id
|
||||
const messageId = req.params.message_id
|
||||
const thread = this.getThread(projectId, threadId)
|
||||
const message = thread.find(msg => msg.id === messageId)
|
||||
if (!message) {
|
||||
return res.status(404).json({ error: 'Message not found' })
|
||||
}
|
||||
res.json(message)
|
||||
}
|
||||
)
|
||||
this.app.post(
|
||||
'/project/:project_id/thread/:thread_id/messages',
|
||||
(req, res) => {
|
||||
|
||||
10
services/web/types/module-hooks.ts
Normal file
10
services/web/types/module-hooks.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Types for module hook events fired across the application
|
||||
*/
|
||||
|
||||
export type CommentAddedEvent = {
|
||||
projectId: string
|
||||
userId: string
|
||||
threadId: string
|
||||
messageId: string
|
||||
}
|
||||
Reference in New Issue
Block a user