mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-23 16:56:07 +00:00
Fix email notifications (#6328)
Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
parent
cc7240c7d9
commit
071551c66f
@ -129,8 +129,8 @@ export function defineNotifications (builder: Builder): void {
|
|||||||
defaultEnabled: false,
|
defaultEnabled: false,
|
||||||
group: chunter.ids.ChunterNotificationGroup,
|
group: chunter.ids.ChunterNotificationGroup,
|
||||||
templates: {
|
templates: {
|
||||||
textTemplate: '{body}',
|
textTemplate: '{sender} replied to {doc}:\n\n{message}',
|
||||||
htmlTemplate: '<p>{body}</p>',
|
htmlTemplate: '<p><b>{sender}</b> replied to {doc}:</p><p>{message}</p><p>{link}</p>',
|
||||||
subjectTemplate: '{title}'
|
subjectTemplate: '{title}'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -556,8 +556,8 @@ export function createModel (builder: Builder): void {
|
|||||||
group: notification.ids.NotificationGroup,
|
group: notification.ids.NotificationGroup,
|
||||||
defaultEnabled: true,
|
defaultEnabled: true,
|
||||||
templates: {
|
templates: {
|
||||||
textTemplate: '{sender} mentioned you in {doc} {message}',
|
textTemplate: '{sender} mentioned you in {doc}: {message}',
|
||||||
htmlTemplate: '<p>{sender}</b> mentioned you in {doc}</p> {message}',
|
htmlTemplate: '<p><b>{sender}</b> mentioned you in {doc}:</p> <p>{message}</p> <p>{link}</p>',
|
||||||
subjectTemplate: 'You were mentioned in {doc}'
|
subjectTemplate: 'You were mentioned in {doc}'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -37,6 +37,10 @@ export function createModel (builder: Builder): void {
|
|||||||
presenter: serverChunter.function.ChatMessageTextPresenter
|
presenter: serverChunter.function.ChatMessageTextPresenter
|
||||||
})
|
})
|
||||||
|
|
||||||
|
builder.mixin(chunter.class.ChatMessage, core.class.Class, serverNotification.mixin.HTMLPresenter, {
|
||||||
|
presenter: serverChunter.function.ChatMessageTextPresenter
|
||||||
|
})
|
||||||
|
|
||||||
builder.mixin<Class<Doc>, ObjectDDParticipant>(
|
builder.mixin<Class<Doc>, ObjectDDParticipant>(
|
||||||
chunter.class.ChatMessage,
|
chunter.class.ChatMessage,
|
||||||
core.class.Class,
|
core.class.Class,
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
"CommonNotificationCollectionRemoved": "{senderName} removed {collection}",
|
"CommonNotificationCollectionRemoved": "{senderName} removed {collection}",
|
||||||
"Sound": "Sound",
|
"Sound": "Sound",
|
||||||
"SoundNotificationsDescription": "Receive sound notifications for events.",
|
"SoundNotificationsDescription": "Receive sound notifications for events.",
|
||||||
"NoAccessToObject": "You no longer have access to this object"
|
"NoAccessToObject": "You no longer have access to this object",
|
||||||
|
"ViewIn": "View in {app}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
"SoundNotificationsDescription": "Reciba notificaciones de sonido para eventos.",
|
"SoundNotificationsDescription": "Reciba notificaciones de sonido para eventos.",
|
||||||
"CommonNotificationCollectionAdded": "{senderName} añadió {collection}",
|
"CommonNotificationCollectionAdded": "{senderName} añadió {collection}",
|
||||||
"CommonNotificationCollectionRemoved": "{senderName} eliminó {collection}",
|
"CommonNotificationCollectionRemoved": "{senderName} eliminó {collection}",
|
||||||
"NoAccessToObject": "Ya no tienes acceso a este objeto"
|
"NoAccessToObject": "Ya no tienes acceso a este objeto",
|
||||||
|
"ViewIn": "Ver en {app}"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -56,6 +56,7 @@
|
|||||||
"SoundNotificationsDescription": "Recevez des notifications sonores pour les événements.",
|
"SoundNotificationsDescription": "Recevez des notifications sonores pour les événements.",
|
||||||
"CommonNotificationCollectionAdded": "{senderName} a ajouté {collection}",
|
"CommonNotificationCollectionAdded": "{senderName} a ajouté {collection}",
|
||||||
"CommonNotificationCollectionRemoved": "{senderName} a supprimé {collection}",
|
"CommonNotificationCollectionRemoved": "{senderName} a supprimé {collection}",
|
||||||
"NoAccessToObject": "Vous n'avez plus accès à cet objet"
|
"NoAccessToObject": "Vous n'avez plus accès à cet objet",
|
||||||
|
"ViewIn": "Voir dans {app}"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -55,6 +55,7 @@
|
|||||||
"SoundNotificationsDescription": "Receba notificações sonoras para eventos.",
|
"SoundNotificationsDescription": "Receba notificações sonoras para eventos.",
|
||||||
"CommonNotificationCollectionAdded": "{senderName} adicionou {collection}",
|
"CommonNotificationCollectionAdded": "{senderName} adicionou {collection}",
|
||||||
"CommonNotificationCollectionRemoved": "{senderName} removeu {collection}",
|
"CommonNotificationCollectionRemoved": "{senderName} removeu {collection}",
|
||||||
"NoAccessToObject": "Você não tem mais acesso a este objeto"
|
"NoAccessToObject": "Você não tem mais acesso a este objeto",
|
||||||
|
"ViewIn": "Ver em {app}"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -56,6 +56,7 @@
|
|||||||
"SoundNotificationsDescription": "Получайте звуковые уведомления о событиях.",
|
"SoundNotificationsDescription": "Получайте звуковые уведомления о событиях.",
|
||||||
"CommonNotificationCollectionAdded": "{senderName} добавил {collection}",
|
"CommonNotificationCollectionAdded": "{senderName} добавил {collection}",
|
||||||
"CommonNotificationCollectionRemoved": "{senderName} удалил {collection}",
|
"CommonNotificationCollectionRemoved": "{senderName} удалил {collection}",
|
||||||
"NoAccessToObject": "У вас больше нет доступа к этому объекту"
|
"NoAccessToObject": "У вас больше нет доступа к этому объекту",
|
||||||
|
"ViewIn": "Посмотреть в {app}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
"SoundNotificationsDescription": "接收事件的声音通知。",
|
"SoundNotificationsDescription": "接收事件的声音通知。",
|
||||||
"CommonNotificationCollectionAdded": "{senderName} 添加了 {collection}",
|
"CommonNotificationCollectionAdded": "{senderName} 添加了 {collection}",
|
||||||
"CommonNotificationCollectionRemoved": "{senderName} 移除了 {collection}",
|
"CommonNotificationCollectionRemoved": "{senderName} 移除了 {collection}",
|
||||||
"NoAccessToObject": "您不再可以访问此对象"
|
"NoAccessToObject": "您不再可以访问此对象",
|
||||||
|
"ViewIn": "在 {app} 中查看"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import activity, { ActivityMessage } from '@hcengineering/activity'
|
import activity, { ActivityMessage } from '@hcengineering/activity'
|
||||||
import chunter from '@hcengineering/chunter'
|
import chunter from '@hcengineering/chunter'
|
||||||
import { getCurrentAccount, groupByArray, IdMap, Ref, SortingOrder, Space } from '@hcengineering/core'
|
import { Doc, getCurrentAccount, groupByArray, IdMap, Ref, SortingOrder, Space } from '@hcengineering/core'
|
||||||
import { DocNotifyContext, InboxNotification, notificationId } from '@hcengineering/notification'
|
import { DocNotifyContext, InboxNotification, notificationId } from '@hcengineering/notification'
|
||||||
import { ActionContext, createQuery, getClient } from '@hcengineering/presentation'
|
import { ActionContext, createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import {
|
import {
|
||||||
@ -31,7 +31,8 @@
|
|||||||
Separator,
|
Separator,
|
||||||
TabItem,
|
TabItem,
|
||||||
TabList,
|
TabList,
|
||||||
closePanel
|
closePanel,
|
||||||
|
getCurrentLocation
|
||||||
} from '@hcengineering/ui'
|
} from '@hcengineering/ui'
|
||||||
import view, { decodeObjectURI } from '@hcengineering/view'
|
import view, { decodeObjectURI } from '@hcengineering/view'
|
||||||
import { parseLinkId } from '@hcengineering/view-resources'
|
import { parseLinkId } from '@hcengineering/view-resources'
|
||||||
@ -143,11 +144,23 @@
|
|||||||
|
|
||||||
$: filteredData = filterData(filter, selectedTabId, inboxData, $contextByIdStore)
|
$: filteredData = filterData(filter, selectedTabId, inboxData, $contextByIdStore)
|
||||||
|
|
||||||
locationStore.subscribe((newLocation) => {
|
const unsubscribeLoc = locationStore.subscribe((newLocation) => {
|
||||||
void syncLocation(newLocation)
|
void syncLocation(newLocation, $contextByDocStore)
|
||||||
})
|
})
|
||||||
|
|
||||||
async function syncLocation (newLocation: Location): Promise<void> {
|
let isContextsLoaded = false
|
||||||
|
|
||||||
|
const unsubscribeContexts = contextByDocStore.subscribe((docs) => {
|
||||||
|
if (selectedContext !== undefined || docs.size === 0 || isContextsLoaded) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const loc = getCurrentLocation()
|
||||||
|
void syncLocation(loc, docs)
|
||||||
|
isContextsLoaded = true
|
||||||
|
})
|
||||||
|
|
||||||
|
async function syncLocation (newLocation: Location, contextByDoc: Map<Ref<Doc>, DocNotifyContext>): Promise<void> {
|
||||||
const loc = await resolveLocation(newLocation)
|
const loc = await resolveLocation(newLocation)
|
||||||
if (loc?.loc.path[2] !== notificationId) {
|
if (loc?.loc.path[2] !== notificationId) {
|
||||||
return
|
return
|
||||||
@ -161,7 +174,7 @@
|
|||||||
|
|
||||||
const [id, _class] = decodeObjectURI(loc?.loc.path[3] ?? '')
|
const [id, _class] = decodeObjectURI(loc?.loc.path[3] ?? '')
|
||||||
const _id = await parseLinkId(linkProviders, id, _class)
|
const _id = await parseLinkId(linkProviders, id, _class)
|
||||||
const context = _id ? $contextByDocStore.get(_id) : undefined
|
const context = _id ? contextByDoc.get(_id) : undefined
|
||||||
|
|
||||||
selectedContextId = context?._id
|
selectedContextId = context?._id
|
||||||
|
|
||||||
@ -357,7 +370,11 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
$: $deviceInfo.replacedPanel = replacedPanel
|
$: $deviceInfo.replacedPanel = replacedPanel
|
||||||
onDestroy(() => ($deviceInfo.replacedPanel = undefined))
|
onDestroy(() => {
|
||||||
|
$deviceInfo.replacedPanel = undefined
|
||||||
|
unsubscribeLoc()
|
||||||
|
unsubscribeContexts()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ActionContext
|
<ActionContext
|
||||||
|
@ -427,7 +427,8 @@ const notification = plugin(notificationId, {
|
|||||||
CommonNotificationCollectionRemoved: '' as IntlString,
|
CommonNotificationCollectionRemoved: '' as IntlString,
|
||||||
SoundNotificationsDescription: '' as IntlString,
|
SoundNotificationsDescription: '' as IntlString,
|
||||||
Sound: '' as IntlString,
|
Sound: '' as IntlString,
|
||||||
NoAccessToObject: '' as IntlString
|
NoAccessToObject: '' as IntlString,
|
||||||
|
ViewIn: '' as IntlString
|
||||||
},
|
},
|
||||||
function: {
|
function: {
|
||||||
Notify: '' as Resource<NotifyFunc>,
|
Notify: '' as Resource<NotifyFunc>,
|
||||||
|
@ -53,7 +53,7 @@ import {
|
|||||||
getDocCollaborators,
|
getDocCollaborators,
|
||||||
getMixinTx
|
getMixinTx
|
||||||
} from '@hcengineering/server-notification-resources'
|
} from '@hcengineering/server-notification-resources'
|
||||||
import { markupToText, stripTags } from '@hcengineering/text'
|
import { markupToHTML, markupToText, stripTags } from '@hcengineering/text'
|
||||||
import { workbenchId } from '@hcengineering/workbench'
|
import { workbenchId } from '@hcengineering/workbench'
|
||||||
|
|
||||||
import { NOTIFICATION_BODY_SIZE } from '@hcengineering/server-notification'
|
import { NOTIFICATION_BODY_SIZE } from '@hcengineering/server-notification'
|
||||||
@ -91,6 +91,10 @@ export async function ChatMessageTextPresenter (doc: ChatMessage): Promise<strin
|
|||||||
return markupToText(doc.message)
|
return markupToText(doc.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function ChatMessageHtmlPresenter (doc: ChatMessage): Promise<string> {
|
||||||
|
return markupToHTML(doc.message)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
@ -580,6 +584,7 @@ export default async () => ({
|
|||||||
ChannelTextPresenter: channelTextPresenter,
|
ChannelTextPresenter: channelTextPresenter,
|
||||||
ChunterNotificationContentProvider: getChunterNotificationContent,
|
ChunterNotificationContentProvider: getChunterNotificationContent,
|
||||||
ChatMessageTextPresenter,
|
ChatMessageTextPresenter,
|
||||||
|
ChatMessageHtmlPresenter,
|
||||||
JoinChannelTypeMatch
|
JoinChannelTypeMatch
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -40,6 +40,7 @@ export default plugin(serverChunterId, {
|
|||||||
ChannelTextPresenter: '' as Resource<Presenter>,
|
ChannelTextPresenter: '' as Resource<Presenter>,
|
||||||
ChunterNotificationContentProvider: '' as Resource<NotificationContentProvider>,
|
ChunterNotificationContentProvider: '' as Resource<NotificationContentProvider>,
|
||||||
ChatMessageTextPresenter: '' as Resource<Presenter>,
|
ChatMessageTextPresenter: '' as Resource<Presenter>,
|
||||||
|
ChatMessageHtmlPresenter: '' as Resource<Presenter>,
|
||||||
JoinChannelTypeMatch: '' as TypeMatchFunc
|
JoinChannelTypeMatch: '' as TypeMatchFunc
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -37,13 +37,15 @@
|
|||||||
"@types/jest": "^29.5.5"
|
"@types/jest": "^29.5.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@hcengineering/activity": "^0.6.0",
|
||||||
|
"@hcengineering/contact": "^0.6.24",
|
||||||
"@hcengineering/core": "^0.6.32",
|
"@hcengineering/core": "^0.6.32",
|
||||||
|
"@hcengineering/gmail": "^0.6.22",
|
||||||
|
"@hcengineering/notification": "^0.6.23",
|
||||||
"@hcengineering/platform": "^0.6.11",
|
"@hcengineering/platform": "^0.6.11",
|
||||||
"@hcengineering/server-core": "^0.6.1",
|
"@hcengineering/server-core": "^0.6.1",
|
||||||
"@hcengineering/server-notification": "^0.6.1",
|
"@hcengineering/server-notification": "^0.6.1",
|
||||||
"@hcengineering/server-notification-resources": "^0.6.0",
|
"@hcengineering/server-notification-resources": "^0.6.0",
|
||||||
"@hcengineering/notification": "^0.6.23",
|
"@hcengineering/text": "^0.6.5"
|
||||||
"@hcengineering/contact": "^0.6.24",
|
|
||||||
"@hcengineering/gmail": "^0.6.22"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ import serverNotification, {
|
|||||||
} from '@hcengineering/server-notification'
|
} from '@hcengineering/server-notification'
|
||||||
import { getContentByTemplate } from '@hcengineering/server-notification-resources'
|
import { getContentByTemplate } from '@hcengineering/server-notification-resources'
|
||||||
import { getMetadata } from '@hcengineering/platform'
|
import { getMetadata } from '@hcengineering/platform'
|
||||||
|
import { ActivityMessage } from '@hcengineering/activity'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
@ -134,7 +135,8 @@ async function notifyByEmail (
|
|||||||
doc: Doc | undefined,
|
doc: Doc | undefined,
|
||||||
sender: SenderInfo,
|
sender: SenderInfo,
|
||||||
receiver: ReceiverInfo,
|
receiver: ReceiverInfo,
|
||||||
data: InboxNotification
|
data: InboxNotification,
|
||||||
|
message?: ActivityMessage
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const account = receiver.account
|
const account = receiver.account
|
||||||
|
|
||||||
@ -145,8 +147,7 @@ async function notifyByEmail (
|
|||||||
const senderPerson = sender.person
|
const senderPerson = sender.person
|
||||||
const senderName = senderPerson !== undefined ? formatName(senderPerson.name, control.branding?.lastNameFirst) : ''
|
const senderName = senderPerson !== undefined ? formatName(senderPerson.name, control.branding?.lastNameFirst) : ''
|
||||||
|
|
||||||
const content = await getContentByTemplate(doc, senderName, type, control, '', data)
|
const content = await getContentByTemplate(doc, senderName, type, control, '', data, message)
|
||||||
|
|
||||||
if (content !== undefined) {
|
if (content !== undefined) {
|
||||||
await sendEmailNotification(control.ctx, content.text, content.html, content.subject, account.email)
|
await sendEmailNotification(control.ctx, content.text, content.html, content.subject, account.email)
|
||||||
}
|
}
|
||||||
@ -158,7 +159,8 @@ const SendEmailNotifications: NotificationProviderFunc = async (
|
|||||||
object: Doc,
|
object: Doc,
|
||||||
data: InboxNotification,
|
data: InboxNotification,
|
||||||
receiver: ReceiverInfo,
|
receiver: ReceiverInfo,
|
||||||
sender: SenderInfo
|
sender: SenderInfo,
|
||||||
|
message?: ActivityMessage
|
||||||
): Promise<Tx[]> => {
|
): Promise<Tx[]> => {
|
||||||
if (types.length === 0) {
|
if (types.length === 0) {
|
||||||
return []
|
return []
|
||||||
@ -169,7 +171,7 @@ const SendEmailNotifications: NotificationProviderFunc = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const type of types) {
|
for (const type of types) {
|
||||||
await notifyByEmail(control, type._id, object, sender, receiver, data)
|
await notifyByEmail(control, type._id, object, sender, receiver, data, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
return []
|
return []
|
||||||
|
@ -80,7 +80,7 @@ import serverNotification, {
|
|||||||
SenderInfo
|
SenderInfo
|
||||||
} from '@hcengineering/server-notification'
|
} from '@hcengineering/server-notification'
|
||||||
import serverView from '@hcengineering/server-view'
|
import serverView from '@hcengineering/server-view'
|
||||||
import { stripTags } from '@hcengineering/text'
|
import { markupToText, stripTags } from '@hcengineering/text'
|
||||||
import { encodeObjectURI } from '@hcengineering/view'
|
import { encodeObjectURI } from '@hcengineering/view'
|
||||||
import { workbenchId } from '@hcengineering/workbench'
|
import { workbenchId } from '@hcengineering/workbench'
|
||||||
import webpush, { WebPushError } from 'web-push'
|
import webpush, { WebPushError } from 'web-push'
|
||||||
@ -91,6 +91,7 @@ import {
|
|||||||
createPushCollaboratorsTx,
|
createPushCollaboratorsTx,
|
||||||
getHTMLPresenter,
|
getHTMLPresenter,
|
||||||
getNotificationContent,
|
getNotificationContent,
|
||||||
|
getNotificationLink,
|
||||||
getTextPresenter,
|
getTextPresenter,
|
||||||
getUsersInfo,
|
getUsersInfo,
|
||||||
isAllowed,
|
isAllowed,
|
||||||
@ -98,6 +99,7 @@ import {
|
|||||||
isShouldNotifyTx,
|
isShouldNotifyTx,
|
||||||
isUserEmployeeInFieldValue,
|
isUserEmployeeInFieldValue,
|
||||||
isUserInFieldValue,
|
isUserInFieldValue,
|
||||||
|
messageToMarkup,
|
||||||
replaceAll,
|
replaceAll,
|
||||||
toReceiverInfo,
|
toReceiverInfo,
|
||||||
updateNotifyContextsSpace
|
updateNotifyContextsSpace
|
||||||
@ -212,7 +214,8 @@ export async function getContentByTemplate (
|
|||||||
type: Ref<BaseNotificationType>,
|
type: Ref<BaseNotificationType>,
|
||||||
control: TriggerControl,
|
control: TriggerControl,
|
||||||
data: string,
|
data: string,
|
||||||
notificationData?: InboxNotification
|
notificationData?: InboxNotification,
|
||||||
|
message?: ActivityMessage
|
||||||
): Promise<Content | undefined> {
|
): Promise<Content | undefined> {
|
||||||
if (doc === undefined) return
|
if (doc === undefined) return
|
||||||
const notificationType = control.modelDb.getObject(type)
|
const notificationType = control.modelDb.getObject(type)
|
||||||
@ -220,11 +223,24 @@ export async function getContentByTemplate (
|
|||||||
|
|
||||||
const textPart = await getTextPart(doc, control)
|
const textPart = await getTextPart(doc, control)
|
||||||
if (textPart === undefined) return
|
if (textPart === undefined) return
|
||||||
const params =
|
const params: Record<string, string> =
|
||||||
notificationData !== undefined
|
notificationData !== undefined
|
||||||
? await getTranslatedNotificationContent(notificationData, notificationData._class, control)
|
? await getTranslatedNotificationContent(notificationData, notificationData._class, control)
|
||||||
: {}
|
: {}
|
||||||
|
|
||||||
|
if (message !== undefined) {
|
||||||
|
const markup = await messageToMarkup(control, message)
|
||||||
|
params.message = markup !== undefined ? markupToText(markup) : params.message ?? ''
|
||||||
|
} else if (params.message === undefined) {
|
||||||
|
params.message = params.body ?? ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const link = await getNotificationLink(control, doc, message?._id)
|
||||||
|
const app = control.branding?.title ?? 'Huly'
|
||||||
|
const linkText = await translate(notification.string.ViewIn, { app })
|
||||||
|
|
||||||
|
params.link = `<a href='${link}'>${linkText}</a>`
|
||||||
|
|
||||||
const text = fillTemplate(notificationType.templates.textTemplate, sender, textPart, data, params)
|
const text = fillTemplate(notificationType.templates.textTemplate, sender, textPart, data, params)
|
||||||
const htmlPart = await getHtmlPart(doc, control)
|
const htmlPart = await getHtmlPart(doc, control)
|
||||||
const html = fillTemplate(notificationType.templates.htmlTemplate, sender, htmlPart ?? textPart, data, params)
|
const html = fillTemplate(notificationType.templates.htmlTemplate, sender, htmlPart ?? textPart, data, params)
|
||||||
@ -838,16 +854,24 @@ export async function createCollabDocInfo (
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
const notifyContexts = await control.findAllCtx(ctx, notification.class.DocNotifyContext, { objectId: object._id })
|
|
||||||
|
|
||||||
await updateContextsTimestamp(notifyContexts, originTx.modifiedOn, control, originTx.modifiedBy)
|
|
||||||
await removeContexts(notifyContexts, unsubscribe, control)
|
|
||||||
|
|
||||||
const docMessages = activityMessages.filter((message) => message.attachedTo === object._id)
|
const docMessages = activityMessages.filter((message) => message.attachedTo === object._id)
|
||||||
|
|
||||||
if (docMessages.length === 0) {
|
if (docMessages.length === 0) {
|
||||||
|
if (unsubscribe.length > 0) {
|
||||||
|
const notifyContexts = await control.findAllCtx(ctx, notification.class.DocNotifyContext, {
|
||||||
|
objectId: object._id,
|
||||||
|
user: { $in: unsubscribe }
|
||||||
|
})
|
||||||
|
await removeContexts(notifyContexts, unsubscribe, control)
|
||||||
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const notifyContexts = await control.findAllCtx(ctx, notification.class.DocNotifyContext, { objectId: object._id })
|
||||||
|
await removeContexts(notifyContexts, unsubscribe, control)
|
||||||
|
await updateContextsTimestamp(notifyContexts, originTx.modifiedOn, control, originTx.modifiedBy)
|
||||||
|
|
||||||
const targets = new Set(collaborators)
|
const targets = new Set(collaborators)
|
||||||
|
|
||||||
// user is not collaborator of himself, but we should notify user of changes related to users account (mentions, comments etc)
|
// user is not collaborator of himself, but we should notify user of changes related to users account (mentions, comments etc)
|
||||||
|
@ -55,10 +55,11 @@ import serverNotification, {
|
|||||||
SenderInfo,
|
SenderInfo,
|
||||||
TextPresenter
|
TextPresenter
|
||||||
} from '@hcengineering/server-notification'
|
} from '@hcengineering/server-notification'
|
||||||
import { ActivityMessage, DocUpdateMessage } from '@hcengineering/activity'
|
import activity, { ActivityMessage, DocUpdateMessage } from '@hcengineering/activity'
|
||||||
import serverView from '@hcengineering/server-view'
|
import serverView from '@hcengineering/server-view'
|
||||||
import { workbenchId } from '@hcengineering/workbench'
|
import { workbenchId } from '@hcengineering/workbench'
|
||||||
import { encodeObjectURI } from '@hcengineering/view'
|
import { encodeObjectURI } from '@hcengineering/view'
|
||||||
|
import chunter, { ChatMessage } from '@hcengineering/chunter'
|
||||||
|
|
||||||
import { NotifyResult } from './types'
|
import { NotifyResult } from './types'
|
||||||
|
|
||||||
@ -568,11 +569,45 @@ export async function getNotificationLink (
|
|||||||
id = await encodeFn(doc, control)
|
id = await encodeFn(doc, control)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let thread: string | undefined
|
||||||
|
|
||||||
|
if (control.hierarchy.isDerived(doc._class, activity.class.ActivityMessage)) {
|
||||||
|
const id = (doc as ActivityMessage)._id
|
||||||
|
|
||||||
|
if (message === undefined) {
|
||||||
|
message = id
|
||||||
|
} else {
|
||||||
|
thread = id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const front = control.branding?.front ?? getMetadata(serverCore.metadata.FrontUrl) ?? ''
|
const front = control.branding?.front ?? getMetadata(serverCore.metadata.FrontUrl) ?? ''
|
||||||
const path = [workbenchId, 'platform', notificationId, encodeObjectURI(id, doc._class)]
|
const path = [workbenchId, control.workspace.workspaceUrl, notificationId, encodeObjectURI(id, doc._class), thread]
|
||||||
|
.filter((x): x is string => x !== undefined)
|
||||||
.map((p) => encodeURIComponent(p))
|
.map((p) => encodeURIComponent(p))
|
||||||
.join('/')
|
.join('/')
|
||||||
|
|
||||||
const link = concatLink(front, path)
|
const link = concatLink(front, path)
|
||||||
|
|
||||||
return message !== undefined ? `${link}?message=${message}` : link
|
return message !== undefined ? `${link}?message=${message}` : link
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function messageToMarkup (control: TriggerControl, message: ActivityMessage): Promise<string | undefined> {
|
||||||
|
const { hierarchy } = control
|
||||||
|
if (hierarchy.isDerived(message._class, chunter.class.ChatMessage)) {
|
||||||
|
const chatMessage = message as ChatMessage
|
||||||
|
return chatMessage.message
|
||||||
|
} else {
|
||||||
|
const resource = getTextPresenter(message._class, control.hierarchy)
|
||||||
|
|
||||||
|
if (resource !== undefined) {
|
||||||
|
const fn = await getResource(resource.presenter)
|
||||||
|
const textData = await fn(message, control)
|
||||||
|
if (textData !== undefined && textData !== '') {
|
||||||
|
return textData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user