From cc7240c7d9cebe2b9705f700c95005bc4ad958aa Mon Sep 17 00:00:00 2001 From: Kristina Date: Tue, 13 Aug 2024 15:10:56 +0400 Subject: [PATCH] Support replies on reply (#6327) Signed-off-by: Kristina Fefelova --- .../telegram-bot/pod-telegram-bot/src/bot.ts | 40 +++++++++++++++++-- .../pod-telegram-bot/src/types.ts | 6 +++ .../pod-telegram-bot/src/worker.ts | 30 +++++++++++--- 3 files changed, 66 insertions(+), 10 deletions(-) diff --git a/services/telegram-bot/pod-telegram-bot/src/bot.ts b/services/telegram-bot/pod-telegram-bot/src/bot.ts index 2763d95a66..5fe713dd3f 100644 --- a/services/telegram-bot/pod-telegram-bot/src/bot.ts +++ b/services/telegram-bot/pod-telegram-bot/src/bot.ts @@ -24,6 +24,7 @@ import { TextMessage } from '@telegraf/entity/types/types' import config from './config' import { PlatformWorker } from './worker' import { getBotCommands, getCommandsHelp } from './utils' +import { NotificationRecord } from './types' async function onStart (ctx: Context, worker: PlatformWorker): Promise { const id = ctx.from?.id @@ -94,14 +95,36 @@ async function onConnect (ctx: Context, worker: PlatformWorker): Promise { await ctx.reply(`*${code}*`, { parse_mode: 'MarkdownV2' }) } +async function findNotificationRecord ( + worker: PlatformWorker, + from: number, + replyTo: number, + email: string +): Promise { + const record = await worker.getNotificationRecord(replyTo, email) + + if (record !== undefined) { + return record + } + + const reply = await worker.getReply(from, replyTo) + + if (reply === undefined) { + return undefined + } + + return await worker.getNotificationRecordById(reply.notificationId, email) +} + async function onReply ( - id: number, + from: number, message: TextMessage, + messageId: number, replyTo: number, worker: PlatformWorker, username?: string ): Promise { - const userRecord = await worker.getUserRecord(id) + const userRecord = await worker.getUserRecord(from) if (userRecord === undefined) { return false @@ -111,12 +134,14 @@ async function onReply ( await worker.updateTelegramUsername(userRecord, username) } - const notification = await worker.getNotificationRecord(replyTo, userRecord.email) + const notification = await findNotificationRecord(worker, from, replyTo, userRecord.email) if (notification === undefined) { return false } + await worker.saveReply({ replyId: messageId, telegramId: from, notificationId: notification.notificationId }) + return await worker.reply(notification, htmlToMarkup(toHTML(message))) } @@ -140,7 +165,14 @@ 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, ctx.from.username) + const isReplied = await onReply( + id, + message as TextMessage, + message.message_id, + replyTo.message_id, + worker, + ctx.from.username + ) if (isReplied) { await ctx.react('👍') diff --git a/services/telegram-bot/pod-telegram-bot/src/types.ts b/services/telegram-bot/pod-telegram-bot/src/types.ts index 1d25554916..b2721132d7 100644 --- a/services/telegram-bot/pod-telegram-bot/src/types.ts +++ b/services/telegram-bot/pod-telegram-bot/src/types.ts @@ -29,6 +29,12 @@ export interface NotificationRecord { telegramId: number } +export interface ReplyRecord { + notificationId: Ref + telegramId: number + replyId: number +} + export interface OtpRecord { telegramId: number telegramUsername?: string diff --git a/services/telegram-bot/pod-telegram-bot/src/worker.ts b/services/telegram-bot/pod-telegram-bot/src/worker.ts index e8aa2dbb5e..e37237cc87 100644 --- a/services/telegram-bot/pod-telegram-bot/src/worker.ts +++ b/services/telegram-bot/pod-telegram-bot/src/worker.ts @@ -15,8 +15,9 @@ import type { Collection } from 'mongodb' import { Account, Ref, SortingOrder } from '@hcengineering/core' +import { InboxNotification } from '@hcengineering/notification' -import { UserRecord, NotificationRecord, OtpRecord } from './types' +import { UserRecord, NotificationRecord, OtpRecord, ReplyRecord } from './types' import { getDB } from './storage' import { WorkspaceClient } from './workspace' import { getNewOtp } from './utils' @@ -32,7 +33,8 @@ export class PlatformWorker { private constructor ( private readonly usersStorage: Collection, private readonly notificationsStorage: Collection, - private readonly otpStorage: Collection + private readonly otpStorage: Collection, + private readonly repliesStorage: Collection ) { this.intervalId = setInterval( () => { @@ -103,10 +105,25 @@ export class PlatformWorker { await this.usersStorage.deleteOne({ account: _id }) } + async saveReply (record: ReplyRecord): Promise { + await this.repliesStorage.insertOne(record) + } + + async getReply (id: number, replyTo: number): Promise { + return (await this.repliesStorage.findOne({ telegramId: id, replyId: replyTo })) ?? undefined + } + async getNotificationRecord (id: number, email: string): Promise { return (await this.notificationsStorage.findOne({ telegramId: id, email })) ?? undefined } + async getNotificationRecordById ( + notificationId: Ref, + email: string + ): Promise { + return (await this.notificationsStorage.findOne({ notificationId, email })) ?? undefined + } + async getUserRecord (id: number): Promise { return (await this.usersStorage.findOne({ telegramId: id })) ?? undefined } @@ -177,19 +194,20 @@ export class PlatformWorker { } static async createStorages (): Promise< - [Collection, Collection, Collection] + [Collection, Collection, Collection, Collection] > { const db = await getDB() const userStorage = db.collection('users') const notificationsStorage = db.collection('notifications') const otpStorage = db.collection('otp') + const repliesStorage = db.collection('replies') - return [userStorage, notificationsStorage, otpStorage] + return [userStorage, notificationsStorage, otpStorage, repliesStorage] } static async create (): Promise { - const [userStorage, notificationsStorage, otpStorage] = await PlatformWorker.createStorages() + const [userStorage, notificationsStorage, otpStorage, repliesStorage] = await PlatformWorker.createStorages() - return new PlatformWorker(userStorage, notificationsStorage, otpStorage) + return new PlatformWorker(userStorage, notificationsStorage, otpStorage, repliesStorage) } }