mirror of
https://github.com/hcengineering/platform.git
synced 2025-05-29 11:31:32 +00:00
Fix tg parsing error for inline actions (#6747)
Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
parent
398f6b477b
commit
3c63f108b2
@ -20,7 +20,7 @@ import { htmlToMarkup, isEmptyMarkup, jsonToMarkup, MarkupNodeType } from '@hcen
|
||||
import { toHTML } from '@telegraf/entity'
|
||||
import { CallbackQuery, Message, Update } from 'telegraf/typings/core/types/typegram'
|
||||
import { translate } from '@hcengineering/platform'
|
||||
import { WithId } from 'mongodb'
|
||||
import { ObjectId, WithId } from 'mongodb'
|
||||
|
||||
import config from '../config'
|
||||
import { PlatformWorker } from '../worker'
|
||||
@ -29,13 +29,13 @@ import { toTelegramFileInfo } from '../utils'
|
||||
import { Command, defineCommands } from './commands'
|
||||
import { ChannelRecord, MessageRecord, TelegramFileInfo, UserRecord, WorkspaceInfo } from '../types'
|
||||
|
||||
function encodeChannelId (workspace: string, channelId: string): string {
|
||||
return `${workspace}_${channelId}`
|
||||
function encodeChannelId (channelId: string): string {
|
||||
return `@${channelId}`
|
||||
}
|
||||
|
||||
function decodeChannelId (id: string): { workspace: string, channelId: string } {
|
||||
const [workspace, channelId] = id.split('_')
|
||||
return { workspace, channelId }
|
||||
function decodeChannelId (id: string): string | undefined {
|
||||
const [, channelId] = id.split('@')
|
||||
return channelId
|
||||
}
|
||||
|
||||
const getNextActionId = (workspace: string, page: number): string => `next_${workspace}_${page}`
|
||||
@ -114,10 +114,9 @@ async function handleSelectChannel (
|
||||
const userRecord = await worker.getUserRecord(id)
|
||||
if (userRecord === undefined) return ['', false]
|
||||
|
||||
const { workspace, channelId } = decodeChannelId(match)
|
||||
|
||||
const channels = await worker.getChannels(userRecord.email, workspace)
|
||||
const channel = channels.find((it) => it._id.toString() === channelId)
|
||||
const channelId = decodeChannelId(match)
|
||||
if (channelId === undefined || channelId === '') return ['', false]
|
||||
const channel = await worker.getChannel(userRecord.email, new ObjectId(channelId))
|
||||
|
||||
if (channel === undefined) return ['', false]
|
||||
|
||||
@ -134,6 +133,14 @@ async function handleSelectChannel (
|
||||
return [channel.name, await worker.sendMessage(channel, userMessage.message_id, text, file)]
|
||||
}
|
||||
|
||||
async function showNoChannelsMessage (ctx: Context, worker: PlatformWorker, workspace: string): Promise<void> {
|
||||
const ws = await worker.getWorkspaceInfo(workspace)
|
||||
await ctx.editMessageText(
|
||||
`No channels found in workspace <b>${ws?.name ?? workspace}</b>.\nTo sync channels call /${Command.SyncAllChannels} or /${Command.SyncStarredChannels}`,
|
||||
{ parse_mode: 'HTML' }
|
||||
)
|
||||
}
|
||||
|
||||
async function createSelectChannelKeyboard (
|
||||
ctx: NarrowedContext<TgContext, Update.MessageUpdate>,
|
||||
worker: PlatformWorker,
|
||||
@ -141,6 +148,12 @@ async function createSelectChannelKeyboard (
|
||||
workspace: string
|
||||
): Promise<void> {
|
||||
const channels = await worker.getChannels(userRecord.email, workspace)
|
||||
|
||||
if (channels.length === 0) {
|
||||
await showNoChannelsMessage(ctx, worker, workspace)
|
||||
return
|
||||
}
|
||||
|
||||
const hasNext = channels.length > channelsPerPage
|
||||
const pageChannels = getPageChannels(channels, 0)
|
||||
|
||||
@ -148,9 +161,7 @@ async function createSelectChannelKeyboard (
|
||||
reply_parameters: { message_id: ctx.message.message_id },
|
||||
...Markup.inlineKeyboard(
|
||||
[
|
||||
...pageChannels.map((channel) =>
|
||||
Markup.button.callback(channel.name, encodeChannelId(channel.workspace, channel._id.toString()))
|
||||
),
|
||||
...pageChannels.map((channel) => Markup.button.callback(channel.name, encodeChannelId(channel._id.toString()))),
|
||||
...(hasNext ? [Markup.button.callback('Next>', getNextActionId(workspace, 0))] : [])
|
||||
],
|
||||
{ columns: 1 }
|
||||
@ -283,7 +294,7 @@ export async function setUpBot (worker: PlatformWorker): Promise<Telegraf<TgCont
|
||||
ctx.processingKeyboards.delete(messageId)
|
||||
})
|
||||
|
||||
bot.action(/.+_.+/, async (ctx) => {
|
||||
bot.action(/@.+/, async (ctx) => {
|
||||
const messageId = ctx.callbackQuery.message?.message_id
|
||||
if (messageId === undefined) return
|
||||
if (ctx.processingKeyboards.has(messageId)) return
|
||||
@ -341,11 +352,7 @@ const editChannelKeyboard = async (
|
||||
const channels = await worker.getChannels(userRecord.email, workspace)
|
||||
|
||||
if (channels.length === 0) {
|
||||
const ws = await worker.getWorkspaceInfo(workspace)
|
||||
await ctx.editMessageText(
|
||||
`No channels found in workspace <b>${ws?.name ?? workspace}</b>.\nTo add channels call /${Command.SyncAllChannels} or /${Command.SyncStarredChannels}`,
|
||||
{ parse_mode: 'HTML' }
|
||||
)
|
||||
await showNoChannelsMessage(ctx, worker, workspace)
|
||||
return
|
||||
}
|
||||
|
||||
@ -355,9 +362,7 @@ const editChannelKeyboard = async (
|
||||
|
||||
await ctx.editMessageReplyMarkup({
|
||||
inline_keyboard: [
|
||||
...pageChannels.map((channel) => [
|
||||
Markup.button.callback(channel.name, encodeChannelId(channel.workspace, channel._id.toString()))
|
||||
]),
|
||||
...pageChannels.map((channel) => [Markup.button.callback(channel.name, encodeChannelId(channel._id.toString()))]),
|
||||
[
|
||||
...(hasPrev ? [Markup.button.callback('<Prev', getPrevActionId(workspace, page))] : []),
|
||||
...(hasNext ? [Markup.button.callback('Next>', getNextActionId(workspace, page))] : [])
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { Collection, WithId } from 'mongodb'
|
||||
import type { Collection, ObjectId, WithId } from 'mongodb'
|
||||
import { MeasureContext, Ref, SortingOrder, systemAccountEmail } from '@hcengineering/core'
|
||||
import { InboxNotification } from '@hcengineering/notification'
|
||||
import { TelegramNotificationRequest } from '@hcengineering/telegram'
|
||||
@ -44,9 +44,11 @@ const closeWorkspaceTimeout = 10 * 60 * 1000 // 10 minutes
|
||||
export class PlatformWorker {
|
||||
private readonly workspacesClients = new Map<string, WorkspaceClient>()
|
||||
private readonly closeWorkspaceTimeouts: Map<string, NodeJS.Timeout> = new Map<string, NodeJS.Timeout>()
|
||||
private readonly intervalId: NodeJS.Timeout | undefined
|
||||
private readonly otpIntervalId: NodeJS.Timeout | undefined
|
||||
private readonly clearIntervalId: NodeJS.Timeout | undefined
|
||||
|
||||
private readonly channelsMap = new Map<string, WithId<ChannelRecord>[]>()
|
||||
private readonly channelsByWorkspace = new Map<string, WithId<ChannelRecord>[]>()
|
||||
private readonly channelById = new Map<ObjectId, WithId<ChannelRecord>>()
|
||||
private readonly workspaceInfoById = new Map<string, WorkspaceInfo>()
|
||||
|
||||
private constructor (
|
||||
@ -58,12 +60,19 @@ export class PlatformWorker {
|
||||
private readonly repliesStorage: Collection<ReplyRecord>,
|
||||
private readonly channelsStorage: Collection<ChannelRecord>
|
||||
) {
|
||||
this.intervalId = setInterval(
|
||||
this.otpIntervalId = setInterval(
|
||||
() => {
|
||||
void otpStorage.deleteMany({ expires: { $lte: Date.now() } })
|
||||
},
|
||||
3 * 60 * 1000
|
||||
)
|
||||
this.clearIntervalId = setInterval(
|
||||
() => {
|
||||
this.channelsByWorkspace.clear()
|
||||
this.channelById.clear()
|
||||
},
|
||||
60 * 60 * 1000
|
||||
)
|
||||
}
|
||||
|
||||
public async getUsersToDisconnect (): Promise<UserRecord[]> {
|
||||
@ -75,8 +84,11 @@ export class PlatformWorker {
|
||||
}
|
||||
|
||||
async close (): Promise<void> {
|
||||
if (this.intervalId !== undefined) {
|
||||
clearInterval(this.intervalId)
|
||||
if (this.otpIntervalId !== undefined) {
|
||||
clearInterval(this.otpIntervalId)
|
||||
}
|
||||
if (this.clearIntervalId !== undefined) {
|
||||
clearInterval(this.clearIntervalId)
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,14 +266,32 @@ export class PlatformWorker {
|
||||
async getChannels (email: string, workspace: string): Promise<WithId<ChannelRecord>[]> {
|
||||
const key = `${email}:${workspace}`
|
||||
|
||||
if (this.channelsMap.has(key)) {
|
||||
return this.channelsMap.get(key) ?? []
|
||||
if (this.channelsByWorkspace.has(key)) {
|
||||
return this.channelsByWorkspace.get(key) ?? []
|
||||
}
|
||||
const res = await this.channelsStorage
|
||||
.find({ workspace, email }, { sort: { name: SortingOrder.Ascending } })
|
||||
.toArray()
|
||||
|
||||
this.channelsMap.set(key, res)
|
||||
this.channelsByWorkspace.set(key, res)
|
||||
for (const channel of res) {
|
||||
this.channelById.set(channel._id, channel)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
async getChannel (email: string, channelId: ObjectId): Promise<WithId<ChannelRecord> | undefined> {
|
||||
if (this.channelById.has(channelId)) {
|
||||
const channel = this.channelById.get(channelId)
|
||||
|
||||
return channel !== undefined && channel.email === email ? channel : undefined
|
||||
}
|
||||
|
||||
const res = (await this.channelsStorage.findOne({ _id: channelId, email })) ?? undefined
|
||||
|
||||
if (res !== undefined) {
|
||||
this.channelById.set(res._id, res)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@ -317,7 +347,12 @@ export class PlatformWorker {
|
||||
await this.channelsStorage.deleteMany({ _id: { $in: toDelete.map((c) => c._id) } })
|
||||
}
|
||||
|
||||
this.channelsMap.delete(`${email}:${workspace}`)
|
||||
this.channelsByWorkspace.delete(`${email}:${workspace}`)
|
||||
for (const [key, channel] of this.channelById.entries()) {
|
||||
if (channel.email === email) {
|
||||
this.channelById.delete(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async getWorkspaceInfo (workspaceId: string): Promise<WorkspaceInfo | undefined> {
|
||||
|
Loading…
Reference in New Issue
Block a user