Aethel Bot OSS repository! aethel.xyz
bot fun ai discord discord-bot aethel

BRO BRO BRO

Changed files
+22 -44
src
+12 -11
src/routes/voteWebhook.ts
··· 7 7 router.all('/webhooks/topgg', async (req, res) => { 8 8 const authHeader = req.headers.authorization; 9 9 if (!authHeader || authHeader !== process.env.TOPGG_WEBHOOK_AUTH) { 10 - logger.warn('Unauthorized webhook attempt', { 10 + logger.warn('Unauthorized webhook attempt', { 11 11 ip: req.ip, 12 12 headers: req.headers, 13 - timestamp: new Date().toISOString() 13 + timestamp: new Date().toISOString(), 14 14 }); 15 15 return res.status(401).json({ error: 'Unauthorized' }); 16 16 } ··· 26 26 ip: req.ip, 27 27 method: req.method, 28 28 url: req.originalUrl, 29 - timestamp: new Date().toISOString() 29 + timestamp: new Date().toISOString(), 30 30 }); 31 31 32 32 const { user, type } = req.body; ··· 43 43 `Processed vote from user ${userId}. Credits awarded: ${result.creditsAwarded}`, 44 44 ); 45 45 return res.status(200).json({ success: true, message: 'Vote processed successfully' }); 46 - } 47 - logger.info(`Vote already processed for user ${userId}`, { nextVote: result.nextVoteAvailable }); 48 - return res.status(200).json({ 49 - success: false, 50 - message: 'Vote already processed', 51 - nextVote: result.nextVoteAvailable, 52 - }); 53 - 46 + } 47 + logger.info(`Vote already processed for user ${userId}`, { 48 + nextVote: result.nextVoteAvailable, 49 + }); 50 + return res.status(200).json({ 51 + success: false, 52 + message: 'Vote already processed', 53 + nextVote: result.nextVoteAvailable, 54 + }); 54 55 } 55 56 56 57 return res.status(400).json({ success: false, message: 'Invalid vote type' });
+9 -32
src/utils/topgg.ts
··· 1 - import fetch from 'node-fetch'; 2 - 3 - const TOPGG_API = 'https://top.gg/api'; 1 + const VOTE_COOLDOWN_HOURS = 12; 4 2 5 3 interface TopGGVote { 6 4 created_at: string; ··· 11 9 export async function checkVoteStatus( 12 10 userId: string, 13 11 ): Promise<{ hasVoted: boolean; nextVote: Date; voteCount: number }> { 14 - if (!process.env.TOPGG_TOKEN) { 15 - throw new Error('Top.gg token is not configured'); 16 - } 12 + const now = new Date(); 13 + const nextVote = new Date(now.getTime() + VOTE_COOLDOWN_HOURS * 60 * 60 * 1000); 17 14 18 - try { 19 - const response = await fetch(`${TOPGG_API}/v1/projects/@me/votes/${userId}`, { 20 - headers: { 21 - Authorization: process.env.TOPGG_TOKEN, 22 - 'Content-Type': 'application/json', 23 - }, 24 - }); 15 + console.log(`Vote recorded for user ${userId}. Next vote available at ${nextVote.toISOString()}`); 25 16 26 - if (!response.ok) { 27 - throw new Error(`Top.gg API error: ${response.statusText}`); 28 - } 29 - 30 - const responseData = await response.json(); 31 - console.log('Top.gg API Response:', JSON.stringify(responseData, null, 2)); 32 - 33 - const data = responseData as TopGGVote; 34 - const hasVoted = !!data?.created_at; 35 - 36 - return { 37 - hasVoted, 38 - nextVote: new Date(data.expires_at), 39 - voteCount: hasVoted ? data.weight : 0, 40 - }; 41 - } catch (error) { 42 - console.error('Error checking Top.gg vote status:', error); 43 - throw new Error('Failed to verify vote status. Please try again later.'); 44 - } 17 + return { 18 + hasVoted: true, 19 + nextVote, 20 + voteCount: 1, 21 + }; 45 22 } 46 23 47 24 export function getVoteLink(): string {
+1 -1
src/utils/voteManager.ts
··· 123 123 if (existingVote.rows.length > 0) { 124 124 const lastVoteTime = new Date(existingVote.rows[0].vote_timestamp).getTime(); 125 125 const cooldownEnd = lastVoteTime + VOTE_COOLDOWN_HOURS * 60 * 60 * 1000; 126 - 126 + 127 127 if (Date.now() < cooldownEnd) { 128 128 return { 129 129 success: false,