mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-10 19:57:43 +02:00
Adjust tg bot (#8412)
* Remove notification provider func Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com> * Adjust tg-bot Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com> * Use global integration Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com> * Use workspace integration Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com> * getSocialIdBySocialKey -> findFullSocialIdBySocialKey Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com> * move findFullSocialIdBySocialKey to service operations Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com> * use listIntegrations with account token Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com> * Adjust api Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com> * Fxi tests Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com> --------- Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
@@ -21,7 +21,6 @@ import core, {
|
||||
Class,
|
||||
Data,
|
||||
Doc,
|
||||
generateId,
|
||||
Hierarchy,
|
||||
Markup,
|
||||
Ref,
|
||||
@@ -38,13 +37,11 @@ import core, {
|
||||
type MeasureContext,
|
||||
AccountUuid
|
||||
} from '@hcengineering/core'
|
||||
import notification, { CommonInboxNotification, MentionInboxNotification } from '@hcengineering/notification'
|
||||
import notification, { MentionInboxNotification } from '@hcengineering/notification'
|
||||
import { getPerson } from '@hcengineering/server-contact'
|
||||
import { StorageAdapter, TriggerControl } from '@hcengineering/server-core'
|
||||
import {
|
||||
applyNotificationProviders,
|
||||
getCommonNotificationTxes,
|
||||
getNotificationContent,
|
||||
getNotificationProviderControl,
|
||||
getPushCollaboratorTx,
|
||||
NotifyResult,
|
||||
@@ -213,43 +210,6 @@ export async function getPersonNotificationTxes (
|
||||
originTx
|
||||
)
|
||||
res.push(...txes)
|
||||
} else {
|
||||
const context = (
|
||||
await control.findAll(
|
||||
ctx,
|
||||
notification.class.DocNotifyContext,
|
||||
{ objectId: reference.srcDocId, user: receiverAccount },
|
||||
{ projection: { _id: 1 } }
|
||||
)
|
||||
)[0]
|
||||
if (context !== undefined) {
|
||||
const content = await getNotificationContent(originTx, receiverPersonRef, sender, doc, control)
|
||||
const notificationData: CommonInboxNotification = {
|
||||
...data,
|
||||
...content,
|
||||
docNotifyContext: context._id,
|
||||
_id: generateId(),
|
||||
_class: notification.class.MentionInboxNotification,
|
||||
space: receiverSpace._id,
|
||||
modifiedOn: originTx.modifiedOn,
|
||||
modifiedBy: senderId
|
||||
}
|
||||
|
||||
const msg = control.hierarchy.isDerived(data.mentionedInClass, activity.class.ActivityMessage)
|
||||
? (await control.findAll(control.ctx, data.mentionedInClass, { _id: data.mentionedIn }))[0]
|
||||
: undefined
|
||||
await applyNotificationProviders(
|
||||
notificationData,
|
||||
notifyResult,
|
||||
control,
|
||||
res,
|
||||
doc,
|
||||
receiver,
|
||||
sender,
|
||||
notification.class.MentionInboxNotification,
|
||||
msg as ActivityMessage
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
|
||||
@@ -81,6 +81,15 @@ export async function getAllSocialStringsByPersonId (
|
||||
}
|
||||
|
||||
export async function getPerson (control: TriggerControl, personId: PersonId): Promise<Person | undefined> {
|
||||
const { contextData } = control.ctx
|
||||
const account: AccountUuid | undefined = contextData.account.socialIds.includes(personId)
|
||||
? contextData.account.uuid
|
||||
: contextData.socialStringsToUsers.get(personId)
|
||||
|
||||
if (account !== undefined) {
|
||||
return (await control.findAll(control.ctx, contact.class.Person, { personUuid: account }))[0]
|
||||
}
|
||||
|
||||
const socialId = (
|
||||
await control.findAll(control.ctx, contact.class.SocialIdentity, { _id: personId as SocialIdentityRef })
|
||||
)[0]
|
||||
|
||||
@@ -32,11 +32,7 @@ import {
|
||||
import gmail, { Message } from '@hcengineering/gmail'
|
||||
import { TriggerControl } from '@hcengineering/server-core'
|
||||
import { BaseNotificationType, InboxNotification, NotificationType } from '@hcengineering/notification'
|
||||
import serverNotification, {
|
||||
NotificationProviderFunc,
|
||||
ReceiverInfo,
|
||||
SenderInfo
|
||||
} from '@hcengineering/server-notification'
|
||||
import serverNotification, { ReceiverInfo, SenderInfo } from '@hcengineering/server-notification'
|
||||
import { getContentByTemplate } from '@hcengineering/server-notification-resources'
|
||||
import { getMetadata } from '@hcengineering/platform'
|
||||
import { ActivityMessage } from '@hcengineering/activity'
|
||||
@@ -162,7 +158,7 @@ async function notifyByEmail (
|
||||
// }
|
||||
}
|
||||
|
||||
const SendEmailNotifications: NotificationProviderFunc = async (
|
||||
const SendEmailNotifications = async (
|
||||
control: TriggerControl,
|
||||
types: BaseNotificationType[],
|
||||
object: Doc,
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import type { Plugin, Resource } from '@hcengineering/platform'
|
||||
import { plugin } from '@hcengineering/platform'
|
||||
import { ObjectDDParticipantFunc, TriggerFunc } from '@hcengineering/server-core'
|
||||
import { NotificationProviderFunc, TypeMatchFunc } from '@hcengineering/server-notification'
|
||||
import { TypeMatchFunc } from '@hcengineering/server-notification'
|
||||
|
||||
/**
|
||||
* @public
|
||||
@@ -33,7 +33,6 @@ export default plugin(serverGmailId, {
|
||||
},
|
||||
function: {
|
||||
IsIncomingMessageTypeMatch: '' as TypeMatchFunc,
|
||||
FindMessages: '' as Resource<ObjectDDParticipantFunc>,
|
||||
SendEmailNotifications: '' as Resource<NotificationProviderFunc>
|
||||
FindMessages: '' as Resource<ObjectDDParticipantFunc>
|
||||
}
|
||||
})
|
||||
|
||||
@@ -60,11 +60,7 @@ import notification, {
|
||||
} from '@hcengineering/notification'
|
||||
import { getResource, translate } from '@hcengineering/platform'
|
||||
import { type TriggerControl } from '@hcengineering/server-core'
|
||||
import serverNotification, {
|
||||
NOTIFICATION_BODY_SIZE,
|
||||
ReceiverInfo,
|
||||
SenderInfo
|
||||
} from '@hcengineering/server-notification'
|
||||
import { NOTIFICATION_BODY_SIZE, ReceiverInfo, SenderInfo } from '@hcengineering/server-notification'
|
||||
import { markupToText, stripTags } from '@hcengineering/text-core'
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import { getAccountBySocialId, getEmployeesBySocialIds } from '@hcengineering/server-contact'
|
||||
@@ -140,7 +136,7 @@ export async function getCommonNotificationTxes (
|
||||
const res: Tx[] = []
|
||||
const notifyContexts = await control.findAll(ctx, notification.class.DocNotifyContext, { objectId: attachedTo })
|
||||
|
||||
const notificationTx = await pushInboxNotifications(
|
||||
await pushInboxNotifications(
|
||||
ctx,
|
||||
control,
|
||||
res,
|
||||
@@ -157,12 +153,6 @@ export async function getCommonNotificationTxes (
|
||||
tx
|
||||
)
|
||||
|
||||
if (notificationTx !== undefined) {
|
||||
const notificationData = TxProcessor.createDoc2Doc(notificationTx)
|
||||
|
||||
await applyNotificationProviders(notificationData, notifyResult, control, res, doc, receiver, sender, _class)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -534,32 +524,6 @@ export async function pushActivityInboxNotifications (
|
||||
)
|
||||
}
|
||||
|
||||
export async function applyNotificationProviders (
|
||||
data: InboxNotification,
|
||||
notifyResult: NotifyResult,
|
||||
control: TriggerControl,
|
||||
res: Tx[],
|
||||
object: Doc,
|
||||
receiver: ReceiverInfo,
|
||||
sender: SenderInfo,
|
||||
_class = notification.class.ActivityInboxNotification,
|
||||
message?: ActivityMessage
|
||||
): Promise<void> {
|
||||
const resources = control.modelDb.findAllSync(serverNotification.class.NotificationProviderResources, {})
|
||||
for (const [provider, types] of notifyResult.entries()) {
|
||||
const resource = resources.find((it) => it.provider === provider)
|
||||
|
||||
if (resource === undefined) continue
|
||||
|
||||
const fn = await getResource(resource.fn)
|
||||
|
||||
const txes = await fn(control, types, object, data, receiver, sender, message)
|
||||
if (txes.length > 0) {
|
||||
res.push(...txes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function createNotifyContext (
|
||||
ctx: MeasureContext,
|
||||
control: TriggerControl,
|
||||
@@ -651,28 +615,12 @@ export async function getNotificationTxes (
|
||||
)
|
||||
|
||||
if (notificationTx !== undefined) {
|
||||
const notificationData = TxProcessor.createDoc2Doc(notificationTx)
|
||||
|
||||
const current: AvailableProvidersCache = control.contextCache.get(AvailableProvidersCacheKey) ?? new Map()
|
||||
const providers = Array.from(notifyResult.keys()).filter(
|
||||
(p) => p !== notification.providers.InboxNotificationProvider
|
||||
)
|
||||
const providers = Array.from(notifyResult.keys())
|
||||
if (providers.length > 0) {
|
||||
current.set(notificationData._id, providers)
|
||||
current.set(notificationTx.objectId, providers)
|
||||
control.contextCache.set('AvailableNotificationProviders', current)
|
||||
}
|
||||
|
||||
await applyNotificationProviders(
|
||||
notificationData,
|
||||
notifyResult,
|
||||
control,
|
||||
res,
|
||||
object,
|
||||
receiver,
|
||||
sender,
|
||||
notificationData._class,
|
||||
message
|
||||
)
|
||||
}
|
||||
} else {
|
||||
const context = getDocNotifyContext(control, docNotifyContexts, message.attachedTo, receiver.account)
|
||||
|
||||
@@ -82,10 +82,10 @@ export function isUserEmployeeInFieldValueTypeMatch (
|
||||
type: NotificationType,
|
||||
control: TriggerControl
|
||||
): boolean {
|
||||
// TODO: check field type and compare with Ref<Person> or PersonId based on that
|
||||
if (type.field === undefined) return false
|
||||
const value = (doc as any)[type.field]
|
||||
if (value == null) return false
|
||||
if (value === person) return true
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
return includesAny(value, socialIds)
|
||||
@@ -121,7 +121,7 @@ function escapeRegExp (str: string): string {
|
||||
|
||||
export async function shouldNotifyCommon (
|
||||
control: TriggerControl,
|
||||
user: PersonId[],
|
||||
socialIds: PersonId[],
|
||||
typeId: Ref<CommonNotificationType>,
|
||||
notificationControl: NotificationProviderControl
|
||||
): Promise<NotifyResult> {
|
||||
@@ -135,7 +135,7 @@ export async function shouldNotifyCommon (
|
||||
const providers = await control.modelDb.findAll(notification.class.NotificationProvider, {})
|
||||
|
||||
for (const provider of providers) {
|
||||
const allowed = isAllowed(control, user, type, provider, notificationControl)
|
||||
const allowed = isAllowed(control, socialIds, type, provider, notificationControl)
|
||||
|
||||
if (allowed) {
|
||||
const cur = result.get(provider._id) ?? []
|
||||
|
||||
@@ -14,16 +14,9 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { ActivityMessage } from '@hcengineering/activity'
|
||||
import { Employee, Person, PersonSpace } from '@hcengineering/contact'
|
||||
import { PersonId, Class, Doc, Mixin, Ref, Tx, TxCUD, AccountUuid } from '@hcengineering/core'
|
||||
import {
|
||||
BaseNotificationType,
|
||||
InboxNotification,
|
||||
NotificationContent,
|
||||
NotificationProvider,
|
||||
NotificationType
|
||||
} from '@hcengineering/notification'
|
||||
import { NotificationContent, NotificationType } from '@hcengineering/notification'
|
||||
import { Metadata, Plugin, Resource, plugin } from '@hcengineering/platform'
|
||||
import type { TriggerControl, TriggerFunc } from '@hcengineering/server-core'
|
||||
|
||||
@@ -102,21 +95,6 @@ export interface SenderInfo {
|
||||
person?: Person
|
||||
}
|
||||
|
||||
export type NotificationProviderFunc = (
|
||||
control: TriggerControl,
|
||||
types: BaseNotificationType[],
|
||||
object: Doc,
|
||||
data: InboxNotification,
|
||||
receiver: ReceiverInfo,
|
||||
sender: SenderInfo,
|
||||
message?: ActivityMessage
|
||||
) => Promise<Tx[]>
|
||||
|
||||
export interface NotificationProviderResources extends Doc {
|
||||
provider: Ref<NotificationProvider>
|
||||
fn: Resource<NotificationProviderFunc>
|
||||
}
|
||||
|
||||
export const NOTIFICATION_BODY_SIZE = 50
|
||||
export const PUSH_NOTIFICATION_TITLE_SIZE = 80
|
||||
|
||||
@@ -130,9 +108,6 @@ export default plugin(serverNotificationId, {
|
||||
WebPushUrl: '' as Metadata<string>,
|
||||
InboxOnlyNotifications: '' as Metadata<boolean>
|
||||
},
|
||||
class: {
|
||||
NotificationProviderResources: '' as Ref<Class<NotificationProviderResources>>
|
||||
},
|
||||
mixin: {
|
||||
HTMLPresenter: '' as Ref<Mixin<HTMLPresenter>>,
|
||||
TextPresenter: '' as Ref<Mixin<TextPresenter>>,
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"@hcengineering/core": "^0.6.32",
|
||||
"@hcengineering/notification": "^0.6.23",
|
||||
"@hcengineering/platform": "^0.6.11",
|
||||
"@hcengineering/server-contact": "^0.6.1",
|
||||
"@hcengineering/server-core": "^0.6.1",
|
||||
"@hcengineering/server-notification": "^0.6.1",
|
||||
"@hcengineering/server-notification-resources": "^0.6.0",
|
||||
|
||||
@@ -12,14 +12,12 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import activity, { ActivityMessage, DocUpdateMessage } from '@hcengineering/activity'
|
||||
import chunter, { ChatMessage } from '@hcengineering/chunter'
|
||||
import contact, { Channel, ChannelProvider, Contact, Employee, formatName, Person } from '@hcengineering/contact'
|
||||
import {
|
||||
import contact, { Channel, Person } from '@hcengineering/contact'
|
||||
import core, {
|
||||
PersonId,
|
||||
Class,
|
||||
concatLink,
|
||||
Doc,
|
||||
DocumentQuery,
|
||||
FindOptions,
|
||||
@@ -28,26 +26,33 @@ import {
|
||||
Ref,
|
||||
Tx,
|
||||
TxCreateDoc,
|
||||
TxProcessor
|
||||
TxProcessor,
|
||||
TxCUD,
|
||||
TxUpdateDoc
|
||||
} from '@hcengineering/core'
|
||||
import notification, {
|
||||
BaseNotificationType,
|
||||
ActivityInboxNotification,
|
||||
InboxNotification,
|
||||
MentionInboxNotification,
|
||||
NotificationProviderSetting,
|
||||
NotificationType
|
||||
} from '@hcengineering/notification'
|
||||
import { getMetadata, getResource, translate } from '@hcengineering/platform'
|
||||
import { TriggerControl } from '@hcengineering/server-core'
|
||||
import { NotificationProviderFunc, ReceiverInfo, SenderInfo } from '@hcengineering/server-notification'
|
||||
import { getResource, translate } from '@hcengineering/platform'
|
||||
import { getAccountBySocialId, getPerson } from '@hcengineering/server-contact'
|
||||
import { PlatformQueueProducer, QueueTopic, TriggerControl } from '@hcengineering/server-core'
|
||||
import {
|
||||
getNotificationLink,
|
||||
getTextPresenter,
|
||||
getTranslatedNotificationContent
|
||||
getTranslatedNotificationContent,
|
||||
AvailableProvidersCache,
|
||||
AvailableProvidersCacheKey
|
||||
} from '@hcengineering/server-notification-resources'
|
||||
import serverTelegram from '@hcengineering/server-telegram'
|
||||
import { generateToken } from '@hcengineering/server-token'
|
||||
import setting, { Integration } from '@hcengineering/setting'
|
||||
import telegram, { TelegramMessage, TelegramNotificationRequest } from '@hcengineering/telegram'
|
||||
import {
|
||||
type TelegramNotificationQueueMessage,
|
||||
TelegramQueueMessageType,
|
||||
TelegramQueueMessage
|
||||
} from '@hcengineering/server-telegram'
|
||||
import telegram, { TelegramMessage } from '@hcengineering/telegram'
|
||||
import { jsonToHTML, markupToJSON } from '@hcengineering/text'
|
||||
|
||||
/**
|
||||
@@ -149,20 +154,20 @@ export async function GetIntegrationOwnerTG (
|
||||
return undefined
|
||||
}
|
||||
|
||||
async function getContactChannel (
|
||||
control: TriggerControl,
|
||||
value: Contact,
|
||||
provider: Ref<ChannelProvider>
|
||||
): Promise<string | undefined> {
|
||||
if (value === undefined) return
|
||||
const res = (
|
||||
await control.findAll(control.ctx, contact.class.Channel, {
|
||||
attachedTo: value._id,
|
||||
provider
|
||||
})
|
||||
)[0]
|
||||
return res?.value ?? ''
|
||||
}
|
||||
// async function getContactChannel (
|
||||
// control: TriggerControl,
|
||||
// value: Contact,
|
||||
// provider: Ref<ChannelProvider>
|
||||
// ): Promise<string | undefined> {
|
||||
// if (value === undefined) return
|
||||
// const res = (
|
||||
// await control.findAll(control.ctx, contact.class.Channel, {
|
||||
// attachedTo: value._id,
|
||||
// provider
|
||||
// })
|
||||
// )[0]
|
||||
// return res?.value ?? ''
|
||||
// }
|
||||
|
||||
async function activityMessageToHtml (control: TriggerControl, message: ActivityMessage): Promise<string | undefined> {
|
||||
const { hierarchy } = control
|
||||
@@ -252,66 +257,185 @@ function hasAttachments (doc: ActivityMessage | undefined, hierarchy: Hierarchy)
|
||||
return false
|
||||
}
|
||||
|
||||
const telegramNotificationKey = 'telegram.notification.reported'
|
||||
const SendTelegramNotifications: NotificationProviderFunc = async (
|
||||
const telegramNotificationCacheKey = 'telegram.notification.cache'
|
||||
|
||||
async function NotificationsHandler (txes: TxCreateDoc<InboxNotification>[], control: TriggerControl): Promise<Tx[]> {
|
||||
const queue = control.queue
|
||||
|
||||
if (queue === undefined) {
|
||||
return []
|
||||
}
|
||||
|
||||
const availableProviders: AvailableProvidersCache = control.contextCache.get(AvailableProvidersCacheKey) ?? new Map()
|
||||
|
||||
const all: InboxNotification[] = txes
|
||||
.map((tx) => TxProcessor.createDoc2Doc(tx))
|
||||
.filter(
|
||||
(it) =>
|
||||
availableProviders.get(it._id)?.find((p) => p === telegram.providers.TelegramNotificationProvider) !== undefined
|
||||
)
|
||||
|
||||
if (all.length === 0) {
|
||||
return []
|
||||
}
|
||||
|
||||
const result: Tx[] = []
|
||||
const producer = queue.createProducer(control.ctx, QueueTopic.TelegramBot)
|
||||
try {
|
||||
for (const inboxNotification of all) {
|
||||
result.push(...(await processNotification(inboxNotification, control, producer)))
|
||||
}
|
||||
} finally {
|
||||
await producer.close()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
async function getNotificationMessage (
|
||||
n: InboxNotification,
|
||||
control: TriggerControl,
|
||||
types: BaseNotificationType[],
|
||||
doc: Doc,
|
||||
data: InboxNotification,
|
||||
receiver: ReceiverInfo,
|
||||
sender: SenderInfo,
|
||||
message?: ActivityMessage
|
||||
): Promise<Tx[]> => {
|
||||
// TODO: FIXME
|
||||
// if (types.length === 0) {
|
||||
// return []
|
||||
// }
|
||||
cache: Map<Ref<Doc>, Doc>
|
||||
): Promise<ActivityMessage | undefined> {
|
||||
const { hierarchy } = control
|
||||
if (hierarchy.isDerived(n._class, notification.class.ActivityInboxNotification)) {
|
||||
const activityNotification = n as ActivityInboxNotification
|
||||
const message =
|
||||
cache.get(activityNotification.attachedTo) ??
|
||||
(
|
||||
await control.findAll(control.ctx, activityNotification.attachedToClass, {
|
||||
_id: activityNotification.attachedTo
|
||||
})
|
||||
)[0]
|
||||
return message as ActivityMessage
|
||||
} else if (hierarchy.isDerived(n._class, notification.class.MentionInboxNotification)) {
|
||||
const mentionNotification = n as MentionInboxNotification
|
||||
if (hierarchy.isDerived(mentionNotification.mentionedInClass, activity.class.ActivityMessage)) {
|
||||
const message =
|
||||
cache.get(mentionNotification.mentionedIn) ??
|
||||
(
|
||||
await control.findAll(control.ctx, mentionNotification.mentionedInClass, {
|
||||
_id: mentionNotification.mentionedIn
|
||||
})
|
||||
)[0]
|
||||
return message as ActivityMessage
|
||||
}
|
||||
}
|
||||
|
||||
// const botUrl = getMetadata(serverTelegram.metadata.BotUrl)
|
||||
return undefined
|
||||
}
|
||||
|
||||
// if (botUrl === undefined || botUrl === '') {
|
||||
// const reported = control.cache.get(telegramNotificationKey)
|
||||
// if (reported === undefined) {
|
||||
// control.ctx.error('Please provide telegram bot service url to enable telegram notifications.')
|
||||
// control.cache.set(telegramNotificationKey, true)
|
||||
// }
|
||||
// return []
|
||||
// }
|
||||
async function getSenderName (n: InboxNotification, control: TriggerControl): Promise<string> {
|
||||
const inlineName = n.intlParams?.senderName
|
||||
if (inlineName != null && inlineName !== '') {
|
||||
return inlineName.toString()
|
||||
}
|
||||
const senderPerson = await getPerson(control, n.createdBy ?? n.modifiedBy)
|
||||
return senderPerson?.name ?? 'System'
|
||||
}
|
||||
|
||||
// if (!receiver.person.active) {
|
||||
// return []
|
||||
// }
|
||||
async function processNotification (
|
||||
n: InboxNotification,
|
||||
control: TriggerControl,
|
||||
producer: PlatformQueueProducer<TelegramQueueMessage>
|
||||
): Promise<Tx[]> {
|
||||
try {
|
||||
const cache: Map<Ref<Doc>, Doc> = control.contextCache.get(telegramNotificationCacheKey) ?? new Map()
|
||||
const doc = cache.get(n.objectId) ?? (await control.findAll(control.ctx, n.objectClass, { _id: n.objectId }))[0]
|
||||
if (doc === undefined) return []
|
||||
const message = await getNotificationMessage(n, control, cache)
|
||||
|
||||
// try {
|
||||
// const { title, body, quote, link } = await getTranslatedData(data, doc, control, message)
|
||||
// const record: TelegramNotificationRequest = {
|
||||
// notificationId: data._id,
|
||||
// messageId: message?._id,
|
||||
// account: receiver._id,
|
||||
// workspace: control.workspace,
|
||||
// sender: data.intlParams?.senderName?.toString() ?? formatName(sender.person?.name ?? 'System'),
|
||||
// attachments: hasAttachments(message, control.hierarchy),
|
||||
// title,
|
||||
// quote,
|
||||
// body,
|
||||
// link
|
||||
// }
|
||||
cache.set(n.objectId, doc)
|
||||
control.contextCache.set(telegramNotificationCacheKey, cache)
|
||||
|
||||
// await fetch(concatLink(botUrl, '/notify'), {
|
||||
// method: 'POST',
|
||||
// headers: {
|
||||
// Authorization: 'Bearer ' + generateToken(receiver.account.email, control.workspace, { service: 'telegram' }),
|
||||
// 'Content-Type': 'application/json'
|
||||
// },
|
||||
// body: JSON.stringify([record])
|
||||
// })
|
||||
// } catch (err) {
|
||||
// control.ctx.error('Could not send telegram notification', {
|
||||
// err,
|
||||
// notificationId: data._id,
|
||||
// receiver: receiver.account.email
|
||||
// })
|
||||
// }
|
||||
const { title, body, quote, link } = await getTranslatedData(n, doc, control, message)
|
||||
const record: TelegramNotificationQueueMessage = {
|
||||
type: TelegramQueueMessageType.Notification,
|
||||
notificationId: n._id,
|
||||
messageId: message?._id,
|
||||
account: n.user,
|
||||
sender: await getSenderName(n, control),
|
||||
attachments: hasAttachments(message, control.hierarchy),
|
||||
title,
|
||||
quote,
|
||||
body,
|
||||
link
|
||||
}
|
||||
|
||||
await producer.send(control.workspace.uuid, [record])
|
||||
} catch (err) {
|
||||
control.ctx.error('Could not send telegram notification', {
|
||||
err,
|
||||
notificationId: n._id,
|
||||
account: n.user
|
||||
})
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
|
||||
async function updateWorkspaceSubscription (
|
||||
producer: PlatformQueueProducer<TelegramQueueMessage>,
|
||||
enabled: boolean,
|
||||
socialId: PersonId,
|
||||
control: TriggerControl
|
||||
): Promise<void> {
|
||||
const account = await getAccountBySocialId(control, socialId)
|
||||
if (account == null) {
|
||||
return
|
||||
}
|
||||
await producer.send(control.workspace.uuid, [
|
||||
{
|
||||
type: TelegramQueueMessageType.WorkspaceSubscription,
|
||||
account,
|
||||
subscribe: enabled
|
||||
}
|
||||
])
|
||||
}
|
||||
|
||||
async function ProviderSettingsHandler (
|
||||
txes: TxCUD<NotificationProviderSetting>[],
|
||||
control: TriggerControl
|
||||
): Promise<Tx[]> {
|
||||
const queue = control.queue
|
||||
|
||||
if (queue === undefined) {
|
||||
return []
|
||||
}
|
||||
|
||||
const producer = queue.createProducer(control.ctx, QueueTopic.TelegramBot)
|
||||
|
||||
try {
|
||||
for (const tx of txes) {
|
||||
if (tx._class === core.class.TxCreateDoc) {
|
||||
const createTx = tx as TxCreateDoc<NotificationProviderSetting>
|
||||
const setting = TxProcessor.createDoc2Doc(createTx)
|
||||
|
||||
if (setting.attachedTo === telegram.providers.TelegramNotificationProvider) {
|
||||
await updateWorkspaceSubscription(producer, setting.enabled, setting.createdBy ?? setting.modifiedBy, control)
|
||||
}
|
||||
} else if (tx._class === core.class.TxUpdateDoc) {
|
||||
const updateTx = tx as TxUpdateDoc<NotificationProviderSetting>
|
||||
if (updateTx.operations.enabled !== undefined) {
|
||||
const setting = (
|
||||
await control.findAll(control.ctx, notification.class.NotificationProviderSetting, {
|
||||
_id: updateTx.objectId
|
||||
})
|
||||
)[0]
|
||||
|
||||
if (setting !== undefined && setting.attachedTo === telegram.providers.TelegramNotificationProvider) {
|
||||
await updateWorkspaceSubscription(
|
||||
producer,
|
||||
updateTx.operations.enabled,
|
||||
setting.createdBy ?? setting.modifiedBy,
|
||||
control
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
await producer.close()
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
@@ -319,13 +443,14 @@ const SendTelegramNotifications: NotificationProviderFunc = async (
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
export default async () => ({
|
||||
trigger: {
|
||||
OnMessageCreate
|
||||
OnMessageCreate,
|
||||
NotificationsHandler,
|
||||
ProviderSettingsHandler
|
||||
},
|
||||
function: {
|
||||
IsIncomingMessageTypeMatch,
|
||||
FindMessages,
|
||||
GetCurrentEmployeeTG,
|
||||
GetIntegrationOwnerTG,
|
||||
SendTelegramNotifications
|
||||
GetIntegrationOwnerTG
|
||||
}
|
||||
})
|
||||
|
||||
@@ -38,10 +38,12 @@
|
||||
"@types/jest": "^29.5.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/activity": "^0.6.0",
|
||||
"@hcengineering/core": "^0.6.32",
|
||||
"@hcengineering/notification": "^0.6.23",
|
||||
"@hcengineering/platform": "^0.6.11",
|
||||
"@hcengineering/server-templates": "^0.6.0",
|
||||
"@hcengineering/server-core": "^0.6.1",
|
||||
"@hcengineering/server-notification": "^0.6.1",
|
||||
"@hcengineering/server-core": "^0.6.1"
|
||||
"@hcengineering/server-templates": "^0.6.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,11 +14,12 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Metadata, Plugin, Resource, plugin } from '@hcengineering/platform'
|
||||
import { Plugin, Resource, plugin } from '@hcengineering/platform'
|
||||
import { ObjectDDParticipantFunc, TriggerFunc } from '@hcengineering/server-core'
|
||||
import { NotificationProviderFunc, TypeMatchFunc } from '@hcengineering/server-notification'
|
||||
import { TypeMatchFunc } from '@hcengineering/server-notification'
|
||||
import { TemplateFieldServerFunc } from '@hcengineering/server-templates'
|
||||
|
||||
export * from './types'
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@@ -28,17 +29,15 @@ export const serverTelegramId = 'server-telegram' as Plugin
|
||||
* @public
|
||||
*/
|
||||
export default plugin(serverTelegramId, {
|
||||
metadata: {
|
||||
BotUrl: '' as Metadata<string>
|
||||
},
|
||||
trigger: {
|
||||
OnMessageCreate: '' as Resource<TriggerFunc>
|
||||
OnMessageCreate: '' as Resource<TriggerFunc>,
|
||||
NotificationsHandler: '' as Resource<TriggerFunc>,
|
||||
ProviderSettingsHandler: '' as Resource<TriggerFunc>
|
||||
},
|
||||
function: {
|
||||
IsIncomingMessageTypeMatch: '' as TypeMatchFunc,
|
||||
FindMessages: '' as Resource<ObjectDDParticipantFunc>,
|
||||
GetCurrentEmployeeTG: '' as Resource<TemplateFieldServerFunc>,
|
||||
GetIntegrationOwnerTG: '' as Resource<TemplateFieldServerFunc>,
|
||||
SendTelegramNotifications: '' as Resource<NotificationProviderFunc>
|
||||
GetIntegrationOwnerTG: '' as Resource<TemplateFieldServerFunc>
|
||||
}
|
||||
})
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// Copyright © 2025 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { ActivityMessage } from '@hcengineering/activity'
|
||||
import { AccountUuid, Ref } from '@hcengineering/core'
|
||||
import { InboxNotification } from '@hcengineering/notification'
|
||||
|
||||
export type TelegramQueueMessage = TelegramNotificationQueueMessage | TelegramWorkspaceSubscriptionQueueMessage
|
||||
|
||||
export enum TelegramQueueMessageType {
|
||||
Notification = 'notification',
|
||||
WorkspaceSubscription = 'workspaceSubscription'
|
||||
}
|
||||
|
||||
export interface TelegramNotificationQueueMessage {
|
||||
type: TelegramQueueMessageType.Notification
|
||||
notificationId: Ref<InboxNotification>
|
||||
messageId?: Ref<ActivityMessage>
|
||||
attachments: boolean
|
||||
account: AccountUuid
|
||||
title: string
|
||||
quote?: string
|
||||
body: string
|
||||
sender: string
|
||||
link: string
|
||||
}
|
||||
|
||||
export interface TelegramWorkspaceSubscriptionQueueMessage {
|
||||
type: TelegramQueueMessageType.WorkspaceSubscription
|
||||
account: AccountUuid
|
||||
subscribe: boolean
|
||||
}
|
||||
Reference in New Issue
Block a user