CREATORS/OnecreatorsbotPublic · Bot Template
AIThe bot manages a membership club called CREATORS. Users can apply for membership, view their status, and receive payment instructions. Administrators can approve or reject applications, set subscription prices, configure payment details, and review pending payments. The bot stores data in a database, sends notifications to users and admins, and handles payment receipts via photo or document uploads.
Commercemembershipsubscriptionpaymentsadmincreatortelegram
22 commands1 envUpdated 20d agoCreated Oct 6, 2026
commands/_handle_callback_query.js
javascript · 1453 lines
1/**#command2name: /handle_callback_query3answer: 4keyboard: 5parse_mode: markdown6aliases: 7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12const data = update.callback_query.data || "";13const callbackId = update.callback_query.id;14const callbackMessage = update.callback_query.message;15const adminId = String(process.env.ADMIN_ID);16 17if (data === "choose_weekly" || data === "choose_monthly") {18const selectedPlan = data === "choose_weekly" ? "weekly" : "monthly";19const planName = data === "choose_weekly" ? "اشتراک هفتگی" : "اشتراک ماهانه";20const duration = data === "choose_weekly" ? 7 : 30;21 22const rawPrice = data === "choose_weekly"23? "500000"24: await db.bot.get("subscription_price", "2000000");25 26const price = Number(rawPrice);27 28if (!Number.isFinite(price) || price <= 0) {29await Api.answerCallbackQuery({30callback_query_id: callbackId,31text: "قیمت این طرح معتبر نیست."32});33return;34}35 36const card = await db.bot.get("payment_card", "");37const owner = await db.bot.get("payment_owner", "");38const bank = await db.bot.get("payment_bank", "");39 40if (!card || !owner || !bank) {41await Api.answerCallbackQuery({42callback_query_id: callbackId,43text: "اطلاعات پرداخت هنوز کامل تنظیم نشده است."44});45return;46}47 48await db.user.set("selected_plan", selectedPlan, {49user_id: Number(user.id)50});51 52await db.user.set("selected_plan_price", String(price), {53user_id: Number(user.id)54});55 56await db.user.set("selected_plan_duration", String(duration), {57user_id: Number(user.id)58});59 60 61await db.user.set(62 "awaiting_payment_receipt",63 "yes",64 { user_id: Number(user.id) }65);66 67await Api.answerCallbackQuery({68callback_query_id: callbackId,69text: "طرح انتخاب شد."70});71 72await Api.sendMessage({73chat_id: callbackMessage.chat.id,74text:75"✦━━━━━━━━━━━━━━━━━━✦\n" +76" C R E A T O R S\n" +77"✦━━━━━━━━━━━━━━━━━━✦\n\n" +78"👑 طرح انتخابی: " + planName + "\n" +79"🗓 مدت: " + duration + " روز\n" +80"💰 مبلغ: " + price.toLocaleString("fa-IR") + " تومان\n\n" +81 82 "🏦 بانک: " + bank + "\n" +83 84 85 86 "👤 صاحب کارت: " + owner + "\n" +87 "💳 شماره کارت:\n" + card + "\n\n" 88 +89 90 "پس از واریز لطفا رسيد پرداخت را ارسال كنيد .\n" +91 92 "اشتراک پس از بررسی فعال خواهد شد.",93reply_markup: {94inline_keyboard: [95[96{97text: "📤 ارسال رسید پرداخت",98callback_data: "payment_done"99 100}101]102]103}104});105 106return;107}108 109 110if (data === "payment_done") {111 const userId = Number(user.id);112 113 const selectedPlan = await db.user.get(114 "selected_plan",115 "",116 { user_id: userId }117 );118 119 if (!selectedPlan) {120 await Api.answerCallbackQuery({121 callback_query_id: callbackId,122 text: "لطفاً ابتدا یکی از طرحهای اشتراک را انتخاب کن."123 });124 return;125 }126 127 await db.user.set(128 "awaiting_payment_receipt",129 "yes",130 { user_id: userId }131 );132 133 await Api.answerCallbackQuery({134 callback_query_id: callbackId,135 text: "منتظر ارسال رسید هستیم."136 });137 138 await Api.sendMessage({139 chat_id: callbackMessage.chat.id,140 text:141 "✦━━━━━━━━━━━━━━━━━━✦\n" +142 " C R E A T O R S\n" +143 "✦━━━━━━━━━━━━━━━━━━✦\n\n" +144 "📤 لطفاً رسید پرداخت خود را ارسال کن.\n\n" +145 "میتوانی یکی از این موارد را بفرستی:\n" +146 "📷 عکس رسید\n" +147 "📄 فایل رسید، مانند PDF\n" +148 "📝 متن رسید و اطلاعات تراکنش\n\n" +149 "پس از دریافت رسید، مدیر پرداخت را بررسی میکند.\n" +150 "اشتراک پس از تأیید مدیر فعال خواهد شد."151 });152 153 return;154}155 156// بررسی دسترسی مدیر؛ فقط یکبار157if (String(user.id) !== adminId) {158 await Api.answerCallbackQuery({159 callback_query_id: callbackId,160 text: "⛔ دسترسی مجاز نیست."161 });162 return;163}164 165// استخراج شناسه کاربر از callback166function getTargetId(prefix) {167 const rawId = data.substring(prefix.length);168 169 if (!/^\d+$/.test(rawId)) return null;170 171 const id = Number(rawId);172 return Number.isSafeInteger(id) && id > 0 ? id : null;173}174 175// بررسی نتیجه ذخیرهسازی176function saveSucceeded(result) {177 return Boolean(result && result.ok === true);178}179 180 181/* =========================================182 صفحهبندی فهرست اعضا183 ========================================= */184 185if (data.startsWith("members_page_")) {186 const rawPage = data.substring("members_page_".length);187 const requestedPage = Number(rawPage);188 189 if (!/^\d+$/.test(rawPage) ||190 !Number.isSafeInteger(requestedPage) ||191 requestedPage < 1) {192 await Api.answerCallbackQuery({193 callback_query_id: callbackId,194 text: "شماره صفحه معتبر نیست."195 });196 return;197 }198 199 const users = await Bot.getUsers();200 const pageSize = 10;201 const totalPages = Math.max(1, Math.ceil(users.length / pageSize));202 const page = Math.min(requestedPage, totalPages);203 const pageUsers = users.slice((page - 1) * pageSize, page * pageSize);204 const keyboard = [];205 206 for (const rawId of pageUsers) {207 const targetId = Number(rawId);208 if (!Number.isSafeInteger(targetId) || targetId <= 0) continue;209 210 const name = await db.user.get(211 "profile_name", "", { user_id: targetId }212 );213 const username = await db.user.get(214 "profile_username", "", { user_id: targetId }215 );216 217 const labelName = String(name || username || "بدون نام")218 .replace(/[\r\n]+/g, " ")219 .slice(0, 30);220 221 keyboard.push([{222 text: "👤 " + labelName + " | " + targetId,223 callback_data: "member_profile_" + targetId224 }]);225 }226 227 const nav = [];228 if (page > 1) {229 nav.push({230 text: "⬅️ صفحه قبل",231 callback_data: "members_page_" + (page - 1)232 });233 }234 if (page < totalPages) {235 nav.push({236 text: "صفحه بعد ➡️",237 callback_data: "members_page_" + (page + 1)238 });239 }240 if (nav.length) keyboard.push(nav);241 242 await Api.answerCallbackQuery({243 callback_query_id: callbackId,244 text: "صفحه " + page245 });246 247 await Api.sendMessage({248 chat_id: callbackMessage.chat.id,249 text:250 "👑 پنل مدیریت اعضای CREATORS\n" +251 "━━━━━━━━━━━━━━━━━━\n\n" +252 "👥 تعداد کاربران: " + users.length +253 "\n📄 صفحه " + page + " از " + totalPages +254 "\n\nبرای مشاهده پرونده، روی عضو موردنظر بزن.",255 reply_markup: { inline_keyboard: keyboard }256 });257 258 return;259}260 261 262/* =========================================263 پرونده کامل عضو264 ========================================= */265 266if (data.startsWith("member_profile_")) {267 const rawId = data.substring("member_profile_".length);268 269 if (!/^\d+$/.test(rawId)) {270 await Api.answerCallbackQuery({271 callback_query_id: callbackId,272 text: "شناسه عضو معتبر نیست."273 });274 return;275 }276 277 const targetId = Number(rawId);278 279 if (!Number.isSafeInteger(targetId) || targetId <= 0) {280 await Api.answerCallbackQuery({281 callback_query_id: callbackId,282 text: "شناسه عضو معتبر نیست."283 });284 return;285 }286 287 const [288 name,289 username,290 creatorId,291 membershipStatus,292 paymentStatus,293 plan,294 price,295 duration,296 startDate,297 endDate,298 access,299 pendingReceipt300 ] = await Promise.all([301 db.user.get("profile_name", "", { user_id: targetId }),302 db.user.get("profile_username", "", { user_id: targetId }),303 db.user.get("creator_id", "ثبت نشده", { user_id: targetId }),304 db.user.get("membership_status", "ثبت نشده", { user_id: targetId }),305 db.user.get("payment_review_status", "ثبت نشده", { user_id: targetId }),306 db.user.get("selected_plan", "ثبت نشده", { user_id: targetId }),307 db.user.get("selected_plan_price", "", { user_id: targetId }),308 db.user.get("selected_plan_duration", "", { user_id: targetId }),309 db.user.get("subscription_start", "", { user_id: targetId }),310 db.user.get("subscription_end", "", { user_id: targetId }),311 db.user.get("access", {}, { user_id: targetId }),312 db.user.get("pending_payment_receipt", null, { user_id: targetId })313 ]);314 315 const archiveData = await db.bot.get("creators_confirmed_payments", []);316 const archive = Array.isArray(archiveData) ? archiveData : [];317 const memberPayments = archive.filter(318 item => Number(item.user_id) === targetId319 );320 321 function displayDate(value) {322 if (!value) return "ثبت نشده";323 const date = new Date(value);324 if (Number.isNaN(date.getTime())) return String(value);325 return date.toLocaleDateString("fa-IR");326 }327 328 const accessData = access || {};329 const enabledAccess = Object.keys(accessData)330 .filter(key => accessData[key] === true);331 332 let text =333 "👑 پرونده عضو CREATORS\n" +334 "━━━━━━━━━━━━━━━━━━\n\n" +335 "👤 نام: " + String(name || "ثبت نشده") + "\n" +336 "🔹 نام کاربری: " +337 (username ? "@" + String(username).replace(/^@/, "") : "ثبت نشده") + "\n" +338 "🆔 شناسه تلگرام: " + targetId + "\n" +339 "✨ Creator ID: " + String(creatorId || "ثبت نشده") + "\n\n" +340 "📌 وضعیت عضویت: " + String(membershipStatus) + "\n" +341 "💳 وضعیت پرداخت: " + String(paymentStatus) + "\n" +342 "📦 طرح انتخابی: " + String(plan) + "\n" +343 "💰 مبلغ طرح: " +344 (price ? Number(price).toLocaleString("fa-IR") + " تومان" : "ثبت نشده") + "\n" +345 "🗓 مدت طرح: " + (duration ? String(duration) + " روز" : "ثبت نشده") + "\n" +346 "📅 شروع اشتراک: " + displayDate(startDate) + "\n" +347 "📅 پایان اشتراک: " + displayDate(endDate) + "\n\n" +348 "🔓 تعداد دسترسیهای فعال: " + enabledAccess.length + "\n" +349 (enabledAccess.length ? enabledAccess.join("، ") : "دسترسی فعالی ثبت نشده") + "\n\n" +350 "🧾 رسید در انتظار: " +351 (pendingReceipt && pendingReceipt.receipt_id352 ? pendingReceipt.receipt_id353 : "رسیدی ثبت نشده") + "\n" +354 "🗃 تعداد پرداختهای آرشیوشده: " + memberPayments.length;355 356 for (const payment of memberPayments.slice(-5).reverse()) {357 text +=358 "\n\n──────────────\n" +359 "🧾 رسید: " + String(payment.receipt_id || "نامشخص") + "\n" +360 "💰 مبلغ: " +361 (Number(payment.price) > 0362 ? Number(payment.price).toLocaleString("fa-IR") + " تومان"363 : "ثبت نشده") + "\n" +364 "📦 طرح: " + String(payment.plan || "ثبت نشده") + "\n" +365 "📍 وضعیت: " + String(payment.status || "ثبت نشده") + "\n" +366 "📅 زمان تأیید: " + displayDate(payment.approved_at);367 }368 369 await Api.answerCallbackQuery({370 callback_query_id: callbackId,371 text: "پرونده عضو باز شد."372 });373 374 await Api.sendMessage({375 chat_id: callbackMessage.chat.id,376 text: text,377 reply_markup: {378 inline_keyboard: [379 [380 {381 text: "🔐 مدیریت دسترسیهای این عضو",382 callback_data: "open_manage_" + targetId383 }384 ],385 [386 {387 text: "⬅️ بازگشت به صفحه اول اعضا",388 callback_data: "members_page_1"389 }390 ]391 ]392 }393 });394 395 return;396}397 398 399/* =========================================400 بازکردن پنل مدیریت از پرونده عضو401 ========================================= */402 403if (data.startsWith("open_manage_")) {404 const targetId = getTargetId("open_manage_");405 406 if (!targetId) {407 await Api.answerCallbackQuery({408 callback_query_id: callbackId,409 text: "شناسه عضو معتبر نیست."410 });411 return;412 }413 414 await Api.answerCallbackQuery({415 callback_query_id: callbackId,416 text: "پنل مدیریت عضو باز میشود."417 });418 419 await updateManagePanel(targetId);420 return;421}422 423/* =========================================424 فهرست درخواستهای عضویت و پرداخت425 ========================================= */426 427if (428 data === "requests_membership" ||429 data === "requests_payments"430) {431 const isMembership = data === "requests_membership";432 const users = await Bot.getUsers();433 434 const groups = isMembership435 ? [436 { status: "pending", title: "🕒 در انتظار بررسی" },437 { status: "approved", title: "✅ تأییدشدهها" },438 { status: "rejected", title: "❌ ردشدهها" }439 ]440 : [441 { status: "pending", title: "🕒 در انتظار بررسی" },442 { status: "approved", title: "✅ تأییدشدهها" },443 { status: "rejected", title: "❌ ردشدهها" }444 ];445 446 let text = isMembership447 ? "👥 فهرست درخواستهای عضویت\n"448 : "💳 فهرست رسیدهای پرداخت\n";449 450 text += "━━━━━━━━━━━━━━━━━━\n\n";451 452 for (const group of groups) {453 const matches = [];454 455 for (const id of users) {456 const targetId = Number(id);457 458 const status = await db.user.get(459 isMembership460 ? "membership_status"461 : "payment_review_status",462 "unknown",463 { user_id: targetId }464 );465 466 let belongs = false;467 468 if (isMembership) {469 if (group.status === "approved") {470 belongs = ["approved", "active", "paid"].includes(status);471 } else {472 belongs = status === group.status;473 }474 } else {475 belongs = status === group.status;476 }477 478 if (belongs) matches.push(targetId);479 }480 481 text += group.title + "\n";482 483 if (matches.length === 0) {484 text += "موردی ثبت نشده است.\n\n";485 continue;486 }487 488 text += "تعداد: " + matches.length + "\n";489 490 // برای جلوگیری از طولانی شدن پیام، حداکثر ۲۰ شناسه491 // در هر بخش نمایش داده میشود.492 for (const targetId of matches.slice(0, 20)) {493 text += "• شناسه تلگرام: " + targetId + "\n";494 }495 496 if (matches.length > 20) {497 text += "۲۰ مورد اول نمایش داده شدهاند؛ تعداد کل: " +498 matches.length + "\n";499 }500 501 text += "\n";502 }503 504 await Api.answerCallbackQuery({505 callback_query_id: callbackId,506 text: "فهرست بهروزرسانی شد."507 });508 509 await Api.sendMessage({510 chat_id: callbackMessage.chat.id,511 text: text,512 reply_markup: {513 inline_keyboard: [514 [515 {516 text: "👥 درخواستهای عضویت",517 callback_data: "requests_membership"518 }519 ],520 [521 {522 text: "💳 رسیدهای پرداخت",523 callback_data: "requests_payments"524 }525 ],526 [527 {528 text: "🔄 بازگشت به پنل",529 callback_data: "requests_refresh"530 }531 ]532 ]533 }534 });535 536 return;537}538 539if (data === "requests_refresh") {540 await Api.answerCallbackQuery({541 callback_query_id: callbackId,542 text: "برای دیدن آمار جدید، دستور /requests را بفرست."543 });544 545 await Api.sendMessage({546 chat_id: callbackMessage.chat.id,547 text: "برای مشاهده آمار بهروز پنل مدیریت، دستور زیر را ارسال کن:\n/requests"548 });549 550 return;551}552 553/* =========================================554 تأیید و رد پرداخت اشتراک555 ========================================= */556 557if (558 data.startsWith("payapprove_") ||559 data.startsWith("payreject_")560) {561 const isApproval = data.startsWith("payapprove_");562 const prefix = isApproval ? "payapprove_" : "payreject_";563 const targetUserId = getTargetId(prefix);564 565 if (!targetUserId) {566 await Api.answerCallbackQuery({567 callback_query_id: callbackId,568 text: "شناسه کاربر نامعتبر است."569 });570 return;571 }572 573 const reviewStatus = await db.user.get(574 "payment_review_status",575 "",576 { user_id: targetUserId }577 );578 579 if (reviewStatus !== "pending") {580 await Api.answerCallbackQuery({581 callback_query_id: callbackId,582 text: "این رسید قبلاً بررسی شده یا در انتظار بررسی نیست."583 });584 return;585 }586 587 if (!isApproval) {588 const rejectResult = await db.user.set(589 "payment_review_status",590 "rejected",591 { user_id: targetUserId }592 );593 594 if (!saveSucceeded(rejectResult)) {595 await Api.answerCallbackQuery({596 callback_query_id: callbackId,597 text: "ذخیره نتیجه رد پرداخت ناموفق بود."598 });599 return;600 }601 602 await Api.answerCallbackQuery({603 callback_query_id: callbackId,604 text: "پرداخت رد شد."605 });606 607 try {608 await Api.editMessageCaption({609 chat_id: callbackMessage.chat.id,610 message_id: callbackMessage.message_id,611 caption: "❌ رسید پرداخت رد شد.\nشناسه کاربر: " + targetUserId612 });613 } catch (error) {614 try {615 await Api.editMessageText({616 chat_id: callbackMessage.chat.id,617 message_id: callbackMessage.message_id,618 text: "❌ رسید پرداخت رد شد.\nشناسه کاربر: " + targetUserId619 });620 } catch (ignored) {}621 }622 623 await Api.sendMessage({624 chat_id: targetUserId,625 text:626 "❌ رسید پرداخت شما تأیید نشد.\n\n" +627 "لطفاً اطلاعات پرداخت را بررسی کن و برای ارسال مجدد، " +628 "دکمه «ارسال رسید پرداخت» را در ربات بزن."629 });630 631 return;632 }633 634 const plan = await db.user.get(635 "selected_plan",636 "",637 { user_id: targetUserId }638 );639 640 const duration = Number(await db.user.get(641 "selected_plan_duration",642 "0",643 { user_id: targetUserId }644 ));645 646 const price = Number(await db.user.get(647 "selected_plan_price",648 "0",649 { user_id: targetUserId }650 ));651 652 if (653 !["weekly", "monthly"].includes(plan) ||654 !Number.isInteger(duration) ||655 duration <= 0 ||656 !Number.isFinite(price) ||657 price <= 0658 ) {659 await Api.answerCallbackQuery({660 callback_query_id: callbackId,661 text: "اطلاعات طرح معتبر نیست؛ پرداخت تأیید نشد."662 });663 return;664 }665 666 const start = new Date();667 const end = new Date(668 start.getTime() + duration * 24 * 60 * 60 * 1000669 );670 671 const oldAccess = await db.user.get(672 "access",673 {},674 { user_id: targetUserId }675 );676 677 const access = Object.assign({}, oldAccess || {});678 679 access.membership = true;680 access.profile = true;681 access.challenges = true;682 access.vc = true;683 access.streak = true;684 access.achievements = true;685 access.rewards = true;686 access.private_content = true;687 access.private_group = true;688 689 // ابتدا نتیجه بررسی را ثبت میکنیم تا کلیک مجدد عادی رد شود.690 const markResult = await db.user.set(691 "payment_review_status",692 "approved",693 { user_id: targetUserId }694 );695 696 if (!saveSucceeded(markResult)) {697 await Api.answerCallbackQuery({698 callback_query_id: callbackId,699 text: "ثبت نتیجه پرداخت ناموفق بود."700 });701 return;702 }703 704 const accessResult = await db.user.set(705 "access",706 access,707 { user_id: targetUserId }708 );709 710 const statusResult = await db.user.set(711 "membership_status",712 "active",713 { user_id: targetUserId }714 );715 716 const startResult = await db.user.set(717 "subscription_start",718 start.toISOString(),719 { user_id: targetUserId }720 );721 722 const endResult = await db.user.set(723 "subscription_end",724 end.toISOString(),725 { user_id: targetUserId }726 );727 728 if (729 !saveSucceeded(accessResult) ||730 !saveSucceeded(statusResult) ||731 !saveSucceeded(startResult) ||732 !saveSucceeded(endResult)733 ) {734 await Api.answerCallbackQuery({735 callback_query_id: callbackId,736 text: "خطا در ذخیره اشتراک؛ اطلاعات را بررسی کن."737 });738 739 await Api.sendMessage({740 chat_id: Number(process.env.ADMIN_ID),741 text:742 "⚠️ خطا هنگام فعالسازی اشتراک\n" +743 "شناسه کاربر: " + targetUserId +744 "\nوضعیت پرداخت approved ثبت شده است؛ پیش از اقدام مجدد، " +745 "وضعیت دسترسی و تاریخها را بررسی کن."746 });747 748 return;749 }750 751 752const pendingReceipt = await db.user.get(753 "pending_payment_receipt",754 null,755 { user_id: targetUserId }756);757 758if (!pendingReceipt || !pendingReceipt.receipt_id) {759 await Api.sendMessage({760 chat_id: Number(process.env.ADMIN_ID),761 text:762 "⚠️ اشتراک فعال شده، اما اطلاعات رسید برای آرشیو پیدا نشد.\n" +763 "شناسه کاربر: " + targetUserId +764 "\nلطفاً پرونده این پرداخت را بررسی کن."765 });766} else {767 const archiveKey = "creators_confirmed_payments";768 const archive = await db.bot.get(archiveKey, []);769 770 const payments = Array.isArray(archive) ? archive : [];771 772 const alreadySaved = payments.some(773 item => item.receipt_id === pendingReceipt.receipt_id774 );775 776 if (!alreadySaved) {777 payments.push({778 receipt_id: pendingReceipt.receipt_id,779 user_id: targetUserId,780 name: String(781 await db.user.get("profile_name", "", {782 user_id: targetUserId783 })784 ),785 username: String(786 await db.user.get("profile_username", "", {787 user_id: targetUserId788 })789 ),790 plan: plan,791 price: price,792 duration: duration,793 receipt_type: pendingReceipt.type,794 receipt_file_id: pendingReceipt.file_id || "",795 receipt_file_name: pendingReceipt.file_name || "",796 receipt_text: pendingReceipt.text || "",797 receipt_submitted_at: pendingReceipt.submitted_at || "",798 approved_at: new Date().toISOString(),799 subscription_start: start.toISOString(),800 subscription_end: end.toISOString(),801 status: "approved"802 });803 804 await db.bot.set(archiveKey, payments);805 806 const verifyArchive = await db.bot.get(archiveKey, []);807 const verified = Array.isArray(verifyArchive) &&808 verifyArchive.some(809 item => item.receipt_id === pendingReceipt.receipt_id810 );811 812 if (!verified) {813 await Api.sendMessage({814 chat_id: Number(process.env.ADMIN_ID),815 text:816 "⚠️ اشتراک فعال شده، اما ثبت نهایی پرداخت تأیید نشد.\n" +817 "شناسه کاربر: " + targetUserId +818 "\nشناسه رسید: " + pendingReceipt.receipt_id819 });820 }821 }822}823 824 await Api.answerCallbackQuery({825 callback_query_id: callbackId,826 text: "پرداخت تأیید و اشتراک فعال شد."827 });828 829 try {830 await Api.editMessageCaption({831 chat_id: callbackMessage.chat.id,832 message_id: callbackMessage.message_id,833 caption:834 "✅ پرداخت تأیید شد.\n\n" +835 "شناسه کاربر: " + targetUserId +836 "\nطرح: " + (plan === "weekly" ? "هفتگی" : "ماهانه") +837 "\nمبلغ: " + price.toLocaleString("fa-IR") + " تومان" +838 "\nپایان اشتراک: " + end.toLocaleDateString("fa-IR")+ "تمديد همين اشتراك عضويت از طريق لينك زير" });839 } catch (error) {840 try {841 await Api.editMessageText({842 chat_id: callbackMessage.chat.id,843 message_id: callbackMessage.message_id,844 text:845 "✅ پرداخت تأیید شد.\n" +846 "شناسه کاربر: " + targetUserId +847 "\nپایان اشتراک: " + end.toLocaleDateString("fa-IR")848 });849 } catch (ignored) {}850 }851 852 try {853 await Api.sendMessage({854 chat_id: targetUserId,855 text:856 "👑 CREATORS\n\n" +857 "✅ پرداخت شما تأیید شد و اشتراک فعال گردید.\n\n" +858 "طرح: " + (plan === "weekly" ? "هفتگی" : "ماهانه") +859 "\nمدت: " + duration + " روز" +860 "\nمبلغ پرداختی: " + price.toLocaleString("fa-IR") + " تومان" +861 "\nتاریخ شروع: " + start.toLocaleDateString("fa-IR") +862 "\nتاریخ پایان: " + end.toLocaleDateString("fa-IR") +863 "\n\nقفل دسترسي ها و امكانات اختصاصي باز شدند 🔓✔️"864 });865 } catch (error) {866 await Api.sendMessage({867 chat_id: Number(process.env.ADMIN_ID),868 text:869 "⚠️ اشتراک فعال شد، اما ارسال پیام به کاربر ناموفق بود.\n" +870 "شناسه کاربر: " + targetUserId871 });872 }873 874 return;875}876 877// ==================================================878// تأیید عضویت879// ==================================================880 881if (data.startsWith("approve_")) {882 const targetUserId = getTargetId("approve_");883 884 if (!targetUserId) {885 await Api.answerCallbackQuery({886 callback_query_id: callbackId,887 text: "شناسه کاربر نامعتبر است."888 });889 return;890 }891 892 const currentStatus = await db.user.get(893 "membership_status",894 "unknown",895 { user_id: targetUserId }896 );897 898 if (["approved", "active", "paid"].includes(currentStatus)) {899 await Api.answerCallbackQuery({900 callback_query_id: callbackId,901 text: "این عضو قبلاً تأیید شده است."902 });903 return;904 }905 906 // دریافت یا ساخت Creator ID907 let creatorId = await db.user.get(908 "creator_id",909 null,910 { user_id: targetUserId }911 );912 913 if (!creatorId) {914 let attempts = 0;915 916 while (!creatorId && attempts < 20) {917 attempts++;918 919 const code = modules.randomstring.generate({920 length: 6,921 charset: "alphanumeric",922 readable: true923 }).toUpperCase();924 925 const candidate = "CREATOR-" + code;926 const ids = await Bot.getUsers();927 let duplicate = false;928 929 for (const id of ids) {930 const existingId = await db.user.get(931 "creator_id",932 null,933 { user_id: Number(id) }934 );935 936 if (existingId === candidate) {937 duplicate = true;938 break;939 }940 }941 942 if (!duplicate) creatorId = candidate;943 }944 945 if (!creatorId) {946 await Api.answerCallbackQuery({947 callback_query_id: callbackId,948 text: "خطا در ساخت Creator ID."949 });950 return;951 }952 953 const saveCreatorId = await db.user.set(954 "creator_id",955 creatorId,956 { user_id: targetUserId }957 );958 959 if (!saveSucceeded(saveCreatorId)) {960 await Api.answerCallbackQuery({961 callback_query_id: callbackId,962 text: "خطا در ذخیره Creator ID."963 });964 return;965 }966 }967 968 // دریافت یا ساخت رمز عبور969 let password = await db.user.get(970 "creator_password",971 null,972 { user_id: targetUserId }973 );974 975 if (!password) {976 password = modules.randomstring.generate({977 length: 12,978 charset: "alphanumeric",979 readable: true980 }).toUpperCase();981 982 const savePassword = await db.user.set(983 "creator_password",984 password,985 { user_id: targetUserId }986 );987 988 if (!saveSucceeded(savePassword)) {989 await Api.answerCallbackQuery({990 callback_query_id: callbackId,991 text: "خطا در ذخیره رمز عبور."992 });993 return;994 }995 }996 997 // ثبت تأیید؛ فعالسازی امکانات همچنان با مدیر است998 const statusResult = await db.user.set(999 "membership_status",1000 "approved",1001 { user_id: targetUserId }1002 );1003 1004 if (!saveSucceeded(statusResult)) {1005 await Api.answerCallbackQuery({1006 callback_query_id: callbackId,1007 text: "خطا در ذخیره وضعیت عضویت."1008 });1009 return;1010 }1011 1012 await Api.answerCallbackQuery({1013 callback_query_id: callbackId,1014 text: "عضویت تأیید شد."1015 });1016 1017 // بهروزرسانی پیام درخواست مدیر1018 try {1019 await Api.editMessageText({1020 chat_id: callbackMessage.chat.id,1021 message_id: callbackMessage.message_id,1022 text:1023 "✦ درخواست عضویت تأیید شد.\n\n" +1024 "Creator ID: " + creatorId + "\n" +1025 "وضعیت: approved"1026 });1027 } catch (error) {1028 // خطای ویرایش پیام نباید مانع اطلاعرسانی به عضو شود1029 }1030 1031 // اطلاعرسانی به عضو1032 try {1033 await Api.sendMessage({1034 chat_id: targetUserId,1035 text:1036 "✦ CREATORS ✦\n" +1037 "━━━━━━━━━━━━━━━━━━\n\n" +1038 "درخواست عضویت شما تأیید شد. ✦\n\n" +1039 "به جمع CREATORS خوش آمدید.\n\n" +1040 "شناسه عضویت شما:\n" +1041 creatorId + "\n\n" +1042 "رمز عبور شما:\n" +1043 password + "\n\n" +1044 "لطفاً این اطلاعات را نزد خود محفوظ نگه دارید.\n\n" +1045 "✦ مرحله بعد:\n" +1046 "برای فعالسازی امکانات عضویت، اشتراک خود را پرداخت کنید.\n\n" +1047 "پس از پرداخت و فعالسازی توسط مدیر، دسترسیهای شما برقرار خواهد شد."1048 });1049 } catch (error) {1050 await Api.sendMessage({1051 chat_id: Number(process.env.ADMIN_ID),1052 text:1053 "⚠️ عضویت تأیید شد، اما ارسال پیام به عضو ناموفق بود.\n\n" +1054 "شناسه تلگرام: " + targetUserId1055 });1056 }1057 1058 return;1059}1060 1061 1062// ==================================================1063// رد درخواست عضویت1064// ==================================================1065 1066if (data.startsWith("reject_")) {1067 const targetUserId = getTargetId("reject_");1068 1069 if (!targetUserId) {1070 await Api.answerCallbackQuery({1071 callback_query_id: callbackId,1072 text: "شناسه کاربر نامعتبر است."1073 });1074 return;1075 }1076 1077 const result = await db.user.set(1078 "membership_status",1079 "rejected",1080 { user_id: targetUserId }1081 );1082 1083 if (!saveSucceeded(result)) {1084 await Api.answerCallbackQuery({1085 callback_query_id: callbackId,1086 text: "خطا در ذخیره وضعیت."1087 });1088 return;1089 }1090 1091 await Api.answerCallbackQuery({1092 callback_query_id: callbackId,1093 text: "درخواست رد شد."1094 });1095 1096 try {1097 await Api.editMessageText({1098 chat_id: callbackMessage.chat.id,1099 message_id: callbackMessage.message_id,1100 text:1101 "✦ درخواست عضویت رد شد.\n\n" +1102 "شناسه کاربر: " + targetUserId1103 });1104 } catch (error) {}1105 1106 try {1107 await Api.sendMessage({1108 chat_id: targetUserId,1109 text:1110 "✦ درخواست عضویت شما پس از بررسی تأیید نشد.\n\n" +1111 "در صورت تمایل میتوانید در آینده دوباره درخواست دهید."1112 });1113 } catch (error) {1114 await Api.sendMessage({1115 chat_id: Number(process.env.ADMIN_ID),1116 text:1117 "⚠️ درخواست رد شد، اما ارسال پیام به کاربر ناموفق بود.\n" +1118 "شناسه کاربر: " + targetUserId1119 });1120 }1121 1122 return;1123}1124 1125 1126// ==================================================1127// فعالسازی همه دسترسیها1128// ==================================================1129 1130if (data.startsWith("all_on_")) {1131 const targetId = getTargetId("all_on_");1132 1133 if (!targetId) {1134 await Api.answerCallbackQuery({1135 callback_query_id: callbackId,1136 text: "شناسه کاربر نامعتبر است."1137 });1138 return;1139 }1140 1141 const access = {1142 membership: true,1143 profile: true,1144 challenges: true,1145 vc: true,1146 streak: true,1147 achievements: true,1148 rewards: true,1149 private_content: true,1150 private_group: true1151 };1152 1153 const accessResult = await db.user.set(1154 "access",1155 access,1156 { user_id: targetId }1157 );1158 1159 if (!saveSucceeded(accessResult)) {1160 await Api.answerCallbackQuery({1161 callback_query_id: callbackId,1162 text: "خطا در فعال کردن دسترسیها."1163 });1164 return;1165 }1166 1167 const statusResult = await db.user.set(1168 "membership_status",1169 "active",1170 { user_id: targetId }1171 );1172 1173 if (!saveSucceeded(statusResult)) {1174 await Api.answerCallbackQuery({1175 callback_query_id: callbackId,1176 text: "دسترسیها ذخیره شدند، اما تغییر وضعیت عضویت ناموفق بود."1177 });1178 return;1179 }1180 1181 await Api.answerCallbackQuery({1182 callback_query_id: callbackId,1183 text: "عضویت و همه دسترسیها فعال شدند."1184 });1185 1186 try {1187 await Api.sendMessage({1188 chat_id: targetId,1189 text:1190 "✦ عضویت شما در CREATORS فعال شد.\n\n" +1191 "دسترسی شما به امکانات خصوصی برقرار شد."1192 });1193 } catch (error) {}1194 1195 await updateManagePanel(targetId);1196 return;1197}1198 1199 1200// ==================================================1201// غیرفعالسازی همه دسترسیها1202// ==================================================1203 1204if (data.startsWith("all_off_")) {1205 const targetId = getTargetId("all_off_");1206 1207 if (!targetId) {1208 await Api.answerCallbackQuery({1209 callback_query_id: callbackId,1210 text: "شناسه کاربر نامعتبر است."1211 });1212 return;1213 }1214 1215 const access = {1216 membership: false,1217 profile: false,1218 challenges: false,1219 vc: false,1220 streak: false,1221 achievements: false,1222 rewards: false,1223 private_content: false,1224 private_group: false1225 };1226 1227 const accessResult = await db.user.set(1228 "access",1229 access,1230 { user_id: targetId }1231 );1232 1233 if (!saveSucceeded(accessResult)) {1234 await Api.answerCallbackQuery({1235 callback_query_id: callbackId,1236 text: "خطا در ذخیره دسترسیها."1237 });1238 return;1239 }1240 1241 const statusResult = await db.user.set(1242 "membership_status",1243 "expired",1244 { user_id: targetId }1245 );1246 1247 if (!saveSucceeded(statusResult)) {1248 await Api.answerCallbackQuery({1249 callback_query_id: callbackId,1250 text: "دسترسیها غیرفعال شدند، اما تغییر وضعیت ناموفق بود."1251 });1252 return;1253 }1254 1255 await Api.answerCallbackQuery({1256 callback_query_id: callbackId,1257 text: "عضویت و همه دسترسیها غیرفعال شدند."1258 });1259 1260 try {1261 await Api.sendMessage({1262 chat_id: targetId,1263 text:1264 "✦ دسترسی عضویت شما در CREATORS غیرفعال شد.\n\n" +1265 "امکانات خصوصی دیگر در دسترس نیستند.\n\n" +1266 "برای ادامه مسیر، با مدیر مجموعه تماس بگیرید."1267 });1268 } catch (error) {}1269 1270 await updateManagePanel(targetId);1271 return;1272}1273 1274 1275// ==================================================1276// تغییر یک دسترسی مشخص1277// ==================================================1278 1279if (data.startsWith("toggle_")) {1280 const parts = data.split("_");1281 const targetId = Number(parts[1]);1282 const accessName = parts.slice(2).join("_");1283 1284 const allowed = [1285 "membership",1286 "profile",1287 "challenges",1288 "vc",1289 "streak",1290 "achievements",1291 "rewards",1292 "private_content",1293 "private_group"1294 ];1295 1296 if (!Number.isSafeInteger(targetId) || targetId <= 0) {1297 await Api.answerCallbackQuery({1298 callback_query_id: callbackId,1299 text: "شناسه کاربر نامعتبر است."1300 });1301 return;1302 }1303 1304 if (!allowed.includes(accessName)) {1305 await Api.answerCallbackQuery({1306 callback_query_id: callbackId,1307 text: "نوع دسترسی نامعتبر است."1308 });1309 return;1310 }1311 1312 const access = await db.user.get(1313 "access",1314 {},1315 { user_id: targetId }1316 );1317 1318 const currentAccess = Object.assign({}, access || {});1319 const newValue = !Boolean(currentAccess[accessName]);1320 1321 currentAccess[accessName] = newValue;1322 1323 const result = await db.user.set(1324 "access",1325 currentAccess,1326 { user_id: targetId }1327 );1328 1329 if (!saveSucceeded(result)) {1330 await Api.answerCallbackQuery({1331 callback_query_id: callbackId,1332 text: "خطا در ذخیره دسترسی."1333 });1334 return;1335 }1336 1337 await Api.answerCallbackQuery({1338 callback_query_id: callbackId,1339 text: newValue ? "دسترسی فعال شد." : "دسترسی غیرفعال شد."1340 });1341 1342 await updateManagePanel(targetId);1343 return;1344}1345 1346 1347// ==================================================1348// callback ناشناخته1349// ==================================================1350 1351await Api.answerCallbackQuery({1352 callback_query_id: callbackId,1353 text: "دستور ناشناخته است."1354});1355 1356 1357// ==================================================1358// بهروزرسانی پنل مدیریت1359// ==================================================1360 1361async function updateManagePanel(targetId) {1362 const membership = await db.user.get(1363 "membership_status",1364 "unknown",1365 { user_id: targetId }1366 );1367 1368 const access = await db.user.get(1369 "access",1370 {},1371 { user_id: targetId }1372 );1373 1374 const a = access || {};1375 1376 await Api.editMessageText({1377 chat_id: callbackMessage.chat.id,1378 message_id: callbackMessage.message_id,1379 text:1380 "✦ مدیریت Creator\n\n" +1381 "Telegram ID: " + targetId + "\n" +1382 "وضعیت عضویت: " + membership + "\n\n" +1383 "دسترسیها:",1384 reply_markup: {1385 inline_keyboard: [1386 [1387 {1388 text: "🟢 فعال کردن همه",1389 callback_data: "all_on_" + targetId1390 },1391 {1392 text: "🔴 غیرفعال کردن همه",1393 callback_data: "all_off_" + targetId1394 }1395 ],1396 [1397 {1398 text: (a.membership ? "🟢" : "🔴") + " عضویت اصلی",1399 callback_data: "toggle_" + targetId + "_membership"1400 }1401 ],1402 [1403 {1404 text: (a.profile ? "🟢" : "🔴") + " پروفایل",1405 callback_data: "toggle_" + targetId + "_profile"1406 }1407 ],1408 [1409 {1410 text: (a.challenges ? "🟢" : "🔴") + " چالشها",1411 callback_data: "toggle_" + targetId + "_challenges"1412 }1413 ],1414 [1415 {1416 text: (a.vc ? "🟢" : "🔴") + " VC",1417 callback_data: "toggle_" + targetId + "_vc"1418 }1419 ],1420 [1421 {1422 text: (a.streak ? "🟢" : "🔴") + " Streak",1423 callback_data: "toggle_" + targetId + "_streak"1424 }1425 ],1426 [1427 {1428 text: (a.achievements ? "🟢" : "🔴") + " دستاوردها",1429 callback_data: "toggle_" + targetId + "_achievements"1430 }1431 ],1432 [1433 {1434 text: (a.rewards ? "🟢" : "🔴") + " جوایز",1435 callback_data: "toggle_" + targetId + "_rewards"1436 }1437 ],1438 [1439 {1440 text: (a.private_content ? "🟢" : "🔴") + " محتوای خصوصی",1441 callback_data: "toggle_" + targetId + "_private_content"1442 }1443 ],1444 [1445 {1446 text: (a.private_group ? "🟢" : "🔴") + " گروه خصوصی",1447 callback_data: "toggle_" + targetId + "_private_group"1448 }1449 ]1450 ]1451 }1452 });1453}