getHashtagTrends
Analyze hashtag performance and trends over specified timeframes to track engagement patterns and identify trending topics on Twitter.
Instructions
Analyze hashtag trends and performance over time
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| hashtag | Yes | Hashtag to analyze (with or without #) | |
| timeframe | No | Analysis timeframe (default: "daily") | |
| period | No | Number of periods to analyze (default: 7) |
Implementation Reference
- Main handler implementation for getHashtagTrends tool. Searches recent tweets for the hashtag, groups them by specified timeframe (hourly/daily/weekly), calculates engagement metrics per period, identifies peaks and trends, and provides content insights.export const handleGetHashtagTrends: SocialDataHandler<HashtagTrendsArgs> = async ( _client: any, { hashtag, timeframe = 'daily', period = 7 }: HashtagTrendsArgs ) => { try { const socialClient = getSocialDataClient(); if (!socialClient) { return createMissingApiKeyResponse('Hashtag Trends Analysis'); } // Clean hashtag const cleanHashtag = hashtag.replace(/^#/, ''); const searchQuery = `#${cleanHashtag}`; // Get recent tweets with the hashtag const result = await socialClient.searchTweets({ query: searchQuery, maxResults: 100 }); const tweets = result.data || []; if (tweets.length === 0) { return createSocialDataResponse(`No recent data found for hashtag #${cleanHashtag}`); } // Group tweets by time periods const now = new Date(); const timeGroups = new Map(); tweets.forEach((tweet: any) => { const tweetDate = new Date(tweet.tweet_created_at); let groupKey: string; if (timeframe === 'hourly') { groupKey = tweetDate.toISOString().substring(0, 13); // YYYY-MM-DDTHH } else if (timeframe === 'daily') { groupKey = tweetDate.toISOString().substring(0, 10); // YYYY-MM-DD } else { const weekStart = new Date(tweetDate); weekStart.setDate(tweetDate.getDate() - tweetDate.getDay()); groupKey = weekStart.toISOString().substring(0, 10); } if (!timeGroups.has(groupKey)) { timeGroups.set(groupKey, []); } timeGroups.get(groupKey).push(tweet); }); // Calculate trend metrics const trendData = Array.from(timeGroups.entries()) .map(([period, periodTweets]: [string, any[]]) => { const totalEngagement = periodTweets.reduce((sum, tweet) => sum + (tweet.favorite_count || 0) + (tweet.retweet_count || 0), 0); return { period, tweet_count: periodTweets.length, total_engagement: totalEngagement, avg_engagement: Math.round(totalEngagement / periodTweets.length), top_tweet: periodTweets.sort((a, b) => ((b.favorite_count || 0) + (b.retweet_count || 0)) - ((a.favorite_count || 0) + (a.retweet_count || 0)) )[0] }; }) .sort((a, b) => a.period.localeCompare(b.period)); const trends = { hashtag: `#${cleanHashtag}`, timeframe, period_analyzed: period, total_tweets: tweets.length, trend_data: trendData, trend_analysis: { peak_period: trendData.reduce((max, current) => current.tweet_count > max.tweet_count ? current : max), trending_direction: trendData.length > 1 ? (trendData[trendData.length - 1].tweet_count > trendData[0].tweet_count ? 'Rising' : 'Declining') : 'Stable', engagement_trend: trendData.length > 1 ? (trendData[trendData.length - 1].avg_engagement > trendData[0].avg_engagement ? 'Increasing' : 'Decreasing') : 'Stable' }, content_insights: { most_engaging_tweet: { text: tweets.sort((a: any, b: any) => ((b.favorite_count || 0) + (b.retweet_count || 0)) - ((a.favorite_count || 0) + (a.retweet_count || 0)) )[0]?.text?.substring(0, 200), engagement: ((tweets[0]?.favorite_count || 0) + (tweets[0]?.retweet_count || 0)) }, avg_tweet_length: Math.round(tweets.reduce((sum: number, tweet: any) => sum + (tweet.text?.length || 0), 0) / tweets.length) } }; return createSocialDataResponse( formatAnalytics(trends, `Hashtag Trends Analysis: #${cleanHashtag}`) ); } catch (error) { throw new Error(formatSocialDataError(error as Error, 'hashtag trends analysis')); } };
- TypeScript interface defining input arguments for the handleGetHashtagTrends handler.interface HashtagTrendsArgs { hashtag: string; timeframe: 'hourly' | 'daily' | 'weekly'; period?: number; }
- src/socialdata-tools.ts:318-341 (schema)MCP tool schema definition for getHashtagTrends, including input schema with properties matching the handler args.getHashtagTrends: { description: 'Analyze hashtag trends and performance over time', inputSchema: { type: 'object', properties: { hashtag: { type: 'string', description: 'Hashtag to analyze (with or without #)' }, timeframe: { type: 'string', enum: ['hourly', 'daily', 'weekly'], description: 'Analysis timeframe (default: "daily")' }, period: { type: 'number', description: 'Number of periods to analyze (default: 7)', minimum: 1, maximum: 30 } }, required: ['hashtag'] } },
- src/index.ts:489-492 (registration)Tool dispatch/registration in the main MCP server request handler switch statement, calling the handler function.case 'getHashtagTrends': { const args = request.params.arguments as any; response = await handleGetHashtagTrends(client, args); break;
- src/index.ts:80-82 (registration)Import statement bringing in the handleGetHashtagTrends handler for use in the MCP server.handleGetHashtagTrends, handleAnalyzeSentiment, handleTrackVirality