diff --git a/desktop/src/ui/platform.ts b/desktop/src/ui/platform.ts index 384e9ec65f..c5080f2d60 100644 --- a/desktop/src/ui/platform.ts +++ b/desktop/src/ui/platform.ts @@ -221,7 +221,7 @@ export async function configurePlatform (): Promise { setMetadata(presentation.metadata.FrontVersion, config.VERSION) } setMetadata(telegram.metadata.TelegramURL, config.TELEGRAM_URL ?? 'http://localhost:8086') - setMetadata(telegram.metadata.BotUrl, config.TELEGRAM_BOT_URL) + setMetadata(telegram.metadata.BotUrl, config.TELEGRAM_BOT_URL ?? 'http://localhost:4020') setMetadata(gmail.metadata.GmailURL, config.GMAIL_URL ?? 'http://localhost:8087') setMetadata(calendar.metadata.CalendarServiceURL, config.CALENDAR_URL ?? 'http://localhost:8095') setMetadata(notification.metadata.PushPublicKey, config.PUSH_PUBLIC_KEY) diff --git a/models/telegram/package.json b/models/telegram/package.json index cb90b70ace..781f6372d6 100644 --- a/models/telegram/package.json +++ b/models/telegram/package.json @@ -29,6 +29,8 @@ }, "dependencies": { "@hcengineering/activity": "^0.6.0", + "@hcengineering/chunter": "^0.6.20", + "@hcengineering/love": "^0.6.0", "@hcengineering/model": "^0.6.11", "@hcengineering/core": "^0.6.32", "@hcengineering/platform": "^0.6.11", diff --git a/models/telegram/src/notification.ts b/models/telegram/src/notification.ts index e8dcb03505..c790b91fa3 100644 --- a/models/telegram/src/notification.ts +++ b/models/telegram/src/notification.ts @@ -17,6 +17,8 @@ import { type Builder } from '@hcengineering/model' import notification from '@hcengineering/model-notification' import core from '@hcengineering/model-core' import contact from '@hcengineering/model-contact' +import chunter from '@hcengineering/chunter' +import love from '@hcengineering/love' import telegram from './plugin' @@ -66,7 +68,17 @@ export function defineNotifications (builder: Builder): void { builder.createDoc(notification.class.NotificationProviderDefaults, core.space.Model, { provider: notification.providers.InboxNotificationProvider, - ignoredTypes: [notification.ids.CollaboratoAddNotification], + ignoredTypes: [], enabledTypes: [telegram.ids.NewMessageNotification] }) + + builder.createDoc(notification.class.NotificationProviderDefaults, core.space.Model, { + provider: telegram.providers.TelegramNotificationProvider, + ignoredTypes: [ + notification.ids.CollaboratoAddNotification, + love.ids.InviteNotification, + love.ids.KnockNotification + ], + enabledTypes: [chunter.ids.DMNotification, chunter.ids.ThreadNotification] + }) } diff --git a/packages/ui/src/components/Modal.svelte b/packages/ui/src/components/Modal.svelte index 3dad7767d7..1a87012330 100644 --- a/packages/ui/src/components/Modal.svelte +++ b/packages/ui/src/components/Modal.svelte @@ -34,6 +34,7 @@ export let allowFullsize: boolean = false export let hideFooter: boolean = false export let adaptive: 'default' | 'freezeActions' | 'doubleRow' | 'disabled' = 'disabled' + export let showCancelButton: boolean = true const dispatch = createEventDispatcher() @@ -97,13 +98,15 @@ on:click={okAction} disabled={!canSave} /> - + {#if showCancelButton} + + {/if} {/if} diff --git a/plugins/notification-resources/src/components/settings/NotificationGroupSetting.svelte b/plugins/notification-resources/src/components/settings/NotificationGroupSetting.svelte index a18df25410..1051dc2848 100644 --- a/plugins/notification-resources/src/components/settings/NotificationGroupSetting.svelte +++ b/plugins/notification-resources/src/components/settings/NotificationGroupSetting.svelte @@ -20,7 +20,8 @@ NotificationGroup, NotificationType, NotificationTypeSetting, - NotificationProviderDefaults + NotificationProviderDefaults, + NotificationProviderSetting } from '@hcengineering/notification' import { getResource, IntlString } from '@hcengineering/platform' import { getClient } from '@hcengineering/presentation' @@ -132,12 +133,13 @@ async function getFilteredProviders ( providers: NotificationProvider[], - types: BaseNotificationType[] + types: BaseNotificationType[], + providersSettings: NotificationProviderSetting[] ): Promise { const result: NotificationProvider[] = [] for (const provider of providers) { - const providerSetting = $providersSettings.find((p) => p.attachedTo === provider._id) + const providerSetting = providersSettings.find((p) => p.attachedTo === provider._id) if (providerSetting !== undefined && !providerSetting.enabled) continue if (providerSetting === undefined && !provider.defaultEnabled) continue @@ -164,7 +166,7 @@ let filteredProviders: NotificationProvider[] = [] - $: void getFilteredProviders(providers, types).then((result) => { + $: void getFilteredProviders(providers, types, $providersSettings).then((result) => { filteredProviders = result }) diff --git a/plugins/telegram-resources/src/components/ConfigureBotPopup.svelte b/plugins/telegram-resources/src/components/ConfigureBotPopup.svelte new file mode 100644 index 0000000000..be35c8267b --- /dev/null +++ b/plugins/telegram-resources/src/components/ConfigureBotPopup.svelte @@ -0,0 +1,209 @@ + + + + + {}} + showCancelButton={false} + canSave + on:close +> +
+ {#if isLoading} +
+ +
+ {:else if info} +
+
+
+ {#if info.photoUrl !== ''} + + {:else} + + {/if} + {info.name} (@{info.username}) + + {#if isConnectionEstablished} + + + {/if} +
+ {#if connectionError} + + + {/if} +
+
+
+ + + {#if codeError} + + + {:else if isCodeValid} + + + {/if} +
+ {:else} + + + {/if} +
+
+ + diff --git a/plugins/telegram-resources/src/components/NotificationProviderPresenter.svelte b/plugins/telegram-resources/src/components/NotificationProviderPresenter.svelte index 0aed0a5045..3b79589836 100644 --- a/plugins/telegram-resources/src/components/NotificationProviderPresenter.svelte +++ b/plugins/telegram-resources/src/components/NotificationProviderPresenter.svelte @@ -14,185 +14,26 @@ --> {#if enabled} - {#if isLoading} -
- -
- {:else if info} -
-
- {#if info.photoUrl !== ''} - - {:else} - - {/if} - {info.name} (@{info.username}) - - {#if isConnectionEstablished} - - - {/if} -
- {#if connectionError} - - - {/if} -
-
- - - {#if codeError} - - - {:else if isCodeValid} - - - {/if} -
- {:else} - - - {/if} +
+ +
{/if} diff --git a/plugins/telegram/src/index.ts b/plugins/telegram/src/index.ts index 83dd982395..5594fa4be3 100644 --- a/plugins/telegram/src/index.ts +++ b/plugins/telegram/src/index.ts @@ -66,6 +66,7 @@ export interface TelegramNotificationRecord { quote?: string body: string sender: string + link: string } /** diff --git a/server-plugins/gmail-resources/src/index.ts b/server-plugins/gmail-resources/src/index.ts index 8ad1e0d1d6..732bfdb325 100644 --- a/server-plugins/gmail-resources/src/index.ts +++ b/server-plugins/gmail-resources/src/index.ts @@ -23,6 +23,7 @@ import { FindOptions, FindResult, Hierarchy, + MeasureContext, Ref, Tx, TxCreateDoc, @@ -98,6 +99,7 @@ export async function IsIncomingMessage ( } export async function sendEmailNotification ( + ctx: MeasureContext, text: string, html: string, subject: string, @@ -106,7 +108,7 @@ export async function sendEmailNotification ( try { const sesURL = getMetadata(serverNotification.metadata.SesUrl) if (sesURL === undefined || sesURL === '') { - console.log('Please provide email service url to enable email confirmations.') + ctx.error('Please provide email service url to enable email confirmations.') return } await fetch(concatLink(sesURL, '/send'), { @@ -122,7 +124,7 @@ export async function sendEmailNotification ( }) }) } catch (err) { - console.log('Could not send email notification', err) + ctx.error('Could not send email notification', { err, receiver }) } } @@ -146,7 +148,7 @@ async function notifyByEmail ( const content = await getContentByTemplate(doc, senderName, type, control, '', data) if (content !== undefined) { - await sendEmailNotification(content.text, content.html, content.subject, account.email) + await sendEmailNotification(control.ctx, content.text, content.html, content.subject, account.email) } } diff --git a/server-plugins/hr-resources/src/index.ts b/server-plugins/hr-resources/src/index.ts index b5298a4d20..c75f30bccd 100644 --- a/server-plugins/hr-resources/src/index.ts +++ b/server-plugins/hr-resources/src/index.ts @@ -296,7 +296,7 @@ async function sendEmailNotifications ( if (content === undefined) return for (const channel of channels) { - await sendEmailNotification(content.text, content.html, content.subject, channel.value) + await sendEmailNotification(control.ctx, content.text, content.html, content.subject, channel.value) } } diff --git a/server-plugins/notification-resources/src/utils.ts b/server-plugins/notification-resources/src/utils.ts index dd21abf77e..1fb631288e 100644 --- a/server-plugins/notification-resources/src/utils.ts +++ b/server-plugins/notification-resources/src/utils.ts @@ -17,10 +17,11 @@ import notification, { Collaborators, CommonNotificationType, NotificationContent, + notificationId, NotificationProvider, NotificationType } from '@hcengineering/notification' -import type { TriggerControl } from '@hcengineering/server-core' +import serverCore, { TriggerControl } from '@hcengineering/server-core' import { Analytics } from '@hcengineering/analytics' import contact, { formatName, PersonAccount } from '@hcengineering/contact' import core, { @@ -42,9 +43,10 @@ import core, { TxRemoveDoc, TxUpdateDoc, type MeasureContext, - Markup + Markup, + concatLink } from '@hcengineering/core' -import { getResource, IntlString, translate } from '@hcengineering/platform' +import { getMetadata, getResource, IntlString, translate } from '@hcengineering/platform' import serverNotification, { getPersonAccountById, HTMLPresenter, @@ -53,7 +55,10 @@ import serverNotification, { SenderInfo, TextPresenter } from '@hcengineering/server-notification' -import { DocUpdateMessage } from '@hcengineering/activity' +import { ActivityMessage, DocUpdateMessage } from '@hcengineering/activity' +import serverView from '@hcengineering/server-view' +import { workbenchId } from '@hcengineering/workbench' +import { encodeObjectURI } from '@hcengineering/view' import { NotifyResult } from './types' @@ -546,3 +551,28 @@ export function createPullCollaboratorsTx ( $pull: { collaborators: { $in: collaborators } } }) } + +export async function getNotificationLink ( + control: TriggerControl, + doc: Doc, + message?: Ref +): Promise { + const linkProviders = control.modelDb.findAllSync(serverView.mixin.ServerLinkIdProvider, {}) + const provider = linkProviders.find(({ _id }) => _id === doc._class) + + let id: string = doc._id + + if (provider !== undefined) { + const encodeFn = await getResource(provider.encode) + + id = await encodeFn(doc, control) + } + + const front = control.branding?.front ?? getMetadata(serverCore.metadata.FrontUrl) ?? '' + const path = [workbenchId, 'platform', notificationId, encodeObjectURI(id, doc._class)] + .map((p) => encodeURIComponent(p)) + .join('/') + const link = concatLink(front, path) + + return message !== undefined ? `${link}?message=${message}` : link +} diff --git a/server-plugins/telegram-resources/package.json b/server-plugins/telegram-resources/package.json index 80f8f91b6c..8bbf4d734d 100644 --- a/server-plugins/telegram-resources/package.json +++ b/server-plugins/telegram-resources/package.json @@ -38,16 +38,16 @@ }, "dependencies": { "@hcengineering/activity": "^0.6.0", - "@hcengineering/contact": "^0.6.24", "@hcengineering/chunter": "^0.6.20", + "@hcengineering/contact": "^0.6.24", "@hcengineering/core": "^0.6.32", "@hcengineering/notification": "^0.6.23", "@hcengineering/platform": "^0.6.11", "@hcengineering/server-core": "^0.6.1", - "@hcengineering/server-token": "^0.6.11", "@hcengineering/server-notification": "^0.6.1", - "@hcengineering/server-telegram": "^0.6.0", "@hcengineering/server-notification-resources": "^0.6.0", + "@hcengineering/server-telegram": "^0.6.0", + "@hcengineering/server-token": "^0.6.11", "@hcengineering/setting": "^0.6.17", "@hcengineering/telegram": "^0.6.21", "@hcengineering/text": "^0.6.5" diff --git a/server-plugins/telegram-resources/src/index.ts b/server-plugins/telegram-resources/src/index.ts index ea3fe59be2..ffed70de82 100644 --- a/server-plugins/telegram-resources/src/index.ts +++ b/server-plugins/telegram-resources/src/index.ts @@ -34,13 +34,17 @@ import telegram, { TelegramMessage, TelegramNotificationRecord } from '@hcengine import { BaseNotificationType, InboxNotification, NotificationType } from '@hcengineering/notification' import setting, { Integration } from '@hcengineering/setting' import { NotificationProviderFunc, ReceiverInfo, SenderInfo } from '@hcengineering/server-notification' -import { getMetadata, getResource } from '@hcengineering/platform' +import { getMetadata, getResource, translate } from '@hcengineering/platform' import serverTelegram from '@hcengineering/server-telegram' -import { getTranslatedNotificationContent, getTextPresenter } from '@hcengineering/server-notification-resources' +import { + getTranslatedNotificationContent, + getTextPresenter, + getNotificationLink +} from '@hcengineering/server-notification-resources' import { generateToken } from '@hcengineering/server-token' import chunter, { ChatMessage } from '@hcengineering/chunter' import { markupToHTML } from '@hcengineering/text' -import activity, { ActivityMessage } from '@hcengineering/activity' +import activity, { ActivityMessage, DocUpdateMessage } from '@hcengineering/activity' /** * @public @@ -162,6 +166,14 @@ async function activityMessageToHtml (control: TriggerControl, message: Activity return undefined } +function isReactionMessage (message?: ActivityMessage): boolean { + return ( + message !== undefined && + message._class === activity.class.DocUpdateMessage && + (message as DocUpdateMessage).objectClass === activity.class.Reaction + ) +} + async function getTranslatedData ( data: InboxNotification, doc: Doc, @@ -171,6 +183,7 @@ async function getTranslatedData ( title: string quote: string | undefined body: string + link: string }> { const { hierarchy } = control @@ -189,15 +202,19 @@ async function getTranslatedData ( if (hierarchy.isDerived(doc._class, activity.class.ActivityMessage)) { const html = await activityMessageToHtml(control, doc as ActivityMessage) if (html !== undefined) { - title = '' quote = html } } + if (isReactionMessage(message)) { + title = await translate(activity.string.Reacted, {}) + } + return { title, quote, - body + body, + link: await getNotificationLink(control, doc, message?._id) } } @@ -217,7 +234,7 @@ const SendTelegramNotifications: NotificationProviderFunc = async ( const botUrl = getMetadata(serverTelegram.metadata.BotUrl) if (botUrl === undefined || botUrl === '') { - console.log('Please provide telegram bot service url to enable telegram notifications.') + control.ctx.error('Please provide telegram bot service url to enable telegram notifications.') return [] } @@ -226,7 +243,7 @@ const SendTelegramNotifications: NotificationProviderFunc = async ( } try { - const { title, body, quote } = await getTranslatedData(data, doc, control, message) + const { title, body, quote, link } = await getTranslatedData(data, doc, control, message) const record: TelegramNotificationRecord = { notificationId: data._id, account: receiver._id, @@ -234,7 +251,8 @@ const SendTelegramNotifications: NotificationProviderFunc = async ( sender: data.intlParams?.senderName?.toString() ?? formatName(sender.person?.name ?? 'System'), title, quote, - body + body, + link } await fetch(concatLink(botUrl, '/notify'), { @@ -246,7 +264,11 @@ const SendTelegramNotifications: NotificationProviderFunc = async ( body: JSON.stringify([record]) }) } catch (err) { - console.log('Could not send telegram notification', err) + control.ctx.error('Could not send telegram notification', { + err, + notificationId: data._id, + receiver: receiver.account.email + }) } return [] diff --git a/services/telegram-bot/pod-telegram-bot/src/bot.ts b/services/telegram-bot/pod-telegram-bot/src/bot.ts index 9bf2b556c7..2763d95a66 100644 --- a/services/telegram-bot/pod-telegram-bot/src/bot.ts +++ b/services/telegram-bot/pod-telegram-bot/src/bot.ts @@ -42,6 +42,9 @@ async function onStart (ctx: Context, worker: PlatformWorker): Promise { const message = welcomeMessage + '\n\n' + commandsHelp + '\n\n' + connectedMessage await ctx.replyWithHTML(message) + if (record.telegramUsername !== ctx.from?.username) { + await worker.updateTelegramUsername(record, ctx.from?.username) + } } else { const connectMessage = await translate(telegram.string.ConnectMessage, { app: config.App }, lang) const message = welcomeMessage + '\n\n' + commandsHelp + '\n\n' + connectMessage @@ -87,17 +90,27 @@ async function onConnect (ctx: Context, worker: PlatformWorker): Promise { return } - const code = await worker.generateCode(id) + const code = await worker.generateCode(id, ctx.from?.username) await ctx.reply(`*${code}*`, { parse_mode: 'MarkdownV2' }) } -async function onReply (id: number, message: TextMessage, replyTo: number, worker: PlatformWorker): Promise { +async function onReply ( + id: number, + message: TextMessage, + replyTo: number, + worker: PlatformWorker, + username?: string +): Promise { const userRecord = await worker.getUserRecord(id) if (userRecord === undefined) { return false } + if (userRecord.telegramUsername !== username) { + await worker.updateTelegramUsername(userRecord, username) + } + const notification = await worker.getNotificationRecord(replyTo, userRecord.email) if (notification === undefined) { @@ -127,7 +140,7 @@ export async function setUpBot (worker: PlatformWorker): Promise { } const replyTo = message.reply_to_message - const isReplied = await onReply(id, message as TextMessage, replyTo.message_id, worker) + const isReplied = await onReply(id, message as TextMessage, replyTo.message_id, worker, ctx.from.username) if (isReplied) { await ctx.react('👍') diff --git a/services/telegram-bot/pod-telegram-bot/src/server.ts b/services/telegram-bot/pod-telegram-bot/src/server.ts index 86f4efcd51..5430dbd828 100644 --- a/services/telegram-bot/pod-telegram-bot/src/server.ts +++ b/services/telegram-bot/pod-telegram-bot/src/server.ts @@ -111,6 +111,7 @@ export function createServer (bot: Telegraf, worker: PlatformWorker, ctx: Measur } await limiter.add(record.telegramId, async () => { + ctx.info('Sending test message', { email: token.email, username: record.telegramUsername }) const testMessage = await translate(telegram.string.TestMessage, { app: config.App }) await bot.telegram.sendMessage(record.telegramId, testMessage) }) @@ -146,6 +147,7 @@ export function createServer (bot: Telegraf, worker: PlatformWorker, ctx: Measur } void limiter.add(newRecord.telegramId, async () => { + ctx.info('Connected account', { email: token.email, username: newRecord.telegramUsername }) const message = await translate(telegram.string.AccountConnectedHtml, { app: config.App, email: token.email }) await bot.telegram.sendMessage(newRecord.telegramId, message, { parse_mode: 'HTML' }) }) @@ -175,11 +177,11 @@ export function createServer (bot: Telegraf, worker: PlatformWorker, ctx: Measur app.post( '/notify', wrapRequest(async (req, res, token) => { - ctx.info('Received notification', { email: token.email }) if (req.body == null || !Array.isArray(req.body)) { ctx.error('Invalid request body', { body: req.body, email: token.email }) throw new ApiError(400) } + const notificationRecords = req.body as TelegramNotificationRecord[] const userRecord = await worker.getUserRecordByEmail(token.email) @@ -188,6 +190,12 @@ export function createServer (bot: Telegraf, worker: PlatformWorker, ctx: Measur throw new ApiError(404) } + ctx.info('Received notification', { + email: token.email, + username: userRecord.telegramUsername, + ids: notificationRecords.map((it) => it.notificationId) + }) + for (const notificationRecord of notificationRecords) { void limiter.add(userRecord.telegramId, async () => { const formattedMessage = toTelegramHtml(notificationRecord) diff --git a/services/telegram-bot/pod-telegram-bot/src/start.ts b/services/telegram-bot/pod-telegram-bot/src/start.ts index 855c84fe75..bff0d81416 100644 --- a/services/telegram-bot/pod-telegram-bot/src/start.ts +++ b/services/telegram-bot/pod-telegram-bot/src/start.ts @@ -52,8 +52,10 @@ export const start = async (): Promise => { const app = createServer(bot, worker, ctx) if (config.Domain === '') { + ctx.info('Starting bot with polling') void bot.launch({ dropPendingUpdates: true }) } else { + ctx.info('Starting bot with webhook', { domain: config.Domain, port: config.BotPort }) void bot.launch({ webhook: { domain: config.Domain, port: config.BotPort }, dropPendingUpdates: true }).then(() => { void bot.telegram.getWebhookInfo().then((info) => { ctx.info('Webhook info', info) diff --git a/services/telegram-bot/pod-telegram-bot/src/types.ts b/services/telegram-bot/pod-telegram-bot/src/types.ts index c50f5e42c6..1d25554916 100644 --- a/services/telegram-bot/pod-telegram-bot/src/types.ts +++ b/services/telegram-bot/pod-telegram-bot/src/types.ts @@ -18,6 +18,7 @@ import { InboxNotification } from '@hcengineering/notification' export interface UserRecord { telegramId: number + telegramUsername?: string email: string } @@ -30,6 +31,7 @@ export interface NotificationRecord { export interface OtpRecord { telegramId: number + telegramUsername?: string code: string expires: Timestamp createdOn: Timestamp diff --git a/services/telegram-bot/pod-telegram-bot/src/utils.ts b/services/telegram-bot/pod-telegram-bot/src/utils.ts index 83945e992d..0ef383a09c 100644 --- a/services/telegram-bot/pod-telegram-bot/src/utils.ts +++ b/services/telegram-bot/pod-telegram-bot/src/utils.ts @@ -74,7 +74,8 @@ const maxBodyLength = 2000 const maxSenderLength = 100 export function toTelegramHtml (record: TelegramNotificationRecord): string { - const title = record.title !== '' ? `${platformToTelegram(record.title, maxTitleLength)}` + '\n' : '' + const title = + record.title !== '' ? `${platformToTelegram(record.title, maxTitleLength)}` + '\n' : '' const quote = record.quote !== undefined && record.quote !== '' ? `
${platformToTelegram(record.quote, maxQuoteLength)}
` + '\n' @@ -132,8 +133,8 @@ export function platformToTelegram (message: string, limit: number): string { newMessage += unescape(text) if (textLength > limit) { - const extra = textLength - limit - newMessage = newMessage.slice(0, -extra) + const extra = textLength - limit + 1 + newMessage = newMessage.slice(0, -extra) + '…' } }, onclosetag: (tag) => { diff --git a/services/telegram-bot/pod-telegram-bot/src/worker.ts b/services/telegram-bot/pod-telegram-bot/src/worker.ts index 3fd5709605..e8aa2dbb5e 100644 --- a/services/telegram-bot/pod-telegram-bot/src/worker.ts +++ b/services/telegram-bot/pod-telegram-bot/src/worker.ts @@ -64,11 +64,7 @@ export class PlatformWorker { } } - async getUsersRecords (): Promise { - return await this.usersStorage.find().toArray() - } - - async addUser (id: number, email: string): Promise { + async addUser (id: number, email: string, telegramUsername?: string): Promise { const emailRes = await this.usersStorage.findOne({ email }) if (emailRes !== null) { @@ -83,11 +79,18 @@ export class PlatformWorker { return } - const insertResult = await this.usersStorage.insertOne({ telegramId: id, email }) + const insertResult = await this.usersStorage.insertOne({ telegramId: id, email, telegramUsername }) return (await this.usersStorage.findOne({ _id: insertResult.insertedId })) ?? undefined } + async updateTelegramUsername (userRecord: UserRecord, telegramUsername?: string): Promise { + await this.usersStorage.updateOne( + { telegramId: userRecord.telegramId, email: userRecord.email }, + { $set: { telegramUsername } } + ) + } + async addNotificationRecord (record: NotificationRecord): Promise { await this.notificationsStorage.insertOne(record) } @@ -148,10 +151,10 @@ export class PlatformWorker { throw new Error('Invalid OTP') } - return await this.addUser(otpData.telegramId, email) + return await this.addUser(otpData.telegramId, email, otpData.telegramUsername) } - async generateCode (telegramId: number): Promise { + async generateCode (telegramId: number, telegramUsername?: string): Promise { const now = Date.now() const otpData = ( await this.otpStorage.find({ telegramId }).sort({ createdOn: SortingOrder.Descending }).limit(1).toArray() @@ -168,7 +171,7 @@ export class PlatformWorker { const timeToLive = config.OtpTimeToLiveSec * 1000 const expires = now + timeToLive - await this.otpStorage.insertOne({ telegramId, code: newCode, expires, createdOn: now }) + await this.otpStorage.insertOne({ telegramId, code: newCode, expires, createdOn: now, telegramUsername }) return newCode }