Deploy Bot
Complete_Localization_Maximal_Logic
298f5d2
const { Scenes, Markup } = require('telegraf');
const User = require('../../models/User');
const usersScene = new Scenes.WizardScene(
'admin_users',
// Step 1: Main Menu for User Management
async (ctx) => {
// Inject i18n
if (!ctx.i18n) {
const User = require('../../models/User');
const locales = require('../../locales');
const user = await User.findOne({ id: ctx.from.id });
const lang = (user && user.language) ? user.language : 'uz';
ctx.i18n = locales[lang] || locales.uz;
}
const i18n = ctx.i18n;
const text = i18n.admin.users_title;
const buttons = [
[Markup.button.callback(i18n.admin.users_search, "search_id")],
[Markup.button.callback(i18n.admin.users_blocked, "list_blocked")],
[Markup.button.callback(i18n.admin.back, "back_dashboard")]
];
if (ctx.callbackQuery) {
await ctx.editMessageText(text, { parse_mode: 'Markdown', ...Markup.inlineKeyboard(buttons) });
} else {
await ctx.replyWithMarkdown(text, Markup.inlineKeyboard(buttons));
}
return ctx.wizard.next();
},
// Step 2: Handle Selection
async (ctx) => {
// Ensure i18n
if (!ctx.i18n) { const locales = require('../../locales'); ctx.i18n = locales.uz; }
const i18n = ctx.i18n;
if (!ctx.callbackQuery && !ctx.message) return;
const txt = ctx.message ? ctx.message.text : '';
if (txt === '/start' || txt === i18n.admin.btn_reject || txt === '❌ Bekor qilish') {
return ctx.scene.leave();
}
if (ctx.callbackQuery) {
const data = ctx.callbackQuery.data;
if (data === 'back_dashboard') {
await ctx.scene.leave();
const adminController = require('../../controllers/adminController');
return adminController.showDashboard(ctx);
}
if (data === 'search_id') {
await ctx.reply(i18n.admin.users_search_prompt, Markup.keyboard([[i18n.admin.btn_reject]]).resize());
ctx.wizard.state.action = 'search_id';
return ctx.wizard.next();
}
if (data === 'list_blocked') {
const blockedUsers = await User.find({ isBlocked: true });
if (blockedUsers.length === 0) {
await ctx.answerCbQuery(i18n.admin.users_blocked + ": 0");
return;
}
let msg = `${i18n.admin.users_blocked}:\n\n`;
blockedUsers.forEach(u => {
msg += `πŸ‘€ ${u.first_name} (ID: ${u.id})\n`;
});
await ctx.replyWithMarkdown(msg);
return;
}
}
},
// Step 3: Input Handler (Search ID) & Action Execution
async (ctx) => {
// Ensure i18n
if (!ctx.i18n) { const locales = require('../../locales'); ctx.i18n = locales.uz; }
const i18n = ctx.i18n;
const txt = ctx.message ? ctx.message.text : '';
if (txt === i18n.admin.btn_reject || txt === '❌ Bekor qilish') {
await ctx.reply(i18n.admin.back, Markup.removeKeyboard());
return ctx.scene.leave();
}
if (ctx.wizard.state.action === 'search_id') {
const userId = parseInt(txt);
if (isNaN(userId)) {
await ctx.reply(i18n.admin.error_num || "Error");
return;
}
const user = await User.findOne({ id: userId });
if (!user) {
await ctx.reply(i18n.admin.del_fail || "Not found");
return ctx.scene.leave();
}
ctx.wizard.state.selectedUser = user;
// Show User Details
const status = user.isBlocked ? i18n.admin.users_blocked : "βœ… Aktiv";
const info = `${i18n.admin.users_info}\n\n` +
`πŸ†” ID: \`${user.id}\`\n` +
`πŸ‘€ ${i18n.name}: ${user.first_name}\n` +
`πŸ“ž ${i18n.phone}: ${user.phone || "Yo'q"}\n` +
`πŸ“Š Status: ${status}\n` +
`πŸ“… Date: ${user.createdAt.toLocaleDateString()}`;
const buttons = [];
if (user.isBlocked) {
buttons.push([Markup.button.callback(i18n.admin.btn_unban, "unban_user")]);
} else {
buttons.push([Markup.button.callback(i18n.admin.btn_ban, "ban_user")]);
}
buttons.push([Markup.button.callback(i18n.admin.btn_dm, "dm_user")]);
buttons.push([Markup.button.callback(i18n.admin.btn_reject, "cancel")]);
await ctx.replyWithMarkdown(info, Markup.inlineKeyboard(buttons));
return ctx.wizard.next();
}
},
// Step 4: Handle User Actions (Ban/Unban/DM)
async (ctx) => {
// Ensure i18n
const i18n = ctx.i18n || require('../../locales').uz;
if (ctx.callbackQuery) {
const data = ctx.callbackQuery.data;
const user = ctx.wizard.state.selectedUser;
if (data === 'cancel') {
await ctx.deleteMessage();
await ctx.reply(i18n.admin.back, Markup.removeKeyboard());
return ctx.scene.leave();
}
if (data === 'ban_user') {
await User.updateOne({ id: user.id }, { isBlocked: true });
await ctx.answerCbQuery(i18n.admin.btn_ban);
await ctx.reply(`🚫 ${user.first_name} blocked.`);
return ctx.scene.leave();
}
if (data === 'unban_user') {
await User.updateOne({ id: user.id }, { isBlocked: false });
await ctx.answerCbQuery(i18n.admin.btn_unban);
await ctx.reply(`βœ… ${user.first_name} unblocked.`);
return ctx.scene.leave();
}
if (data === 'dm_user') {
await ctx.reply(i18n.admin.dm_prompt, Markup.keyboard([[i18n.admin.btn_reject]]).resize());
ctx.wizard.state.action = 'typing_dm';
return ctx.wizard.next(); // Go to Step 5 (DM Input)
}
}
},
// Step 5: Send DM
async (ctx) => {
// Ensure i18n
const i18n = ctx.i18n || require('../../locales').uz;
const txt = ctx.message ? ctx.message.text : '';
if (txt === i18n.admin.btn_reject || txt === '❌ Bekor qilish') {
await ctx.reply(i18n.admin.back, Markup.removeKeyboard());
return ctx.scene.leave();
}
const user = ctx.wizard.state.selectedUser;
try {
await ctx.telegram.sendMessage(user.id, `πŸ”” **Admin:**\n\n${txt}`, { parse_mode: 'Markdown' });
await ctx.reply(i18n.admin.dm_sent);
} catch (err) {
await ctx.reply(i18n.admin.error);
}
return ctx.scene.leave();
}
);
module.exports = usersScene;