fix(bot): shorten payment topic callback payloads

This commit is contained in:
2026-03-11 11:46:25 +04:00
parent cd3b364125
commit 9553ca342a
2 changed files with 76 additions and 82 deletions

View File

@@ -338,11 +338,11 @@ describe('registerConfiguredPaymentTopicIngestion', () => {
[
{
text: 'Подтвердить оплату',
callback_data: expect.stringContaining('payment_topic:confirm:10002:')
callback_data: expect.stringMatching(/^payment_topic:confirm:[^:]+$/)
},
{
text: 'Отменить',
callback_data: expect.stringContaining('payment_topic:cancel:10002:')
callback_data: expect.stringMatching(/^payment_topic:cancel:[^:]+$/)
}
]
]
@@ -352,6 +352,13 @@ describe('registerConfiguredPaymentTopicIngestion', () => {
expect(await promptRepository.getPendingAction('-10012345', '10002')).toMatchObject({
action: 'payment_topic_confirmation'
})
const proposalId = (
(await promptRepository.getPendingAction('-10012345', '10002'))?.payload as {
proposalId?: string
} | null
)?.proposalId
expect(`payment_topic:confirm:${proposalId ?? ''}`.length).toBeLessThanOrEqual(64)
expect(`payment_topic:cancel:${proposalId ?? ''}`.length).toBeLessThanOrEqual(64)
})
test('asks for clarification and resolves follow-up answers in the same payments topic', async () => {
@@ -448,7 +455,7 @@ describe('registerConfiguredPaymentTopicIngestion', () => {
calls.length = 0
await bot.handleUpdate(
paymentCallbackUpdate(`payment_topic:confirm:10002:${proposalId ?? 'missing'}`) as never
paymentCallbackUpdate(`payment_topic:confirm:${proposalId ?? 'missing'}`) as never
)
expect(paymentConfirmationService.submitted).toEqual([

View File

@@ -216,11 +216,7 @@ function parsePaymentTopicConfirmationPayload(
}
}
function paymentProposalReplyMarkup(
locale: BotLocale,
senderTelegramUserId: string,
proposalId: string
) {
function paymentProposalReplyMarkup(locale: BotLocale, proposalId: string) {
const t = getBotTranslations(locale).payments
return {
@@ -228,11 +224,11 @@ function paymentProposalReplyMarkup(
[
{
text: t.confirmButton,
callback_data: `${PAYMENT_TOPIC_CONFIRM_CALLBACK_PREFIX}${senderTelegramUserId}:${proposalId}`
callback_data: `${PAYMENT_TOPIC_CONFIRM_CALLBACK_PREFIX}${proposalId}`
},
{
text: t.cancelButton,
callback_data: `${PAYMENT_TOPIC_CANCEL_CALLBACK_PREFIX}${senderTelegramUserId}:${proposalId}`
callback_data: `${PAYMENT_TOPIC_CANCEL_CALLBACK_PREFIX}${proposalId}`
}
]
]
@@ -272,30 +268,21 @@ export function registerConfiguredPaymentTopicIngestion(
} = {}
): void {
bot.callbackQuery(
new RegExp(`^${PAYMENT_TOPIC_CONFIRM_CALLBACK_PREFIX}(\\d+):([^:]+)$`),
new RegExp(`^${PAYMENT_TOPIC_CONFIRM_CALLBACK_PREFIX}([^:]+)$`),
async (ctx) => {
if (ctx.chat?.type !== 'group' && ctx.chat?.type !== 'supergroup') {
return
}
const actorTelegramUserId = ctx.from?.id?.toString()
const ownerTelegramUserId = ctx.match[1]
const proposalId = ctx.match[2]
if (!actorTelegramUserId || !ownerTelegramUserId || !proposalId) {
const proposalId = ctx.match[1]
if (!actorTelegramUserId || !proposalId) {
return
}
const locale = await resolveTopicLocale(ctx, householdConfigurationRepository)
const t = getBotTranslations(locale).payments
if (actorTelegramUserId !== ownerTelegramUserId) {
await ctx.answerCallbackQuery({
text: t.notYourProposal,
show_alert: true
})
return
}
const pending = await promptRepository.getPendingAction(
ctx.chat.id.toString(),
actorTelegramUserId
@@ -313,6 +300,14 @@ export function registerConfiguredPaymentTopicIngestion(
return
}
if (payload.senderTelegramUserId !== actorTelegramUserId) {
await ctx.answerCallbackQuery({
text: t.notYourProposal,
show_alert: true
})
return
}
const paymentService = paymentServiceForHousehold(payload.householdId)
const result = await paymentService.submit({
...payload,
@@ -348,31 +343,20 @@ export function registerConfiguredPaymentTopicIngestion(
}
)
bot.callbackQuery(
new RegExp(`^${PAYMENT_TOPIC_CANCEL_CALLBACK_PREFIX}(\\d+):([^:]+)$`),
async (ctx) => {
bot.callbackQuery(new RegExp(`^${PAYMENT_TOPIC_CANCEL_CALLBACK_PREFIX}([^:]+)$`), async (ctx) => {
if (ctx.chat?.type !== 'group' && ctx.chat?.type !== 'supergroup') {
return
}
const actorTelegramUserId = ctx.from?.id?.toString()
const ownerTelegramUserId = ctx.match[1]
const proposalId = ctx.match[2]
if (!actorTelegramUserId || !ownerTelegramUserId || !proposalId) {
const proposalId = ctx.match[1]
if (!actorTelegramUserId || !proposalId) {
return
}
const locale = await resolveTopicLocale(ctx, householdConfigurationRepository)
const t = getBotTranslations(locale).payments
if (actorTelegramUserId !== ownerTelegramUserId) {
await ctx.answerCallbackQuery({
text: t.notYourProposal,
show_alert: true
})
return
}
const pending = await promptRepository.getPendingAction(
ctx.chat.id.toString(),
actorTelegramUserId
@@ -390,6 +374,14 @@ export function registerConfiguredPaymentTopicIngestion(
return
}
if (payload.senderTelegramUserId !== actorTelegramUserId) {
await ctx.answerCallbackQuery({
text: t.notYourProposal,
show_alert: true
})
return
}
await promptRepository.clearPendingAction(ctx.chat.id.toString(), actorTelegramUserId)
await ctx.answerCallbackQuery({
text: t.cancelled
@@ -402,8 +394,7 @@ export function registerConfiguredPaymentTopicIngestion(
}
})
}
}
)
})
bot.on('message', async (ctx, next) => {
const candidate = toCandidateFromContext(ctx)
@@ -517,11 +508,7 @@ export function registerConfiguredPaymentTopicIngestion(
await replyToPaymentMessage(
ctx,
t.proposal(proposal.payload.kind, amount.toMajorString(), amount.currency),
paymentProposalReplyMarkup(
locale,
record.senderTelegramUserId,
proposal.payload.proposalId
)
paymentProposalReplyMarkup(locale, proposal.payload.proposalId)
)
}
} catch (error) {