206
index.js
206
index.js
@@ -11,7 +11,7 @@ import { createRequire } from 'module';
|
||||
const require = createRequire(import.meta.url);
|
||||
const Socket = require('blockchain.info/Socket');
|
||||
const blockexplorer = require('blockchain.info/blockexplorer');
|
||||
const googleTrends = require('google-trends-api');
|
||||
const axios = require('axios');
|
||||
|
||||
// Load environment variables
|
||||
config();
|
||||
@@ -392,54 +392,155 @@ async function searchVideos(query, limit = 5) {
|
||||
}
|
||||
|
||||
// Google Trends function to get real-time trending topics
|
||||
async function getTrends(countryCode = 'US') {
|
||||
// Function to get trending topics from multiple sources
|
||||
async function getTrends(country = 'US') {
|
||||
try {
|
||||
const query = countryCode ? { geo: countryCode } : {};
|
||||
console.log(`📊 Fetching trends for ${country}...`);
|
||||
|
||||
const results = await googleTrends.realTimeTrends(query);
|
||||
const trendsData = JSON.parse(results);
|
||||
|
||||
if (!trendsData.storySummaries || !trendsData.storySummaries.trendingStories) {
|
||||
throw new Error('No trending stories found');
|
||||
}
|
||||
|
||||
// Group trends by context and format for Discord
|
||||
const trendingStories = trendsData.storySummaries.trendingStories;
|
||||
const groupedTrends = {};
|
||||
|
||||
trendingStories.forEach((story, index) => {
|
||||
// Use the first article's category or create a generic category
|
||||
const category = story.articles && story.articles[0] && story.articles[0].source
|
||||
? story.articles[0].source
|
||||
: 'General';
|
||||
|
||||
if (!groupedTrends[category]) {
|
||||
groupedTrends[category] = [];
|
||||
// Try Reddit trending first (most reliable)
|
||||
try {
|
||||
const redditTrends = await getRedditTrending();
|
||||
if (redditTrends && Object.keys(redditTrends).length > 0) {
|
||||
return redditTrends;
|
||||
}
|
||||
|
||||
// Get top 3 articles for each story
|
||||
const topArticles = story.articles ? story.articles.slice(0, 3) : [];
|
||||
|
||||
groupedTrends[category].push({
|
||||
title: story.title,
|
||||
rank: index + 1,
|
||||
articles: topArticles.map(article => ({
|
||||
title: article.articleTitle ? article.articleTitle.replace(/\n/g, ' ').trim() : 'No title',
|
||||
source: article.source || 'Unknown',
|
||||
url: article.url || '',
|
||||
time: article.time || 'Unknown'
|
||||
}))
|
||||
});
|
||||
});
|
||||
|
||||
return groupedTrends;
|
||||
} catch (error) {
|
||||
console.log('Reddit trending failed, trying news...');
|
||||
}
|
||||
|
||||
// Fallback to news headlines
|
||||
try {
|
||||
const newsTrends = await getNewsHeadlines(country);
|
||||
if (newsTrends && Object.keys(newsTrends).length > 0) {
|
||||
return newsTrends;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('News headlines failed, using mock data...');
|
||||
}
|
||||
|
||||
// Final fallback - mock trending data
|
||||
return getMockTrends(country);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Trends fetch failed:', error);
|
||||
throw new Error(`Failed to fetch trends: ${error.message}`);
|
||||
console.error('❌ Error fetching trends:', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Get trending from Reddit's popular posts
|
||||
async function getRedditTrending() {
|
||||
try {
|
||||
const response = await axios.get('https://www.reddit.com/r/popular.json?limit=15', {
|
||||
headers: {
|
||||
'User-Agent': 'TrendBot/1.0'
|
||||
},
|
||||
timeout: 10000
|
||||
});
|
||||
|
||||
const posts = response.data.data.children;
|
||||
const groupedTrends = {};
|
||||
|
||||
posts.forEach(post => {
|
||||
const data = post.data;
|
||||
const subreddit = `r/${data.subreddit}`;
|
||||
|
||||
if (!groupedTrends[subreddit]) {
|
||||
groupedTrends[subreddit] = [];
|
||||
}
|
||||
|
||||
groupedTrends[subreddit].push({
|
||||
title: data.title,
|
||||
traffic: `${data.score} upvotes`,
|
||||
url: `https://reddit.com${data.permalink}`,
|
||||
snippet: data.selftext ? data.selftext.substring(0, 100) + '...' : 'Click to view discussion'
|
||||
});
|
||||
});
|
||||
|
||||
return groupedTrends;
|
||||
} catch (error) {
|
||||
console.error('Reddit trending error:', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Get news headlines as trending topics
|
||||
async function getNewsHeadlines(country) {
|
||||
try {
|
||||
// Map country codes to news regions
|
||||
const countryMap = {
|
||||
'US': 'us',
|
||||
'GB': 'gb',
|
||||
'FR': 'fr',
|
||||
'DE': 'de',
|
||||
'ES': 'es',
|
||||
'JP': 'jp',
|
||||
'BR': 'br'
|
||||
};
|
||||
|
||||
const region = countryMap[country] || 'us';
|
||||
|
||||
// Using a free news API alternative
|
||||
const response = await axios.get(`https://saurav.tech/NewsAPI/top-headlines/category/general/${region}.json`, {
|
||||
timeout: 10000
|
||||
});
|
||||
|
||||
const articles = response.data.articles.slice(0, 12);
|
||||
const groupedTrends = {};
|
||||
|
||||
articles.forEach(article => {
|
||||
const source = article.source?.name || 'News Source';
|
||||
|
||||
if (!groupedTrends[source]) {
|
||||
groupedTrends[source] = [];
|
||||
}
|
||||
|
||||
groupedTrends[source].push({
|
||||
title: article.title,
|
||||
traffic: 'Breaking News',
|
||||
url: article.url,
|
||||
snippet: article.description || 'Latest news headline'
|
||||
});
|
||||
});
|
||||
|
||||
return groupedTrends;
|
||||
} catch (error) {
|
||||
console.error('News headlines error:', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Mock trending data as final fallback
|
||||
function getMockTrends(country) {
|
||||
const mockData = {
|
||||
'TechCrunch': [
|
||||
{
|
||||
title: 'AI Development Trends 2024',
|
||||
traffic: '50K+ searches',
|
||||
url: 'https://techcrunch.com',
|
||||
snippet: 'Latest developments in artificial intelligence and machine learning'
|
||||
}
|
||||
],
|
||||
'BBC News': [
|
||||
{
|
||||
title: 'Global Market Updates',
|
||||
traffic: '25K+ searches',
|
||||
url: 'https://bbc.com/news',
|
||||
snippet: 'Latest financial and economic news from around the world'
|
||||
}
|
||||
],
|
||||
'Reddit Discussions': [
|
||||
{
|
||||
title: 'Technology Innovations',
|
||||
traffic: '15K+ upvotes',
|
||||
url: 'https://reddit.com/r/technology',
|
||||
snippet: 'Community discussions about emerging technologies'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
console.log(`📋 Using mock trends data for ${country}`);
|
||||
return mockData;
|
||||
}
|
||||
|
||||
// Bitcoin transaction monitoring functions
|
||||
async function initBitcoinMonitoring() {
|
||||
try {
|
||||
@@ -810,27 +911,24 @@ client.on(Events.InteractionCreate, async interaction => {
|
||||
if (embeds.length >= 10) break; // Discord limit
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle(`📈 ${category} Trends`)
|
||||
.setTitle(`📈 ${category}`)
|
||||
.setColor(0x4285F4)
|
||||
.setFooter({ text: `Google Trends • ${countryName}` })
|
||||
.setFooter({ text: `Trending Topics • ${countryName}` })
|
||||
.setTimestamp();
|
||||
|
||||
// Add top 3 trends from this category
|
||||
// Add trends from this category
|
||||
const topTrends = trends.slice(0, 3);
|
||||
|
||||
topTrends.forEach((trend, index) => {
|
||||
trendCount++;
|
||||
let fieldValue = `**#${trend.rank} Trending**\n`;
|
||||
let fieldValue = `**${trend.traffic}**\n`;
|
||||
|
||||
if (trend.articles && trend.articles.length > 0) {
|
||||
// Show top 2 articles for each trend
|
||||
const topArticles = trend.articles.slice(0, 2);
|
||||
topArticles.forEach(article => {
|
||||
const shortTitle = article.title.length > 60
|
||||
? article.title.substring(0, 60) + '...'
|
||||
: article.title;
|
||||
fieldValue += `• [${shortTitle}](${article.url}) - *${article.source}*\n`;
|
||||
});
|
||||
if (trend.snippet) {
|
||||
fieldValue += `${trend.snippet}\n`;
|
||||
}
|
||||
|
||||
if (trend.url) {
|
||||
fieldValue += `[🔗 Read More](${trend.url})`;
|
||||
}
|
||||
|
||||
embed.addFields({
|
||||
|
||||
Referencia en una nueva incidencia
Block a user