feat(subscriptions): update subscription messages and enhance bot functionality

- Renamed `msg-subscribe-active-until` to `msg-subscription-active-until` for consistency in localization.
- Added `msg-subscription-active-days` to inform users about remaining subscription days.
- Refactored subscription handling in the bot to utilize updated subscription checks and improve user messaging.
- Enhanced conversation flow by integrating chat action for typing indication during subscription interactions.
This commit is contained in:
vchikalkin 2025-09-16 19:16:21 +03:00
parent a6d05bcf69
commit 336f3a11fd
5 changed files with 19 additions and 11 deletions

View File

@ -117,4 +117,5 @@ msg-subscribe-success =
msg-subscribe-error =
❌ Произошла ошибка при обработке платежа
msg-subscribe-active-until = 📅 Ваша подписка активна до { $date }
msg-subscription-active-until = 📅 Ваша подписка активна до { $date }
msg-subscription-active-days = 📅 Осталось еще { $days } дней вашей подписки

View File

@ -18,7 +18,9 @@ export async function subscription(conversation: Conversation<Context, Context>,
const subscriptionsService = new SubscriptionsService({ telegramId });
const hasUserTrial = await subscriptionsService.usedTrialSubscription();
const { remainingDays, usedTrialSubscription } = await subscriptionsService.getSubscription({
telegramId,
});
const { subscriptionPrices } = await subscriptionsService.getSubscriptionPrices({
filters: {
@ -26,7 +28,7 @@ export async function subscription(conversation: Conversation<Context, Context>,
eq: true,
},
period: {
ne: hasUserTrial ? GQL.Enum_Subscriptionprice_Period.Trial : undefined,
ne: usedTrialSubscription ? GQL.Enum_Subscriptionprice_Period.Trial : undefined,
},
},
});
@ -40,7 +42,11 @@ export async function subscription(conversation: Conversation<Context, Context>,
const messageWithPrices = await ctx.reply(
combine(
await conversation.external(({ t }) =>
combine(t('msg-subscribe'), fmt`${i}${t('msg-cancel-operation')}${i}`.text),
combine(
t('msg-subscribe'),
remainingDays ? t('msg-subscription-active-days', { days: remainingDays }) : '',
fmt`${i}${t('msg-cancel-operation')}${i}`.text,
),
),
),
{ reply_markup: keyboard },
@ -49,7 +55,7 @@ export async function subscription(conversation: Conversation<Context, Context>,
// ждём выбора
const selectPlanWaitCtx = await conversation.wait();
// удаляем сообщение с выбором (не обязательно, но красивее)
// удаляем сообщение с выбором
try {
await ctx.api.deleteMessage(telegramId, messageWithPrices.message_id);
} catch {

View File

@ -32,7 +32,7 @@ feature.on(':successful_payment', logHandle('successful-payment'), async (ctx) =
const { formattedDate } = await subscriptionsService.createOrUpdateSubscription(payload);
await ctx.reply(ctx.t('msg-subscribe-success'));
await ctx.reply(ctx.t('msg-subscribe-active-until', { date: formattedDate }));
await ctx.reply(ctx.t('msg-subscription-active-until', { date: formattedDate }));
} catch (error) {
await ctx.reply(ctx.t('msg-subscribe-error'));
logger.error(

View File

@ -9,7 +9,7 @@ import { setCommands } from './settings/commands';
import { setInfo } from './settings/info';
import { env } from '@/config/env';
import { getRedisInstance } from '@/utils/redis';
import { autoChatAction } from '@grammyjs/auto-chat-action';
import { autoChatAction, chatAction } from '@grammyjs/auto-chat-action';
import { createConversation, conversations as grammyConversations } from '@grammyjs/conversations';
import { hydrate } from '@grammyjs/hydrate';
import { limit } from '@grammyjs/ratelimiter';
@ -38,13 +38,15 @@ export function createBot({ token }: Parameters_) {
}),
);
bot.use(autoChatAction(bot.api));
bot.use(grammyConversations()).command('cancel', async (ctx) => {
await ctx.conversation.exitAll();
await ctx.reply(ctx.t('msg-cancel'));
});
for (const conversation of Object.values(conversations)) {
bot.use(createConversation(conversation));
bot.use(chatAction('typing'), createConversation(conversation));
}
setInfo(bot);
@ -53,7 +55,6 @@ export function createBot({ token }: Parameters_) {
const protectedBot = bot.errorBoundary(errorHandler);
protectedBot.use(middlewares.updateLogger());
protectedBot.use(autoChatAction(bot.api));
protectedBot.use(hydrate());
for (const feature of Object.values(features)) {

View File

@ -1,3 +1,3 @@
export function combine(...messages: string[]) {
return messages.join('\n\n');
export function combine(...messages: Array<string | undefined>) {
return messages.filter(Boolean).join('\n\n');
}