Sticker-eitaa / api.html
Hosdroid's picture
Create api.html
fcbf57c verified
Raw
History Blame Contribute Delete
32 kB
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline' https://eitaayar.ir; connect-src https://eitaayar.ir;">
<title>🤖 ربات هوشمند ایتا - نسخه 2.0</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', Tahoma, sans-serif;
background: linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%);
min-height: 100vh; padding: 20px; color: #fff;
}
.container {
max-width: 1200px; margin: 0 auto;
display: grid; grid-template-columns: 350px 1fr; gap: 20px;
}
@media (max-width: 968px) { .container { grid-template-columns: 1fr; } }
.panel {
background: rgba(255,255,255,0.05); backdrop-filter: blur(20px);
border: 1px solid rgba(255,255,255,0.1); border-radius: 20px;
padding: 25px; box-shadow: 0 20px 40px rgba(0,0,0,0.3);
}
.panel h2 {
font-size: 18px; margin-bottom: 20px; display: flex;
align-items: center; gap: 10px; color: #00d2ff;
}
.panel h2 .icon {
width: 40px; height: 40px; border-radius: 12px;
background: linear-gradient(135deg, #00d2ff, #3a7bd5);
display: flex; align-items: center; justify-content: center; font-size: 20px;
}
.form-group { margin-bottom: 18px; }
.form-group label {
display: block; font-size: 13px; font-weight: 600;
margin-bottom: 8px; color: rgba(255,255,255,0.8);
}
.form-group input, .form-group textarea, .form-group select {
width: 100%; padding: 12px 15px;
background: rgba(255,255,255,0.07); border: 2px solid rgba(255,255,255,0.1);
border-radius: 10px; color: #fff; font-size: 14px;
font-family: inherit; outline: none; transition: all 0.3s;
}
.form-group input:focus, .form-group textarea:focus {
border-color: #00d2ff; background: rgba(255,255,255,0.1);
}
.input-with-toggle { position: relative; }
.input-with-toggle input { padding-left: 45px; }
.toggle-vis {
position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
background: none; border: none; color: rgba(255,255,255,0.5);
cursor: pointer; font-size: 16px;
}
.btn {
width: 100%; padding: 14px; border: none; border-radius: 10px;
font-size: 15px; font-weight: 700; font-family: inherit;
cursor: pointer; transition: all 0.3s; display: flex;
align-items: center; justify-content: center; gap: 8px;
}
.btn-primary { background: linear-gradient(135deg, #00d2ff, #3a7bd5); color: #fff; }
.btn-primary:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 10px 25px rgba(0,210,255,0.4); }
.btn-success { background: linear-gradient(135deg, #2ed573, #17a558); color: #fff; }
.btn-danger { background: linear-gradient(135deg, #ff4757, #c0392b); color: #fff; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.status-indicator {
display: inline-flex; align-items: center; gap: 8px;
padding: 8px 15px; border-radius: 20px; font-size: 13px; font-weight: 600;
margin-bottom: 15px;
}
.status-indicator.online { background: rgba(46,213,115,0.2); color: #2ed573; }
.status-indicator.offline { background: rgba(255,71,87,0.2); color: #ff4757; }
.status-indicator .dot {
width: 8px; height: 8px; border-radius: 50%;
animation: pulse 1.5s ease-in-out infinite;
}
.status-indicator.online .dot { background: #2ed573; }
.status-indicator.offline .dot { background: #ff4757; }
@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.3} }
.stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin-bottom: 20px; }
.stat-box {
background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1);
border-radius: 12px; padding: 15px; text-align: center;
}
.stat-box .value { font-size: 24px; font-weight: 700; color: #00d2ff; }
.stat-box .label { font-size: 11px; color: rgba(255,255,255,0.6); margin-top: 5px; }
.log-container {
background: rgba(0,0,0,0.3); border-radius: 12px; padding: 15px;
height: 400px; overflow-y: auto; font-family: 'Courier New', monospace;
font-size: 12px; line-height: 1.8;
}
.log-entry {
padding: 8px 12px; margin-bottom: 8px; border-radius: 8px;
border-right: 3px solid; animation: slideIn 0.3s ease;
}
@keyframes slideIn { from{opacity:0;transform:translateX(20px)} to{opacity:1;transform:translateX(0)} }
.log-entry.info { background: rgba(0,210,255,0.1); border-color: #00d2ff; }
.log-entry.success { background: rgba(46,213,115,0.1); border-color: #2ed573; }
.log-entry.warning { background: rgba(255,193,7,0.1); border-color: #ffc107; }
.log-entry.error { background: rgba(255,71,87,0.1); border-color: #ff4757; }
.log-entry .time { color: rgba(255,255,255,0.5); font-size: 10px; }
.log-entry .message { color: #fff; margin-top: 3px; word-break: break-word; }
.features-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-top: 15px; }
.feature-card {
background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1);
border-radius: 10px; padding: 12px; cursor: pointer; transition: all 0.3s;
}
.feature-card:hover { background: rgba(255,255,255,0.1); transform: translateY(-2px); }
.feature-card.active { border-color: #2ed573; background: rgba(46,213,115,0.1); }
.feature-card .icon { font-size: 24px; margin-bottom: 8px; }
.feature-card .title { font-size: 13px; font-weight: 600; margin-bottom: 3px; }
.feature-card .desc { font-size: 11px; color: rgba(255,255,255,0.5); }
.tab-buttons {
display: flex; gap: 8px; margin-bottom: 20px;
border-bottom: 2px solid rgba(255,255,255,0.1); padding-bottom: 10px;
}
.tab-btn {
padding: 8px 16px; border: none; background: transparent;
color: rgba(255,255,255,0.6); font-size: 13px; font-weight: 600;
cursor: pointer; border-radius: 8px; transition: all 0.3s;
}
.tab-btn.active { background: rgba(0,210,255,0.2); color: #00d2ff; }
.tab-content { display: none; }
.tab-content.active { display: block; animation: fadeIn 0.3s ease; }
@keyframes fadeIn { from{opacity:0} to{opacity:1} }
.keyword-list { max-height: 200px; overflow-y: auto; margin-top: 10px; }
.keyword-item {
display: flex; align-items: center; justify-content: space-between;
padding: 10px; background: rgba(255,255,255,0.05); border-radius: 8px;
margin-bottom: 8px;
}
.keyword-item .text { flex: 1; font-size: 13px; word-break: break-word; }
.keyword-item .delete {
background: rgba(255,71,87,0.2); border: none; color: #ff4757;
width: 28px; height: 28px; border-radius: 50%; cursor: pointer;
flex-shrink: 0; margin-right: 8px;
}
.add-keyword { display: flex; gap: 8px; margin-top: 10px; }
.add-keyword input { flex: 1; }
.add-keyword button {
padding: 10px 20px; background: #00d2ff; border: none;
border-radius: 8px; color: #fff; cursor: pointer; font-weight: 600;
}
.warning-banner {
background: rgba(255,193,7,0.15); border: 1px solid rgba(255,193,7,0.4);
border-radius: 10px; padding: 12px; margin-bottom: 15px;
font-size: 12px; color: #ffc107; display: none;
}
.warning-banner.show { display: block; }
</style>
</head>
<body>
<div class="container">
<div class="panel">
<h2><span class="icon">⚙️</span> پنل کنترل ربات</h2>
<div class="warning-banner" id="corsWarning">
⚠️ احتمالاً CORS درخواست رو بلاک می‌کنه. اگه کار نکرد، از سرور proxy استفاده کن.
</div>
<div class="status-indicator offline" id="statusIndicator">
<span class="dot"></span>
<span id="statusText">آفلاین</span>
</div>
<div class="form-group">
<label>🔑 توکن API</label>
<div class="input-with-toggle">
<input type="password" id="apiToken" placeholder="توکن را وارد کنید...">
<button type="button" class="toggle-vis" onclick="toggleTokenVis(this)">👁️</button>
</div>
</div>
<div class="form-group">
<label>👥 شناسه گروه (Chat ID)</label>
<input type="text" id="chatId" placeholder="مثال: 279058397">
</div>
<button class="btn btn-primary" id="startBtn" onclick="startBot()">
<span>▶️</span> شروع ربات
</button>
<button class="btn btn-danger" id="stopBtn" onclick="stopBot()" style="margin-top: 10px; display: none;">
<span>⏹️</span> توقف ربات
</button>
<div class="stats" style="margin-top: 20px;">
<div class="stat-box"><div class="value" id="messagesCount">0</div><div class="label">پیام دریافتی</div></div>
<div class="stat-box"><div class="value" id="responsesCount">0</div><div class="label">پاسخ ارسال شده</div></div>
<div class="stat-box"><div class="value" id="uptime">00:00</div><div class="label">زمان فعالیت</div></div>
<div class="stat-box"><div class="value" id="errorsCount">0</div><div class="label">خطاها</div></div>
</div>
<h2 style="margin-top: 25px;"><span class="icon"></span> ویژگی‌ها</h2>
<div class="features-grid" id="featuresGrid"></div>
</div>
<div class="panel">
<h2><span class="icon">📊</span> لاگ فعالیت‌ها</h2>
<div class="tab-buttons">
<button class="tab-btn active" data-tab="logs">📜 لاگ‌ها</button>
<button class="tab-btn" data-tab="settings">⚙️ تنظیمات</button>
<button class="tab-btn" data-tab="keywords">🔑 کلمات کلیدی</button>
</div>
<div class="tab-content active" id="tab-logs">
<div class="log-container" id="logContainer"></div>
</div>
<div class="tab-content" id="tab-settings">
<div class="form-group">
<label>پیام خوش‌آمدگویی</label>
<textarea id="welcomeMessage" rows="3">👋 سلام {name} عزیز!
به گروه ما خوش آمدی 🎉</textarea>
</div>
<div class="form-group">
<label>پاسخ به سلام</label>
<input type="text" id="greetingResponse" value="سلام علیکم 🙏">
</div>
<div class="form-group">
<label>فاصله بررسی (میلی‌ثانیه) - حداقل 3000</label>
<input type="number" id="pollInterval" value="3000" min="3000" step="500">
</div>
<button class="btn btn-success" onclick="saveSettings()">
<span>💾</span> ذخیره تنظیمات
</button>
</div>
<div class="tab-content" id="tab-keywords">
<h3 style="font-size: 14px; margin-bottom: 10px;">🚫 کلمات ممنوعه</h3>
<div class="keyword-list" id="bannedWordsList"></div>
<div class="add-keyword">
<input type="text" id="newBannedWord" placeholder="کلمه جدید...">
<button onclick="addBannedWord()">افزودن</button>
</div>
<h3 style="font-size: 14px; margin-top: 25px; margin-bottom: 10px;">💡 پاسخ‌های خودکار</h3>
<div class="keyword-list" id="autoResponsesList"></div>
<div class="add-keyword">
<input type="text" id="newAutoKeyword" placeholder="کلمه...">
<input type="text" id="newAutoResponse" placeholder="پاسخ...">
<button onclick="addAutoResponse()">افزودن</button>
</div>
</div>
</div>
</div>
<script>
'use strict';
// ===== تنظیمات پیش‌فرض =====
const DEFAULTS = {
token: '', chatId: '', lastUpdateId: 0, pollInterval: 3000,
welcomeMessage: '👋 سلام {name} عزیز!\nبه گروه ما خوش آمدی 🎉',
greetingResponse: 'سلام علیکم 🙏',
features: { welcome:true, greeting:true, google:true, help:true, time:true, quote:true, ping:true, filter:true },
bannedWords: [],
autoResponses: { 'سلام': 'سلام علیکم 🙏', 'صبح بخیر': 'صبح شما هم بخیر ☀️' },
stats: { messages: 0, responses: 0, errors: 0 }
};
const FEATURES_META = [
{ id: 'welcome', icon: '👋', title: 'خوش‌آمدگویی', desc: 'پیام برای اعضای جدید' },
{ id: 'greeting', icon: '🙏', title: 'پاسخ به سلام', desc: 'پاسخ "سلام علیکم"' },
{ id: 'google', icon: '🔍', title: 'جستجوی گوگل', desc: 'دستور /google' },
{ id: 'help', icon: '❓', title: 'راهنما', desc: 'دستور /help' },
{ id: 'time', icon: '🕐', title: 'ساعت و تاریخ', desc: 'دستور /time' },
{ id: 'quote', icon: '💬', title: 'نقل قول', desc: 'دستور /quote' },
{ id: 'ping', icon: '🏓', title: 'پینگ', desc: 'دستور /ping' },
{ id: 'filter', icon: '🚫', title: 'فیلتر کلمات', desc: 'حذف پیام نامناسب' }
];
const QUOTES = [
'💡 "تنها راه انجام کار بزرگ، عشق به آن است." - استیو جابز',
'🌟 "موفقیت نهایی نیست، شکست کشنده نیست، شجاعت ادامه دادن مهم است."',
'🚀 "آینده به کسانی تعلق دارد که به رویاهایشان ایمان دارند."',
'💪 "هر روز یک فرصت جدید برای تغییر است."',
'🎯 "تمرکز یعنی نه گفتن به صد ایده خوب دیگر."',
'🌈 "بعد از هر شب تاریک، صبح روشن در راه است."'
];
// ===== وضعیت ربات =====
let bot = {
config: { ...DEFAULTS },
running: false,
startTime: null,
pollTimer: null,
uptimeTimer: null
};
// ===== ابزارهای کمکی =====
function escapeHtml(str) {
const div = document.createElement('div');
div.textContent = str;
return div.innerHTML;
}
function escapeMarkdown(str) {
return str.replace(/([_*`\[\]()~>#+\-=|{}.!])/g, '\\$1');
}
function $(id) { return document.getElementById(id); }
function loadConfig() {
try {
const saved = localStorage.getItem('eitaBotConfig_v2');
if (saved) {
const parsed = JSON.parse(saved);
bot.config = { ...DEFAULTS, ...parsed, features: { ...DEFAULTS.features, ...(parsed.features||{}) }, stats: { ...DEFAULTS.stats, ...(parsed.stats||{}) } };
}
} catch (e) { console.error('Load error:', e); }
}
function saveConfig() {
try {
localStorage.setItem('eitaBotConfig_v2', JSON.stringify(bot.config));
} catch (e) { addLog('error', '❌ خطا در ذخیره: ' + e.message); }
}
// ===== UI =====
function toggleTokenVis(btn) {
const input = $('apiToken');
if (input.type === 'password') { input.type = 'text'; btn.textContent = '🙈'; }
else { input.type = 'password'; btn.textContent = '👁️'; }
}
function renderFeatures() {
const grid = $('featuresGrid');
grid.innerHTML = FEATURES_META.map(f => `
<div class="feature-card ${bot.config.features[f.id] ? 'active' : ''}" data-feature="${f.id}">
<div class="icon">${f.icon}</div>
<div class="title">${f.title}</div>
<div class="desc">${f.desc}</div>
</div>
`).join('');
grid.querySelectorAll('.feature-card').forEach(card => {
card.addEventListener('click', () => {
const id = card.dataset.feature;
bot.config.features[id] = !bot.config.features[id];
card.classList.toggle('active');
saveConfig();
addLog('info', `${bot.config.features[id] ? '✅' : '❌'} ${FEATURES_META.find(f=>f.id===id).title}`);
});
});
}
function renderBannedWords() {
const list = $('bannedWordsList');
list.innerHTML = '';
bot.config.bannedWords.forEach((word, i) => {
const item = document.createElement('div');
item.className = 'keyword-item';
const span = document.createElement('span');
span.className = 'text';
span.textContent = word;
const btn = document.createElement('button');
btn.className = 'delete';
btn.textContent = '✕';
btn.onclick = () => {
bot.config.bannedWords.splice(i, 1);
renderBannedWords();
saveConfig();
addLog('warning', '🗑️ حذف: ' + word);
};
item.appendChild(span);
item.appendChild(btn);
list.appendChild(item);
});
}
function renderAutoResponses() {
const list = $('autoResponsesList');
list.innerHTML = '';
Object.entries(bot.config.autoResponses).forEach(([k, v]) => {
const item = document.createElement('div');
item.className = 'keyword-item';
const span = document.createElement('span');
span.className = 'text';
span.innerHTML = `<strong>${escapeHtml(k)}:</strong> ${escapeHtml(v)}`;
const btn = document.createElement('button');
btn.className = 'delete';
btn.textContent = '✕';
btn.onclick = () => {
delete bot.config.autoResponses[k];
renderAutoResponses();
saveConfig();
addLog('warning', '🗑️ حذف: ' + k);
};
item.appendChild(span);
item.appendChild(btn);
list.appendChild(item);
});
}
function addBannedWord() {
const input = $('newBannedWord');
const word = input.value.trim();
if (word && !bot.config.bannedWords.includes(word)) {
bot.config.bannedWords.push(word);
input.value = '';
renderBannedWords();
saveConfig();
addLog('success', '✅ اضافه: ' + word);
}
}
function addAutoResponse() {
const k = $('newAutoKeyword').value.trim();
const v = $('newAutoResponse').value.trim();
if (k && v) {
bot.config.autoResponses[k] = v;
$('newAutoKeyword').value = '';
$('newAutoResponse').value = '';
renderAutoResponses();
saveConfig();
addLog('success', '✅ پاسخ خودکار: ' + k);
}
}
function addLog(type, message) {
const container = $('logContainer');
const entry = document.createElement('div');
entry.className = `log-entry ${type}`;
const timeDiv = document.createElement('div');
timeDiv.className = 'time';
timeDiv.textContent = new Date().toLocaleTimeString('fa-IR');
const msgDiv = document.createElement('div');
msgDiv.className = 'message';
msgDiv.textContent = message; // ✅ امن - بدون innerHTML
entry.appendChild(timeDiv);
entry.appendChild(msgDiv);
container.insertBefore(entry, container.firstChild);
while (container.children.length > 100) container.removeChild(container.lastChild);
}
function updateStats() {
$('messagesCount').textContent = bot.config.stats.messages;
$('responsesCount').textContent = bot.config.stats.responses;
$('errorsCount').textContent = bot.config.stats.errors;
}
function updateStatus(online) {
$('statusIndicator').className = 'status-indicator ' + (online ? 'online' : 'offline');
$('statusText').textContent = online ? 'آنلاین' : 'آفلاین';
}
function switchTab(tabName, btnEl) {
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
btnEl.classList.add('active');
$('tab-' + tabName).classList.add('active');
}
function saveSettings() {
const interval = Math.max(3000, parseInt($('pollInterval').value) || 3000);
bot.config.pollInterval = interval;
$('pollInterval').value = interval;
bot.config.welcomeMessage = $('welcomeMessage').value;
bot.config.greetingResponse = $('greetingResponse').value;
saveConfig();
addLog('success', '✅ تنظیمات ذخیره شد');
}
// ===== API =====
async function apiCall(method, params) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 15000); // ✅ timeout 15s
try {
// ساختار واقعی API ایتایار
const url = 'https://eitaayar.ir/api/app/' + method;
const body = { token: bot.config.token, ...params };
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
body: JSON.stringify(body),
signal: controller.signal
});
clearTimeout(timeout);
if (!response.ok) throw new Error('HTTP ' + response.status);
const data = await response.json();
if (data.status === 'error' || data.ok === false) {
throw new Error(data.error || data.description || 'خطای API');
}
return data;
} catch (e) {
clearTimeout(timeout);
if (e.name === 'AbortError') throw new Error('Timeout - سرور جواب نداد');
if (e.message.includes('Failed to fetch')) {
$('corsWarning').classList.add('show');
throw new Error('CORS یا خطای شبکه - نیاز به proxy');
}
throw e;
}
}
async function sendMessage(chatId, text) {
try {
const result = await apiCall('sendMessage', {
chat_id: String(chatId),
text: text
// parse_mode حذف شد تا مشکل Markdown حل بشه
});
bot.config.stats.responses++;
updateStats();
return true;
} catch (e) {
bot.config.stats.errors++;
updateStats();
addLog('error', '❌ ارسال: ' + e.message);
return false;
}
}
// ===== منطق ربات =====
async function startBot() {
const token = $('apiToken').value.trim();
const chatId = $('chatId').value.trim();
if (!token || !chatId) { addLog('error', '❌ توکن و شناسه گروه الزامی است'); return; }
bot.config.token = token;
bot.config.chatId = chatId;
bot.running = true;
bot.startTime = Date.now();
$('startBtn').style.display = 'none';
$('stopBtn').style.display = 'block';
updateStatus(true);
addLog('success', '🚀 ربات شروع شد');
try {
const me = await apiCall('getMe', {});
addLog('success', '✅ اتصال موفق');
} catch (e) {
addLog('error', '❌ اتصال: ' + e.message);
stopBot();
return;
}
saveConfig();
pollLoop();
bot.uptimeTimer = setInterval(() => {
if (bot.startTime) $('uptime').textContent = formatUptime(Date.now() - bot.startTime);
}, 1000);
}
function stopBot() {
bot.running = false;
if (bot.pollTimer) clearTimeout(bot.pollTimer);
if (bot.uptimeTimer) clearInterval(bot.uptimeTimer);
$('startBtn').style.display = 'block';
$('stopBtn').style.display = 'none';
updateStatus(false);
addLog('warning', '⏹️ ربات متوقف شد');
saveConfig();
}
async function pollLoop() {
if (!bot.running) return;
try {
await pollMessages();
} catch (e) {
bot.config.stats.errors++;
updateStats();
addLog('error', '❌ Poll: ' + e.message);
}
if (bot.running) bot.pollTimer = setTimeout(pollLoop, bot.config.pollInterval);
}
async function pollMessages() {
const data = await apiCall('getUpdates', {
offset: bot.config.lastUpdateId + 1,
limit: 100
});
const updates = data.result || [];
for (const update of updates) {
bot.config.lastUpdateId = update.update_id;
bot.config.stats.messages++;
updateStats();
if (update.message) await processMessage(update.message);
}
if (updates.length) saveConfig(); // ✅ ذخیره offset
}
async function processMessage(msg) {
const text = msg.text || msg.caption || '';
const chatId = msg.chat?.id;
const userName = msg.from?.first_name || msg.from?.username || 'کاربر';
if (!chatId) return;
addLog('info', `📨 ${userName}: ${text.substring(0, 50)}`);
// فیلتر
if (bot.config.features.filter && text && shouldFilter(text)) {
addLog('warning', '🚫 فیلتر: ' + userName);
try {
await apiCall('deleteMessage', { chat_id: String(chatId), message_id: msg.message_id });
await sendMessage(chatId, `⚠️ ${userName}، لطفاً کلمات مناسب استفاده کنید.`);
} catch (e) { addLog('error', 'حذف نشد: ' + e.message); }
return;
}
// دستورات
if (text.startsWith('/')) {
await processCommand(text, chatId, userName);
return;
}
// پاسخ خودکار
for (const [k, v] of Object.entries(bot.config.autoResponses)) {
if (text.includes(k)) {
await sendMessage(chatId, v);
addLog('success', '💬 خودکار: ' + k);
return;
}
}
// سلام
if (bot.config.features.greeting && /سلام|درود|hello|hi/i.test(text)) {
await sendMessage(chatId, bot.config.greetingResponse);
addLog('success', '🙏 پاسخ سلام');
}
}
async function processCommand(text, chatId, userName) {
// ✅ پشتیبانی از /command@botname
const parts = text.split(' ')[0].toLowerCase().split('@')[0];
const args = text.substring(text.indexOf(' ') + 1).trim();
switch (parts) {
case '/help': case '/start':
if (!bot.config.features.help) return;
await sendMessage(chatId, `🤖 دستورات ربات:
👋 /help - راهنما
🔍 /google [عبارت] - جستجو
🕐 /time - ساعت
💬 /quote - نقل قول
🏓 /ping - پینگ
📊 /info - آمار`);
break;
case '/google':
if (!bot.config.features.google) return;
if (!args) { await sendMessage(chatId, '❗ مثال: /google هوش مصنوعی'); return; }
await sendMessage(chatId, `🔍 جستجو: ${args}\n\n🔗 https://www.google.com/search?q=${encodeURIComponent(args)}`);
break;
case '/time':
if (!bot.config.features.time) return;
await sendMessage(chatId, '🕐 ' + new Date().toLocaleString('fa-IR'));
break;
case '/quote':
if (!bot.config.features.quote) return;
await sendMessage(chatId, QUOTES[Math.floor(Math.random() * QUOTES.length)]);
break;
case '/ping':
if (!bot.config.features.ping) return;
const t = Date.now();
await sendMessage(chatId, '🏓 پینگ...');
await sendMessage(chatId, `🏓 پنگ!\n⏱️ ${Date.now() - t}ms`);
break;
case '/info':
await sendMessage(chatId, `📊 آمار:
⏱️ فعالیت: ${formatUptime(Date.now() - (bot.startTime||Date.now()))}
📨 دریافتی: ${bot.config.stats.messages}
💬 پاسخ: ${bot.config.stats.responses}
❌ خطا: ${bot.config.stats.errors}`);
break;
}
}
function shouldFilter(text) {
const lower = text.toLowerCase();
return bot.config.bannedWords.some(w => lower.includes(w.toLowerCase()));
}
function formatUptime(ms) {
const s = Math.floor(ms / 1000);
const m = Math.floor(s / 60);
const h = Math.floor(m / 60);
if (h > 0) return `${h}h ${m%60}m`;
if (m > 0) return `${m}m ${s%60}s`;
return `${s}s`;
}
// ===== راه‌اندازی =====
window.addEventListener('load', () => {
loadConfig();
$('apiToken').value = bot.config.token || '';
$('chatId').value = bot.config.chatId || '';
$('pollInterval').value = bot.config.pollInterval;
$('welcomeMessage').value = bot.config.welcomeMessage;
$('greetingResponse').value = bot.config.greetingResponse;
renderFeatures();
renderBannedWords();
renderAutoResponses();
updateStats();
// تب‌ها - ✅ بدون event global
document.querySelectorAll('.tab-btn').forEach(btn => {
btn.addEventListener('click', () => switchTab(btn.dataset.tab, btn));
});
// Enter برای افزودن کلمات
$('newBannedWord').addEventListener('keypress', e => { if (e.key === 'Enter') addBannedWord(); });
$('newAutoResponse').addEventListener('keypress', e => { if (e.key === 'Enter') addAutoResponse(); });
$('newAutoKeyword').addEventListener('keypress', e => { if (e.key === 'Enter') $('newAutoResponse').focus(); });
addLog('info', '✅ سیستم آماده است');
});
// ✅ قبل از خروج فقط ذخیره، نه stop
window.addEventListener('beforeunload', saveConfig);
</script>
</body>
</html>