tes-wc-bot
Version:
š Advanced Telegram Bot for Cloudflare Wildcard Domain Management with Telegram Notifications
366 lines (321 loc) ⢠13.7 kB
JavaScript
const { readConfig } = require('../utils/fileUtils');
const { readCustomSubdomains, writeCustomSubdomains } = require('../utils/fileUtils');
const { isValidSubdomain, getAllSubdomains, isDomainExists } = require('../utils/validation');
const { LIMITS, DEFAULT_SUBDOMAINS } = require('../config/constants');
const { ADMIN_IDS } = require('../config/default');
/**
* Check if user is admin/owner
*/
function isOwner(userId) {
return ADMIN_IDS.includes(Number(userId));
}
/**
* Handler untuk command /new
* Menambah custom subdomain baru
*/
async function handleNew(ctx) {
const userId = String(ctx.from.id);
const configData = readConfig();
if (!configData[userId]) {
return ctx.reply(
'ā ļø *Anda belum terdaftar!*\n\n' +
'š Silakan daftar terlebih dahulu dengan:\n' +
'`/addcf <global_api_key> <email>`\n\n' +
'š” Setelah terdaftar, Anda bisa menambahkan custom domain wildcard.',
{ parse_mode: 'Markdown' }
);
}
const newDomain = ctx.message.text.replace('/new', '').trim().toLowerCase();
if (!newDomain) {
return ctx.reply(
'ā *Format tidak valid!*\n\n' +
'š Format: `/new <domain>`\n' +
'š Contoh: `/new api.example.com`\n\n' +
'š” *Tips:*\n' +
'⢠Gunakan domain yang valid\n' +
'⢠Hindari kata-kata terlarang\n' +
'⢠Maksimal 63 karakter',
{ parse_mode: 'Markdown' }
);
}
try {
// Validasi domain
const validation = isValidSubdomain(newDomain);
if (!validation.valid) {
return ctx.reply(`ā ${validation.message}`);
}
// Cek apakah sudah ada
if (isDomainExists(newDomain, userId)) {
return ctx.reply(
'ā ļø *Domain sudah ada!*\n\n' +
`š Domain \`${newDomain}\` sudah ada dalam daftar Anda.\n` +
'š Gunakan /listdomain untuk melihat semua domain.\n' +
'š Gunakan /searchdomain untuk mencari domain tertentu.',
{ parse_mode: 'Markdown' }
);
}
// Cek limit
const customSubdomains = readCustomSubdomains();
if (!customSubdomains[userId]) {
customSubdomains[userId] = [];
}
if (customSubdomains[userId].length >= LIMITS.MAX_CUSTOM_SUBDOMAINS) {
return ctx.reply(
'ā ļø *Batas maksimal tercapai!*\n\n' +
`š Anda telah mencapai batas maksimal custom domain (${LIMITS.MAX_CUSTOM_SUBDOMAINS}).\n` +
'šļø Hapus beberapa domain dengan /delsub untuk menambah yang baru.\n' +
'š Lihat domain Anda dengan /mysub',
{ parse_mode: 'Markdown' }
);
}
// Tambahkan domain
customSubdomains[userId].push(newDomain);
if (!writeCustomSubdomains(customSubdomains)) {
throw new Error('Gagal menyimpan data domain');
}
await ctx.reply(
'ā
*Berhasil menambahkan domain wildcard!*\n\n' +
`š **Domain:** \`${newDomain}\`\n` +
`š¤ **User:** \`${userId}\`\n` +
`š **Total domain Anda:** ${customSubdomains[userId].length}/${LIMITS.MAX_CUSTOM_SUBDOMAINS}\n\n` +
'š Domain telah ditambahkan ke daftar custom wildcard.\n' +
'š Gunakan /setupwildcard untuk mengonfigurasi domain utama.',
{ parse_mode: 'Markdown' }
);
} catch (error) {
console.error('ā Error adding new domain:', error);
await ctx.reply(
'ā *Gagal menambahkan domain*\n\n' +
`š Error: ${error.message}\n\n` +
'š” Silakan coba lagi dalam beberapa menit.'
);
}
}
/**
* Handler untuk command /listdomain
* Menampilkan semua domain yang tersedia
*/
async function handleListDomain(ctx) {
const userId = String(ctx.from.id);
const allSubdomains = getAllSubdomains(userId);
const customSubdomains = readCustomSubdomains()[userId] || [];
const domainList =
'š **DAFTAR DOMAIN TERSEDIA**\n\n' +
'š **Statistik:**\n' +
`⢠Total domain: ${allSubdomains.length}\n` +
`⢠Default domain: ${DEFAULT_SUBDOMAINS.length}\n` +
`⢠Custom domain: ${customSubdomains.length}\n\n` +
(DEFAULT_SUBDOMAINS.length > 0
? `š **Default Domain Wildcard:**\n${DEFAULT_SUBDOMAINS.map(
(domain, index) => `${index + 1}. ${domain}`
).join('\n')}\n\n`
: '') +
(customSubdomains.length > 0
? `šÆ **Custom Domain Wildcard:**\n${customSubdomains
.map(
(domain, index) =>
`${index + 1}. ${domain} ${userId === ctx.from.id ? '(Milik Anda)' : ''}`
)
.join('\n')}\n\n`
: '') +
'ā” **Quick Actions:**\n' +
'⢠`/new <subdomain.domain>` - Tambah custom domain Wildcard\n' +
'⢠`/mysub` - Lihat subdomain Wildcard Anda\n' +
'⢠`/setupwildcard <domain>` - Setup wildcard';
await ctx.reply(domainList, { parse_mode: 'Markdown' });
}
/**
* Handler untuk command /searchdomain
* Mencari domain berdasarkan keyword
*/
async function handleSearchDomain(ctx) {
const userId = String(ctx.from.id);
const query = ctx.message.text.replace('/searchdomain', '').trim().toLowerCase();
if (!query) {
return ctx.reply(
'ā *Format tidak valid!*\n\n' +
'š Format: `/searchdomain <keyword>`\n' +
'š Contoh: `/searchdomain zoom`\n\n' +
'š” Masukkan kata kunci untuk mencari domain yang tersedia.',
{ parse_mode: 'Markdown' }
);
}
try {
// Get default domains from config
const config = global.BOT_CONFIG || require('../config/default');
const defaultDomains = config.DEFAULT_DOMAINS || [
'support.zoom.us',
'discord.com',
'telegram.org',
'whatsapp.com',
'facebook.com',
'instagram.com',
'twitter.com',
'linkedin.com',
'github.com',
'stackoverflow.com',
];
// Search in custom domains
const customSubdomains = readCustomSubdomains();
const allCustomDomains = Object.values(customSubdomains).flat();
// Filter results
const defaultResults = defaultDomains.filter((domain) =>
domain.toLowerCase().includes(query)
);
const customResults = allCustomDomains.filter((domain) =>
domain.toLowerCase().includes(query)
);
const results = [...defaultResults, ...customResults];
if (results.length === 0) {
return ctx.reply(
'š *Hasil Pencarian*\n\n' +
`š Kata kunci: "${query}"\n` +
'ā Tidak ditemukan domain yang cocok\n\n' +
'š” *Saran:*\n' +
'⢠Coba kata kunci yang berbeda\n' +
'⢠Gunakan `/listdomain` untuk melihat semua domain\n' +
'⢠Gunakan `/new` untuk menambah domain baru',
{ parse_mode: 'Markdown' }
);
}
let searchResult = 'š *Hasil Pencarian*\n\n';
searchResult += `š Kata kunci: "${query}"\n`;
searchResult += `š Ditemukan: ${results.length} domain\n\n`;
if (defaultResults.length > 0) {
searchResult += `š *Default Domain (${defaultResults.length}):*\n`;
defaultResults.forEach((domain, index) => {
searchResult += `${index + 1}. \`${domain}\`\n`;
});
}
if (customResults.length > 0) {
searchResult += `\nš° *Custom Domain (${customResults.length}):*\n`;
customResults.forEach((domain, index) => {
searchResult += `${index + 1}. \`${domain}\`\n`;
});
}
searchResult += '\nš” Gunakan `/setupwildcard <domain>` untuk konfigurasi.';
await ctx.reply(searchResult, { parse_mode: 'Markdown' });
} catch (error) {
console.error('ā Error searching domains:', error);
await ctx.reply(
'ā *Terjadi kesalahan saat mencari domain*\n\n' +
'Silakan coba lagi dalam beberapa menit.',
{ parse_mode: 'Markdown' }
);
}
}
/**
* Handler untuk command /delsub
* Menghapus custom subdomain milik user sendiri
*/
async function handleDelSub(ctx) {
const userId = String(ctx.from.id);
const configData = readConfig();
if (!configData[userId]) {
return ctx.reply(
'ā ļø *Anda belum terdaftar!*\n\n' +
'š Silakan daftar terlebih dahulu dengan:\n' +
'`/addcf <global_api_key> <email>`\n\n' +
'š” Setelah terdaftar, Anda bisa mengelola custom domain Wildcard.',
{ parse_mode: 'Markdown' }
);
}
const domainToDelete = ctx.message.text.replace('/delsub', '').trim().toLowerCase();
if (!domainToDelete) {
return ctx.reply(
'ā *Format tidak valid!*\n\n' +
'š Format: `/delsub <domain>`\n' +
'š Contoh: `/delsub api.example.com`\n\n' +
'ā ļø Hanya custom domain Wildcard milik Anda yang bisa dihapus.',
{ parse_mode: 'Markdown' }
);
}
try {
const customSubdomains = readCustomSubdomains();
const mySubdomains = customSubdomains[userId] || [];
if (!mySubdomains.includes(domainToDelete)) {
return ctx.reply(
'ā *Domain Wildcard tidak ditemukan!*\n\n' +
`š Domain "\`${domainToDelete}\`" tidak ada dalam daftar custom domain Wildcard Anda.\n\n` +
'š” *Tips:*\n' +
'⢠Pastikan ejaan domain Wildcard benar\n' +
'⢠Hanya domain Wildcard milik Anda yang bisa dihapus\n' +
'⢠Gunakan /mysub untuk melihat domain Wildcard Anda',
{ parse_mode: 'Markdown' }
);
}
// Hapus domain dari list user
customSubdomains[userId] = mySubdomains.filter((d) => d !== domainToDelete);
// Jika user tidak punya domain lagi, hapus entrynya
if (customSubdomains[userId].length === 0) {
delete customSubdomains[userId];
}
if (!writeCustomSubdomains(customSubdomains)) {
throw new Error('Gagal menyimpan perubahan');
}
const remainingDomains = customSubdomains[userId] ? customSubdomains[userId].length : 0;
await ctx.reply(
'ā
*Berhasil menghapus domain Wildcard!*\n\n' +
`šļø **Domain Wildcard:** \`${domainToDelete}\`\n` +
`š **Sisa domain Wildcard Anda:** ${remainingDomains}/${LIMITS.MAX_CUSTOM_SUBDOMAINS}\n\n` +
'š” *Tips:*\n' +
'⢠Gunakan /new untuk menambah domain Wildcard baru\n' +
'⢠Gunakan /mysub untuk melihat domain Wildcard Anda\n' +
'⢠Domain yang dihapus tidak bisa dikembalikan',
{ parse_mode: 'Markdown' }
);
} catch (error) {
console.error('ā Error deleting domain:', error);
await ctx.reply(
'ā *Gagal menghapus domain*\n\n' +
`š Error: ${error.message}\n\n` +
'š” Silakan coba lagi dalam beberapa menit.',
{ parse_mode: 'Markdown' }
);
}
}
/**
* Handler untuk command /mysub
* Menampilkan custom subdomain milik user
*/
async function handleMySub(ctx) {
const userId = String(ctx.from.id);
const customSubdomains = readCustomSubdomains();
const mySubdomains = customSubdomains[userId] || [];
if (mySubdomains.length === 0) {
return ctx.reply(
'š **SUBDOMAIN ANDA**\n\n' +
'ā Anda belum memiliki custom subdomain Wildcard\n\n' +
'š” **Cara menambahkan:**\n' +
'⢠Gunakan `/new <subdomain.domain>`\n' +
'⢠Contoh: `/new app.example.com`\n\n' +
'š Gunakan `/listdomain` untuk melihat domain Wildcard tersedia',
{ parse_mode: 'Markdown' }
);
}
const subdomainList =
'š¤ **SUBDOMAIN ANDA**\n\n' +
`š **Total:** ${mySubdomains.length}/${LIMITS.MAX_CUSTOM_SUBDOMAINS}\n\n` +
'šÆ **Daftar subdomain:**\n' +
mySubdomains.map((domain, index) => `${index + 1}. ${domain}`).join('\n') +
'\n\n' +
'ā” **Quick Actions:**\n' +
'⢠`/new <subdomain.domain>` - Tambah subdomain Wildcard\n' +
'⢠`/delsub <subdomain.domain>` - Hapus subdomain Wildcard\n' +
'⢠`/searchdomain <keyword>` - Cari domain Wildcard';
await ctx.reply(subdomainList, { parse_mode: 'Markdown' });
}
module.exports = {
// Handler functions
handleNew,
handleListDomain,
handleSearchDomain,
handleDelSub,
handleMySub,
// Aliases for WildcardBot.js compatibility
addCustomDomain: handleNew,
listDomains: handleListDomain,
mySubdomains: handleMySub,
domainAnalytics: handleSearchDomain, // Using search as analytics for now
clearCache: (ctx) => ctx.reply('š Cache cleared successfully!'), // Simple implementation
};