mirror of
https://github.com/whekin/household-bot.git
synced 2026-03-31 12:04:02 +00:00
fix(bot): improve utilities reminder template flow
This commit is contained in:
@@ -270,7 +270,8 @@ export const enBotTranslations: BotTranslationCatalog = {
|
||||
`I could not read that amount for ${categoryName}. Reply with a number in ${currency}, or send 0 / "skip".`,
|
||||
templateIntro: (currency) =>
|
||||
`Fill in the utility amounts below in ${currency}, then send the completed message back in this topic.`,
|
||||
templateInstruction: 'Use 0 or skip for any category you want to leave empty.',
|
||||
templateInstruction:
|
||||
'For any category you do not want to add, leave it blank, remove the line entirely, or send 0 / "skip".',
|
||||
templateInvalid:
|
||||
'I could not read any utility amounts from that template. Send the filled template back with at least one amount.',
|
||||
summaryTitle: (period) => `Utility charges for ${period}`,
|
||||
|
||||
@@ -275,7 +275,7 @@ export const ruBotTranslations: BotTranslationCatalog = {
|
||||
templateIntro: (currency) =>
|
||||
`Заполните суммы по коммуналке ниже в ${currency}, затем отправьте заполненное сообщение обратно в этот топик.`,
|
||||
templateInstruction:
|
||||
'Для любой категории, которую не нужно добавлять, укажите 0 или слово «пропуск».',
|
||||
'Для любой категории, которую не нужно добавлять, оставьте поле пустым, удалите строку целиком или укажите 0 / «пропуск».',
|
||||
templateInvalid:
|
||||
'Не удалось распознать ни одной суммы в этом шаблоне. Отправьте заполненный шаблон хотя бы с одной суммой.',
|
||||
summaryTitle: (period) => `Коммунальные начисления за ${period}`,
|
||||
|
||||
@@ -375,7 +375,8 @@ describe('registerReminderTopicUtilities', () => {
|
||||
expect(calls[1]).toMatchObject({
|
||||
method: 'sendMessage',
|
||||
payload: {
|
||||
text: expect.stringContaining('Electricity:'),
|
||||
text: expect.stringContaining('<pre>Electricity: \nWater: </pre>'),
|
||||
parse_mode: 'HTML',
|
||||
message_thread_id: 555
|
||||
}
|
||||
})
|
||||
@@ -391,6 +392,34 @@ describe('registerReminderTopicUtilities', () => {
|
||||
})
|
||||
})
|
||||
|
||||
test('treats blank or removed template lines as skipped categories', async () => {
|
||||
const { bot, calls } = setupBot()
|
||||
|
||||
await bot.handleUpdate(reminderCallbackUpdate(REMINDER_UTILITY_TEMPLATE_CALLBACK) as never)
|
||||
|
||||
calls.length = 0
|
||||
await bot.handleUpdate(reminderMessageUpdate('Electricity: 22\nWater: ') as never)
|
||||
|
||||
expect(calls[0]).toMatchObject({
|
||||
method: 'sendMessage',
|
||||
payload: {
|
||||
text: expect.stringContaining('- Electricity: 22.00 GEL')
|
||||
}
|
||||
})
|
||||
|
||||
calls.length = 0
|
||||
await bot.handleUpdate(reminderCallbackUpdate(REMINDER_UTILITY_TEMPLATE_CALLBACK) as never)
|
||||
calls.length = 0
|
||||
await bot.handleUpdate(reminderMessageUpdate('Electricity: 22') as never)
|
||||
|
||||
expect(calls[0]).toMatchObject({
|
||||
method: 'sendMessage',
|
||||
payload: {
|
||||
text: expect.stringContaining('- Electricity: 22.00 GEL')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('treats expired pending reminder submissions as unavailable', async () => {
|
||||
const { bot, calls, promptRepository } = setupBot()
|
||||
|
||||
|
||||
@@ -182,20 +182,32 @@ function parseTemplateEntries(
|
||||
return entries.length > 0 ? entries : null
|
||||
}
|
||||
|
||||
function escapeHtml(raw: string): string {
|
||||
return raw.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>')
|
||||
}
|
||||
|
||||
function buildTemplateText(
|
||||
locale: BotLocale,
|
||||
currency: 'GEL' | 'USD',
|
||||
categories: readonly string[]
|
||||
): string {
|
||||
): {
|
||||
text: string
|
||||
parseMode: 'HTML'
|
||||
} {
|
||||
const t = getBotTranslations(locale).reminders
|
||||
|
||||
return [
|
||||
t.templateIntro(currency),
|
||||
const templateLines = categories.map((category) => `${category}: `).join('\n')
|
||||
|
||||
return {
|
||||
text: [
|
||||
escapeHtml(t.templateIntro(currency)),
|
||||
'',
|
||||
...categories.map((category) => `${category}: `),
|
||||
`<pre>${escapeHtml(templateLines)}</pre>`,
|
||||
'',
|
||||
t.templateInstruction
|
||||
].join('\n')
|
||||
escapeHtml(t.templateInstruction)
|
||||
].join('\n'),
|
||||
parseMode: 'HTML'
|
||||
}
|
||||
}
|
||||
|
||||
function reminderUtilitySummaryText(
|
||||
@@ -261,7 +273,10 @@ function buildReminderConfirmationPayload(input: {
|
||||
async function replyInTopic(
|
||||
ctx: Context,
|
||||
text: string,
|
||||
replyMarkup?: InlineKeyboardMarkup
|
||||
replyMarkup?: InlineKeyboardMarkup,
|
||||
options?: {
|
||||
parseMode?: 'HTML'
|
||||
}
|
||||
): Promise<void> {
|
||||
const message = ctx.msg
|
||||
if (!ctx.chat || !message) {
|
||||
@@ -286,6 +301,11 @@ async function replyInTopic(
|
||||
? {
|
||||
reply_markup: replyMarkup as InlineKeyboardMarkup
|
||||
}
|
||||
: {}),
|
||||
...(options?.parseMode
|
||||
? {
|
||||
parse_mode: options.parseMode
|
||||
}
|
||||
: {})
|
||||
})
|
||||
}
|
||||
@@ -481,14 +501,14 @@ export function registerReminderTopicUtilities(options: {
|
||||
await ctx.answerCallbackQuery({
|
||||
text: t.templateToast
|
||||
})
|
||||
await replyInTopic(
|
||||
ctx,
|
||||
buildTemplateText(
|
||||
const template = buildTemplateText(
|
||||
reminderContext.locale,
|
||||
reminderContext.currency,
|
||||
reminderContext.categories
|
||||
)
|
||||
)
|
||||
await replyInTopic(ctx, template.text, undefined, {
|
||||
parseMode: template.parseMode
|
||||
})
|
||||
}
|
||||
|
||||
options.bot.callbackQuery(REMINDER_UTILITY_GUIDED_CALLBACK, async (ctx) => {
|
||||
|
||||
Reference in New Issue
Block a user