feat(bot): improve /setup UX and update checklist on /bind

- Enhance /setup message with a warmer greeting and binding instructions\n- Rename 'Setup' buttons to 'Create' for clarity\n- Track /setup message ID to enable automatic checklist updates when /bind is used\n- Refresh /setup checklist after successful topic binding\n- Update English and Russian translations
This commit is contained in:
2026-03-15 01:44:13 +04:00
parent d0475743f8
commit 531e52b238
4 changed files with 62 additions and 11 deletions

View File

@@ -874,14 +874,14 @@ describe('registerHouseholdSetupCommands', () => {
chat_id: -100123456 chat_id: -100123456
} }
}) })
expect(sendPayload.text).toContain('Welcome! Kojori House is successfully registered') expect(sendPayload.text).toContain('New household! **Kojori House** is ready.')
expect(sendPayload.text).toContain("Let's configure your household topics to get started") expect(sendPayload.text).toContain('Current setup progress: 0/5')
expect(sendPayload.text).toContain('(0/5)') expect(sendPayload.text).toContain('0/5')
expect(sendPayload.text).toContain('⚪ Purchases') expect(sendPayload.text).toContain('⚪ Purchases')
expect(sendPayload.text).toContain('⚪ Payments') expect(sendPayload.text).toContain('⚪ Payments')
// Check that join household button exists // Check that join household button exists
expect(JSON.stringify(sendPayload.reply_markup)).toContain('Join household') expect(JSON.stringify(sendPayload.reply_markup)).toContain('Join household')
expect(JSON.stringify(sendPayload.reply_markup)).toContain('Setup Purchases') expect(JSON.stringify(sendPayload.reply_markup)).toContain('Create Purchases')
expect(JSON.stringify(sendPayload.reply_markup)).toContain('setup_topic:create:purchase') expect(JSON.stringify(sendPayload.reply_markup)).toContain('setup_topic:create:purchase')
}) })

View File

@@ -565,7 +565,20 @@ export function registerHouseholdSetupCommands(options: {
household: result.household, household: result.household,
created: result.status === 'created' created: result.status === 'created'
}) })
await ctx.reply(reply.text, 'reply_markup' in reply ? { reply_markup: reply.reply_markup } : {}) const sent = await ctx.reply(
reply.text,
'reply_markup' in reply ? { reply_markup: reply.reply_markup } : {}
)
if (options.promptRepository) {
await options.promptRepository.upsertPendingAction({
telegramUserId: `setup_tracking:${result.household.householdId}`,
telegramChatId: ctx.chat.id.toString(),
action: 'setup_topic_binding',
payload: { setupMessageId: sent.message_id },
expiresAt: null
})
}
}) })
options.bot.command('unsetup', async (ctx) => { options.bot.command('unsetup', async (ctx) => {
@@ -1041,6 +1054,40 @@ export function registerHouseholdSetupCommands(options: {
t.topicBoundSuccess(setupTopicRoleLabel(locale, role), result.household.householdName) t.topicBoundSuccess(setupTopicRoleLabel(locale, role), result.household.householdName)
) )
} }
// Try to update the main /setup checklist if it exists
if (options.promptRepository) {
const setupTracking = await options.promptRepository.getPendingAction(
telegramChatId,
`setup_tracking:${result.household.householdId}`
)
if (setupTracking?.payload.setupMessageId) {
const setupMessageId = setupTracking.payload.setupMessageId as number
const refreshed = await buildSetupReplyForHousehold({
ctx,
locale,
household: result.household,
created: false
})
try {
await ctx.api.editMessageText(telegramChatId, setupMessageId, refreshed.text, {
reply_markup: refreshed.reply_markup
} as any)
} catch (error) {
// Message might be deleted or too old, ignore
options.logger?.debug(
{
event: 'household_setup.update_checklist_failed',
error,
setupMessageId
},
'Failed to update setup checklist message'
)
}
}
}
} }
) )
} }

View File

@@ -51,12 +51,14 @@ export const enBotTranslations: BotTranslationCatalog = {
joinRequestSent: (householdName) => joinRequestSent: (householdName) =>
`Join request sent for ${householdName}. Wait for a household admin to confirm you.`, `Join request sent for ${householdName}. Wait for a household admin to confirm you.`,
setupSummary: ({ householdName, created }) => setupSummary: ({ householdName, created }) =>
`${created ? '✨' : ''} Welcome! ${householdName} is ${created ? 'successfully registered' : 'already active'} and ready to help.`, `🏡 ${created ? 'New household!' : 'Household active!'} **${householdName}** is ready.\n\n` +
`I've set up the basic configuration. Now, let's organize your communication by linking topics for specific roles.`,
setupTopicsHeading: (configured, total) => setupTopicsHeading: (configured, total) =>
`Let's configure your household topics to get started (${configured}/${total}):`, `Current setup progress: ${configured}/${total}\n\n` +
`Tap buttons below to create new topics automatically, or go to any existing topic and use /bind to link it manually.`,
setupTopicBound: (role) => `${role}`, setupTopicBound: (role) => `${role}`,
setupTopicMissing: (role) => `${role}`, setupTopicMissing: (role) => `${role}`,
setupTopicCreateButton: (role) => `Setup ${role}`, setupTopicCreateButton: (role) => `Create ${role}`,
setupTopicBindButton: (role) => `Bind ${role}`, setupTopicBindButton: (role) => `Bind ${role}`,
useBindInTopic: 'Run /bind inside a topic to link it to a role.', useBindInTopic: 'Run /bind inside a topic to link it to a role.',
topicAlreadyBound: (role) => `This topic is already linked to ${role}.`, topicAlreadyBound: (role) => `This topic is already linked to ${role}.`,

View File

@@ -53,12 +53,14 @@ export const ruBotTranslations: BotTranslationCatalog = {
joinRequestSent: (householdName) => joinRequestSent: (householdName) =>
`Заявка на вступление в ${householdName} отправлена. Дождитесь подтверждения от админа дома.`, `Заявка на вступление в ${householdName} отправлена. Дождитесь подтверждения от админа дома.`,
setupSummary: ({ householdName, created }) => setupSummary: ({ householdName, created }) =>
`${created ? '✨' : ''} Добро пожаловать! Дом ${householdName} ${created ? 'успешно зарегистрирован' : 'уже активен'} и готов к работе.`, `🏡 ${created ? 'Новый дом!' : 'Дом активен!'} **${householdName}** готов.\n\n` +
`Базовая настройка выполнена. Теперь давайте распределим общение, привязав топики к конкретным ролям.`,
setupTopicsHeading: (configured, total) => setupTopicsHeading: (configured, total) =>
`Давайте настроим топики для вашего дома (${configured}/${total}):`, `Текущий прогресс настройки: ${configured}/${total}\n\n` +
`Нажмите кнопки ниже, чтобы создать топики автоматически, или перейдите в любой существующий топик и используйте /bind, чтобы привязать его вручную.`,
setupTopicBound: (role) => `${role}`, setupTopicBound: (role) => `${role}`,
setupTopicMissing: (role) => `${role}`, setupTopicMissing: (role) => `${role}`,
setupTopicCreateButton: (role) => `Настроить ${role}`, setupTopicCreateButton: (role) => `Создать ${role}`,
setupTopicBindButton: (role) => `Привязать ${role}`, setupTopicBindButton: (role) => `Привязать ${role}`,
useBindInTopic: 'Используйте /bind внутри топика, чтобы привязать его к роли.', useBindInTopic: 'Используйте /bind внутри топика, чтобы привязать его к роли.',
topicAlreadyBound: (role) => `Этот топик уже привязан к роли «${role}».`, topicAlreadyBound: (role) => `Этот топик уже привязан к роли «${role}».`,