111dhruvil111/EntrysakibotPublic · Bot Template
AIThis TBL bot implements a private crypto community access flow called RED EYE. It stores user Telegram profiles, enforces entry requirements such as minimum crypto net worth and deal volume, and offers inline buttons for applying, checking application status, and contacting support. Admin commands are protected by an owner/admin registry, log actions to an audit trail, and route callback-driven menus. A global webhook worker retries failed notifications, and the wildcard handler collects multi-step form input such as asset names.
Socialcryptoprivate-communityaccess-applicationadmin-panelaudit-lognotifications
7 commands0 envUpdated 20d agoCreated Aug 17, 2026
commands/_.js
javascript · 246 lines
1/**#command2name: *3answer: 4keyboard: 5parse_mode: markdown6aliases: 7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12/**#command13name: *14answer:15keyboard:16parse_mode: markdown17aliases:18allow_only_group: false19need_reply: 020case_insensitive: false21is_web: 022#command**/23 24let uid = Number(user.telegramid || user.id);25let mode = String(await db.user.get("input_mode", ""));26if (!mode) return;27let msg = (update && update.message) ? update.message : (typeof message !== "undefined" ? message : null);28if (!msg) return;29let text = String(msg.text || msg.caption || "").trim();30 31function fileInfo(m) {32 if (m.video) return { type:"video", file_id:m.video.file_id };33 if (m.document) return { type:"document", file_id:m.document.file_id };34 if (m.photo && m.photo.length) return { type:"photo", file_id:m.photo[m.photo.length-1].file_id };35 if (m.animation) return { type:"animation", file_id:m.animation.file_id };36 return null;37}38 39async function inputAudit(action,target,details){40 let logs=await db.bot.get("audit_logs",[]);if(!Array.isArray(logs))logs=[];41 logs.push({id:"AUD-"+Date.now()+"-"+Math.floor(Math.random()*100000),action:String(action),target_user_id:Number(target||0)||undefined,details:details||{},by:uid,at:Date.now()});42 await db.bot.set("audit_logs",logs.slice(-1000));43}44 45async function inputNotify(payload,kind,target){46 try{let r=await Api.sendMessage(payload);if(r&&r.ok===false)throw new Error(String(r.description||"send_failed"));return true;}catch(e){let q=await db.bot.get("notification_retry_queue",[]);if(!Array.isArray(q))q=[];q.push({id:"NQ-"+Date.now()+"-"+Math.floor(Math.random()*100000),payload:payload,kind:String(kind||"notification"),target_user_id:Number(target||payload.chat_id||0),attempts:0,next_retry_at:Date.now()+5*60000,created_at:Date.now()});await db.bot.set("notification_retry_queue",q.slice(-500));return false;}47}48 49if (mode === "other_asset_name") {50 if (!text || text.length > 20) { Bot.sendMessage("Send a short asset name/symbol, e.g. AVAX."); return; }51 let symbol = text.toUpperCase();52 let assets = await db.user.get("assets", []); if (!Array.isArray(assets)) assets = [];53 if (!assets.includes(symbol)) assets.push(symbol);54 await db.user.set("assets", assets);55 await db.user.del("input_mode");56 Bot.runCommand("/handle_callback_query", { route: "user_core assets" });57 return;58}59 60if (mode === "wallet_address") {61 if (!text || text.length < 12 || text.length > 140 || /\s/.test(text)) {62 Bot.sendMessage("⚠️ That does not look like a valid public wallet address. Check it and send it again.");63 return;64 }65 let asset = String(await db.user.get("current_wallet_asset", "OTHER"));66 let network = String(await db.user.get("current_wallet_network", "MANUAL"));67 let wallets = await db.user.get("wallets", []); if (!Array.isArray(wallets)) wallets = [];68 if (wallets.some(w => String(w.address).toLowerCase() === text.toLowerCase() && w.network === network)) {69 Bot.sendMessage("That wallet is already added.");70 return;71 }72 wallets.push({ asset:asset, network:network, address:text, added_at:Date.now(), verification_status:"pending" });73 await db.user.set("wallets", wallets);74 let memberStatus=String(await db.user.get("member_status","")||"");75 if(["active","approved_pending_join"].includes(memberStatus)){76 await db.user.set("wallet_change_pending",true);await db.user.set("reverification_status","requested");await db.user.set("reverification_type","wallet");77 let rr=await db.bot.get("reverification_requests",[]);if(!Array.isArray(rr))rr=[];if(!rr.some(x=>x&&Number(x.user_id)===uid&&!['completed','cancelled'].includes(String(x.status))&&x.reason==="wallet_change")){rr.push({id:"RV-WALLET-"+uid+"-"+Date.now(),user_id:uid,type:"wallet",reason:"wallet_change",status:"requested",requested_at:Date.now(),requested_by:"system"});await db.bot.set("reverification_requests",rr);}78 let settings=await db.bot.get("system_settings",{});if(!settings||typeof settings!=="object")settings={};let owner=Number(settings.owner_id||771142220);await inputNotify({chat_id:owner,text:"👛 <b>MEMBER WALLET CHANGE</b>\n\nMember <code>"+uid+"</code> added a new public wallet. It is pending admin verification; previous wallet history is retained.",parse_mode:"HTML"},"member_wallet_change",owner);await inputAudit("member_wallet_added_pending",uid,{asset:asset,network:network});79 }80 await db.user.del("input_mode");81 Bot.sendMessage("✅ Wallet saved. Checking public balance/value where supported…"+(memberStatus?" Admin verification remains pending.":""));82 Bot.runCommand("/handle_callback_query", { route: "user_core wallet_recheck" });83 return;84}85 86if (mode === "ownership_proof") {87 let f = fileInfo(msg);88 if (!f || !["video","document","animation"].includes(f.type)) {89 Bot.sendMessage("Send a video/screen recording, document or animation as ownership proof.");90 return;91 }92 f.submitted_at = Date.now();93 await db.user.set("ownership_proof", f);94 await db.user.del("input_mode");95 Bot.sendMessage("✅ Ownership proof received.");96 Bot.runCommand("/handle_callback_query", { route: "user_core deal_proof" });97 return;98}99 100if (mode === "deal_proof") {101 let f = fileInfo(msg);102 if (!f) { Bot.sendMessage("Send a photo, video or document containing your deal-history proof."); return; }103 f.submitted_at = Date.now();104 let proofs = await db.user.get("deal_proofs", []); if (!Array.isArray(proofs)) proofs = [];105 proofs.push(f);106 await db.user.set("deal_proofs", proofs);107 Bot.sendMessage("✅ Deal proof received. Total proofs: " + proofs.length + ". Send another proof or tap Finish Proof Upload.");108 return;109}110 111if (mode === "reverify_ownership_proof") {112 let f=fileInfo(msg); if(!f||!["video","document","animation"].includes(f.type)){Bot.sendMessage("Send a video/screen recording, document or animation.");return;} f.submitted_at=Date.now();await db.user.set("reverify_ownership_proof",f);await db.user.del("input_mode");Bot.sendMessage("✅ Updated ownership proof received.");Bot.runCommand("/handle_callback_query",{route:"user_core reverify_start"});return;113}114if (mode === "reverify_deal_proof") {115 let f=fileInfo(msg);if(!f){Bot.sendMessage("Send a photo, video or document.");return;}f.submitted_at=Date.now();let p=await db.user.get("reverify_deal_proofs",[]);if(!Array.isArray(p))p=[];p.push(f);await db.user.set("reverify_deal_proofs",p);Bot.sendMessage("✅ Updated deal proof received. Total: "+p.length+". Send another or tap Done.");return;116}117 118if (mode === "more_info_response") {119 let f = fileInfo(msg);120 let item = { text:text || "", file:f, submitted_at:Date.now() };121 let hist = await db.user.get("more_info_history", []); if (!Array.isArray(hist)) hist = [];122 hist.push(item);123 await db.user.set("more_info_history", hist);124 await db.user.set("latest_more_info_response", item);125 await db.user.set("application_status", "submitted");126 await db.user.del("input_mode");127 let queue = await db.bot.get("application_queue", []); if (!Array.isArray(queue)) queue = [];128 for (let q of queue) if (Number(q.user_id) === uid) { q.status = "submitted"; q.more_info_received_at = Date.now(); }129 await db.bot.set("application_queue", queue);130 let settings = await db.bot.get("system_settings", {}); if (!settings || typeof settings !== "object") settings = {};131 let owner = Number(settings.owner_id || 771142220);132 await inputNotify({ chat_id:owner, text:"📝 Additional information received from user <code>"+uid+"</code>.", parse_mode:"HTML", reply_markup:{inline_keyboard:[[{text:"🧿 Review",callback_data:"admin_core app:"+uid,style:"primary"}]]} },"more_info_response",owner);133 Bot.sendMessage("✅ Additional information submitted. Your application has returned to the review queue.");134 return;135}136 137if (mode === "support_message") {138 let settings = await db.bot.get("system_settings", {}); if (!settings || typeof settings !== "object") settings = {};139 let owner = Number(settings.owner_id || 771142220);140 let f = fileInfo(msg);141 await inputNotify({ chat_id:owner, text:"✉ <b>SUPPORT MESSAGE</b>\n\nFrom: <code>"+uid+"</code>\nUsername: "+(user.username?"@"+user.username:"—")+"\n\n"+(text||"[media attached]"), parse_mode:"HTML" },"support_message",owner);142 if (f) {143 let method = f.type === "photo" ? "sendPhoto" : f.type === "video" ? "sendVideo" : f.type === "animation" ? "sendAnimation" : "sendDocument";144 let key = f.type === "photo" ? "photo" : f.type;145 let payload = { chat_id:owner }; payload[key] = f.file_id;146 await Api.call(method, payload);147 }148 await db.user.del("input_mode");149 Bot.sendMessage("✅ Your support message has been sent.");150 return;151}152 153if (mode === "staff_set_pin" || mode === "staff_login_pin") {154 let authSettings=await db.bot.get("system_settings",{});if(!authSettings||typeof authSettings!=="object")authSettings={};let authOwner=Number(authSettings.owner_id||771142220);let authRegistry=await db.bot.get("admin_registry",[]);if(!Array.isArray(authRegistry))authRegistry=[];let authRec=uid===authOwner?{user_id:uid,role:"owner",revoked:false}:authRegistry.find(x=>x&&Number(x.user_id)===uid&&x.revoked!==true);if(!authRec){await db.user.del("input_mode");Bot.sendMessage("⛔ Admin access is not authorized for this account.");return;}155 let pin=text.trim(); if(!/^\d{6,12}$/.test(pin)){Bot.sendMessage("⚠️ PIN must contain 6–12 digits.");return;}156 if(!modules || !modules.bcrypt){Bot.sendMessage("⛔ Secure bcrypt module is unavailable in this runtime.");return;}157 if(mode==="staff_set_pin") { let hash=await modules.bcrypt.hash(pin,10);await db.user.set("staff_pin_hash",hash);await db.user.set("staff_session_until",Date.now()+30*60*1000);await db.user.del("staff_auth_failures");await db.user.del("staff_auth_lock_until");await db.user.del("input_mode");await inputAudit("staff_pin_configured",uid,{});Bot.sendMessage("✅ Staff PIN saved. Secure session active for 30 minutes.");Bot.runCommand("/handle_callback_query",{route:"admin_core home"});return; }158 let lock=Number(await db.user.get("staff_auth_lock_until",0)||0);if(lock>Date.now()){await db.user.del("input_mode");Bot.sendMessage("⛔ Login is temporarily locked.");return;}159 let hash=String(await db.user.get("staff_pin_hash","")||""),valid=hash?await modules.bcrypt.compare(pin,hash):false;160 if(!valid){let failures=Number(await db.user.get("staff_auth_failures",0)||0)+1;if(failures>=5){await db.user.set("staff_auth_lock_until",Date.now()+15*60*1000);failures=0;}await db.user.set("staff_auth_failures",failures);Bot.sendMessage("❌ Invalid PIN."+(failures===0?" Login locked for 15 minutes.":""));return;}161 await db.user.set("staff_session_until",Date.now()+30*60*1000);await db.user.del("staff_auth_failures");await db.user.del("staff_auth_lock_until");await db.user.del("input_mode");await inputAudit("staff_login_success",uid,{});Bot.sendMessage("✅ Staff authentication successful. Session active for 30 minutes.");Bot.runCommand("/handle_callback_query",{route:"admin_core home"});return;162}163 164if (mode.indexOf("admin_") === 0) {165 let settings = await db.bot.get("system_settings", {}); if (!settings || typeof settings !== "object") settings = {};166 let owner = Number(settings.owner_id || 771142220);167 let registry = await db.bot.get("admin_registry", []); if (!Array.isArray(registry)) registry = [];168 let rec = uid === owner ? {user_id:uid,role:"owner",revoked:false} : registry.find(x=>x&&Number(x.user_id)===uid&&x.revoked!==true);169 if (!rec) { await db.user.del("input_mode"); return; }170 let allPerms=["dashboard","applications","review","approve","reject","more_info","override","members","wallets","reverify","alerts","blacklist","rules","settings","assets","p2p","announcements","analytics","admins","audit","backup","maintenance","system"];171 let role=String(rec.role||"support"), perms = (role==="owner"||role==="super_admin") ? allPerms : role==="verification_staff" ? ["dashboard","applications","review","approve","reject","more_info","members","wallets","reverify","alerts","analytics"] : role==="moderator" ? ["dashboard","members","alerts","blacklist","rules","announcements","audit"] : role==="support" ? ["dashboard","applications","members"] : [];172 let need = mode==="admin_set_crypto"||mode==="admin_set_deals" ? "wallets" : mode==="admin_reject_reason" ? "reject" : mode==="admin_custom_message"||mode==="admin_more_info" ? "more_info" : mode.startsWith("admin_setting_") ? "settings" : mode==="admin_override_reason" ? "override" : mode==="admin_member_note" ? "members" : mode==="admin_blacklist_id"||mode==="admin_blacklist_reason" ? "blacklist" : mode.startsWith("admin_rule_") ? "rules" : mode.startsWith("admin_asset_")||mode.startsWith("admin_network_") ? "assets" : mode==="admin_announcement" ? "announcements" : mode==="admin_maintenance_message" ? "maintenance" : mode.startsWith("admin_p2p_") ? "p2p" : mode.startsWith("admin_add_staff") ? "admins" : mode.startsWith("admin_system_") ? "system" : "dashboard";173 let sessionUntil=Number(await db.user.get("staff_session_until",0)||0);174 if (!perms.includes(need) || sessionUntil<=Date.now()) { await db.user.del("input_mode"); Bot.sendMessage("⛔ This staff session is not authorized for that action."); return; }175 let target = Number(await db.user.get("admin_selected_user", 0));176 let noTargetModes = ["admin_blacklist_id","admin_rule_add","admin_rule_edit_title","admin_rule_edit_text","admin_asset_add","admin_announcement","admin_maintenance_message","admin_network_add","admin_p2p_add","admin_add_staff_id","admin_system_channel","admin_system_group"];177 if (!target && !mode.startsWith("admin_setting_") && !noTargetModes.includes(mode)) { Bot.sendMessage("No applicant selected."); return; }178 179 if (mode === "admin_set_crypto") {180 let n = Number(text.replace(/[$,]/g,"")); if (!Number.isFinite(n) || n < 0) { Bot.sendMessage("Send a valid USD amount."); return; }181 let old=Number(await db.user.get("admin_verified_crypto",0,{user_id:target})||0);await db.user.set("admin_verified_crypto", n, {user_id:target}); await db.user.del("input_mode");await inputAudit("verified_crypto_changed",target,{old_value:old,new_value:n});182 Bot.sendMessage("✅ Verified crypto value saved: $"+n); Bot.runCommand("/handle_callback_query",{route:"admin_core app:"+target}); return;183 }184 if (mode === "admin_set_deals") {185 let n = Number(text.replace(/[$,]/g,"")); if (!Number.isFinite(n) || n < 0) { Bot.sendMessage("Send a valid USD amount."); return; }186 let old=Number(await db.user.get("admin_verified_deals",0,{user_id:target})||0);await db.user.set("admin_verified_deals", n, {user_id:target}); await db.user.del("input_mode");await inputAudit("verified_deals_changed",target,{old_value:old,new_value:n});187 Bot.sendMessage("✅ Verified deal volume saved: $"+n); Bot.runCommand("/handle_callback_query",{route:"admin_core app:"+target}); return;188 }189 if (mode === "admin_reject_reason") {190 if (!text) { Bot.sendMessage("Send a rejection reason."); return; }191 await db.user.del("input_mode"); Bot.runCommand("/handle_callback_query", {route:"admin_core reject_do:"+target+":"+encodeURIComponent(text)}); return;192 }193 if (mode === "admin_custom_message") {194 if (!text) { Bot.sendMessage("Send the message text."); return; }195 await db.user.del("input_mode");196 Api.sendMessage({chat_id:target,text:"✉ <b>MESSAGE FROM RED EYE ADMIN</b>\n\n"+text,parse_mode:"HTML"});197 let hist=await db.user.get("admin_message_history",[],{user_id:target});if(!Array.isArray(hist))hist=[];hist.push({text:text,by:uid,at:Date.now()});await db.user.set("admin_message_history",hist.slice(-100),{user_id:target});198 let audit=await db.bot.get("audit_logs",[]);if(!Array.isArray(audit))audit=[];audit.push({id:"AUD-"+Date.now(),action:"admin_custom_message",target_user_id:target,by:uid,at:Date.now()});await db.bot.set("audit_logs",audit.slice(-1000));199 Bot.sendMessage("✅ Message sent."); Bot.runCommand("/handle_callback_query",{route:"admin_core app:"+target}); return;200 }201 if (mode === "admin_more_info") {202 if (!text) { Bot.sendMessage("Send the information request."); return; }203 await db.user.del("input_mode"); Bot.runCommand("/handle_callback_query", {route:"admin_core moreinfo_do:"+target+":"+encodeURIComponent(text)}); return;204 }205 if (mode.startsWith("admin_setting_")) {206 let key = mode.replace("admin_setting_","");207 let n = Number(text.replace(/[$,]/g,""));208 if (!["min_crypto_networth","min_deal_volume","low_wallet_threshold","low_wallet_clear_threshold","low_wallet_duration_days","rejection_cooldown_hours","extended_cooldown_hours","application_reminder_minutes","application_expiry_hours","verification_expiry_days"].includes(key) || !Number.isFinite(n) || n < 0) { Bot.sendMessage("Send a valid numeric setting value."); return; }209 let old=settings[key];settings[key] = n; await db.bot.set("system_settings", settings); await db.user.del("input_mode");await inputAudit("setting_changed",0,{key:key,old_value:old,new_value:n}); Bot.sendMessage("✅ Setting updated."); Bot.runCommand("/handle_callback_query", { route: "admin_core settings" }); return;210 }211 if (mode === "admin_override_reason") {212 if (!text) { Bot.sendMessage("Send a mandatory override reason."); return; }213 await db.user.del("input_mode"); Bot.runCommand("/handle_callback_query", {route:"admin_core override_do:"+target+":"+encodeURIComponent(text)}); return;214 }215 if (mode === "admin_member_note") {216 if (!text) { Bot.sendMessage("Send a note."); return; }217 let notes=await db.user.get("admin_notes",[],{user_id:target});if(!Array.isArray(notes))notes=[];notes.push({text:text,by:uid,at:Date.now()});await db.user.set("admin_notes",notes.slice(-100),{user_id:target});await db.user.del("input_mode");await inputAudit("member_note_added",target,{});Bot.sendMessage("✅ Note saved.");Bot.runCommand("/handle_callback_query",{route:"admin_core member:"+target});return;218 }219 if (mode === "admin_blacklist_id") {220 let id=Number(text);if(!id||id<=0){Bot.sendMessage("Send a valid numeric Telegram user ID.");return;}await db.user.set("admin_selected_user",id);await db.user.set("input_mode","admin_blacklist_reason");Bot.sendMessage("Now send the blacklist reason.");return;221 }222 if (mode === "admin_blacklist_reason") {223 if(!text){Bot.sendMessage("Send the blacklist reason.");return;}let bl=await db.bot.get("blacklist",[]);if(!Array.isArray(bl))bl=[];let prevApp=String(await db.user.get("application_status","",{user_id:target})||""),prevMember=String(await db.user.get("member_status","",{user_id:target})||"");bl=bl.filter(x=>Number(x.user_id)!==target);bl.push({user_id:target,reason:text,blacklisted_at:Date.now(),blacklisted_by:uid,previous_application_status:prevApp,previous_member_status:prevMember});await db.bot.set("blacklist",bl);await db.user.set("pre_blacklist_application_status",prevApp,{user_id:target});await db.user.set("pre_blacklist_member_status",prevMember,{user_id:target});await db.user.set("application_status","blacklisted",{user_id:target});if(prevMember)await db.user.set("member_status","blacklisted",{user_id:target});let members=await db.bot.get("member_registry",[]);if(!Array.isArray(members))members=[];for(let m of members)if(m&&Number(m.user_id)===target){m.pre_blacklist_status=m.status;m.status="blacklisted";m.updated_at=Date.now();}await db.bot.set("member_registry",members);await db.user.set("blacklist_reason",text,{user_id:target});await db.user.del("input_mode");await inputAudit("user_blacklisted",target,{reason:text,previous_application_status:prevApp,previous_member_status:prevMember});await inputNotify({chat_id:target,text:"⛔ <b>RED EYE ACCESS RESTRICTED</b>\n\nYour account has been blocked from the application system.\nReason: "+text,parse_mode:"HTML"},"blacklist_notice",target);Bot.sendMessage("✅ User blacklisted.");Bot.runCommand("/handle_callback_query", { route: "admin_core blacklist" });return;224 }225 if (mode === "admin_rule_add") {226 let parts=text.split("|");if(parts.length<3){Bot.sendMessage("Use: Category | Title | Full rule text");return;}let category=parts.shift().trim(),title=parts.shift().trim(),body=parts.join("|").trim();let cats=["General","P2P","OTC","NFT","Advertising","DM","Scam/Fraud","Conduct"];if(!cats.includes(category)){Bot.sendMessage("Category must be one of: "+cats.join(", "));return;}if(!title||!body){Bot.sendMessage("Title and rule text are required.");return;}let rules=await db.bot.get("rules",[]);if(!Array.isArray(rules))rules=[];let rec={id:"RULE-"+Date.now(),category:category,title:title,text:body,enabled:true,version:1,created_at:Date.now(),created_by:uid};rules.push(rec);await db.bot.set("rules",rules);let h=await db.bot.get("rule_history",[]);if(!Array.isArray(h))h=[];h.push({rule_id:rec.id,change:"created",snapshot:rec,by:uid,at:Date.now()});await db.bot.set("rule_history",h.slice(-500));let audit=await db.bot.get("audit_logs",[]);if(!Array.isArray(audit))audit=[];audit.push({id:"AUD-"+Date.now(),action:"rule_added",details:{title:title,category:category},by:uid,at:Date.now()});await db.bot.set("audit_logs",audit.slice(-1000));await db.user.del("input_mode");Bot.runCommand("/handle_callback_query", { route: "admin_core rules" });return;227 }228 if (mode === "admin_rule_edit_title" || mode === "admin_rule_edit_text") {229 let i=Number(await db.user.get("admin_selected_rule",-1));let rules=await db.bot.get("rules",[]);if(!Array.isArray(rules)||!rules[i]){Bot.sendMessage("Rule not found.");await db.user.del("input_mode");return;}if(!text){Bot.sendMessage("Value cannot be empty.");return;}let field=mode==="admin_rule_edit_title"?"title":"text",old=rules[i][field];rules[i][field]=text;rules[i].version=Number(rules[i].version||1)+1;rules[i].updated_at=Date.now();rules[i].updated_by=uid;await db.bot.set("rules",rules);let h=await db.bot.get("rule_history",[]);if(!Array.isArray(h))h=[];h.push({rule_id:rules[i].id,change:"edit_"+field,old_value:old,new_value:text,version:rules[i].version,by:uid,at:Date.now()});await db.bot.set("rule_history",h.slice(-500));await db.user.del("input_mode");await inputAudit("rule_edited",0,{rule_id:rules[i].id,field:field,old_value:old,new_value:text});Bot.runCommand("/handle_callback_query",{route:"admin_core rule_view:"+i});return;230 }231 if (mode === "admin_asset_add") {232 let symbol=text.toUpperCase().replace(/[^A-Z0-9._-]/g,"").slice(0,15);if(!symbol){Bot.sendMessage("Send a valid asset symbol.");return;}let assets=Array.isArray(settings.featured_assets)?settings.featured_assets:["USDT","SOL","ETH","BTC","TON"];if(!assets.includes(symbol))assets.push(symbol);settings.featured_assets=assets;await db.bot.set("system_settings",settings);await db.user.del("input_mode");await inputAudit("asset_added",0,{symbol:symbol});Bot.runCommand("/handle_callback_query", { route: "admin_core assets" });return;233 }234 if (mode === "admin_announcement") {235 if(!text){Bot.sendMessage("Announcement text cannot be empty.");return;}await db.user.set("pending_announcement",text);await db.user.del("input_mode");Api.sendMessage({chat_id:chat.id,text:"📣 <b>CONFIRM ANNOUNCEMENT</b>\n\n"+text,parse_mode:"HTML",reply_markup:{inline_keyboard:[[{text:"✅ Send to Members",callback_data:"admin_core announcement_confirm",style:"success"},{text:"✕ Cancel",callback_data:"admin_core announcement_cancel",style:"danger"}]]}});return;236 }237 if (mode === "admin_network_add") { let parts=text.split("|");if(parts.length<2){Bot.sendMessage("Use: ASSET | NETWORK1, NETWORK2");return;}let asset=parts.shift().trim().toUpperCase(),nets=parts.join("|").split(",").map(x=>x.trim().toUpperCase()).filter(Boolean);if(!asset||!nets.length){Bot.sendMessage("Asset and at least one network are required.");return;}let map=settings.asset_networks;if(!map||typeof map!=="object")map={};map[asset]=Array.from(new Set(nets));settings.asset_networks=map;await db.bot.set("system_settings",settings);await db.user.del("input_mode");await inputAudit("asset_networks_changed",0,{asset:asset,networks:map[asset]});Bot.runCommand("/handle_callback_query",{route:"admin_core networks"});return; }238 if (mode === "admin_p2p_add") { let parts=text.split("|");if(parts.length<2){Bot.sendMessage("Use: Name | @username_or_chat_id");return;}let name=parts.shift().trim(),ref=parts.join("|").trim();if(!name||!ref){Bot.sendMessage("Both values are required.");return;}let g=await db.bot.get("p2p_groups",[]);if(!Array.isArray(g))g=[];g.push({id:"P2P-"+Date.now(),name:name,reference:ref,enabled:true,created_at:Date.now(),created_by:uid});await db.bot.set("p2p_groups",g);await db.user.del("input_mode");await inputAudit("p2p_group_added",0,{name:name,reference:ref});Bot.runCommand("/handle_callback_query",{route:"admin_core p2p"});return; }239 if (mode === "admin_add_staff_id") { let id=Number(text);if(!id||id<=0){Bot.sendMessage("Send a valid numeric Telegram user ID.");return;}let a=await db.bot.get("admin_registry",[]);if(!Array.isArray(a))a=[];if(a.some(x=>x&&Number(x.user_id)===id)){Bot.sendMessage("Admin already exists.");return;}a.push({user_id:id,role:"support",revoked:false,created_at:Date.now(),created_by:uid});await db.bot.set("admin_registry",a);await db.user.del("input_mode");await inputAudit("admin_added",id,{role:"support"});await inputNotify({chat_id:id,text:"👮 You were added as RED EYE staff with Support role. Open /admin and set a secure staff PIN before using protected actions."},"staff_added",id);Bot.runCommand("/handle_callback_query",{route:"admin_core admins"});return; }240 if (mode === "admin_system_channel") { let ch=text.trim();if(!/^@[A-Za-z0-9_]{5,}$/.test(ch)){Bot.sendMessage("Send a valid @channel username.");return;}let old=settings.official_channel;settings.official_channel=ch;settings.official_channel_url="https://t.me/"+ch.slice(1);await db.bot.set("system_settings",settings);await db.user.del("input_mode");await inputAudit("official_channel_changed",0,{old_value:old,new_value:ch});Bot.runCommand("/handle_callback_query",{route:"admin_core system"});return; }241 if (mode === "admin_system_group") { let id=Number(text);if(!Number.isFinite(id)||id>=0){Bot.sendMessage("Send a valid negative Telegram group/channel ID, usually -100…");return;}let old=settings.private_group_id;settings.private_group_id=id;await db.bot.set("system_settings",settings);await db.user.del("input_mode");await inputAudit("private_group_changed",0,{old_value:old,new_value:id});Bot.runCommand("/handle_callback_query",{route:"admin_core system"});return; }242 if (mode === "admin_maintenance_message") {243 if(!text){Bot.sendMessage("Message cannot be empty.");return;}let old=settings.maintenance_message;settings.maintenance_message=text;await db.bot.set("system_settings",settings);await db.user.del("input_mode");await inputAudit("maintenance_message_changed",0,{old_value:old,new_value:text});Bot.runCommand("/handle_callback_query", { route: "admin_core maintenance_page" });return;244 }245 246}