Instagram Collector
by @adarshvmore
Collects Instagram profile stats including followers, posts, engagement rate, posting frequency, avg likes/comments, and top hashtags via Apify scraper.
clawhub install instagram-collectorπ About This Skill
Instagram Collector Skill
Purpose
Collects Instagram profile data for a given handle using the Apify Instagram Profile Scraper. Extracts follower count, engagement metrics, posting frequency, and top hashtags. This collector feeds into the Marketing Audit Pipeline to populate the Instagram Performance section of the final report.Input Schema
// Function signature
collectInstagram(handle: string): Promise// The handle parameter is the Instagram username without the @ symbol.
// Example: "gymshark" (not "@gymshark")
Output Schema
interface InstagramData {
followers: number;
posts: number;
engagementRate: number; // Calculated: (avgLikes + avgComments) / followers * 100
postingFrequency: string; // e.g. "1.2 posts/day", "3 posts/week", "unknown"
avgLikes: number;
avgComments: number;
topHashtags: string[]; // Up to 10 most-used hashtags from recent posts
error?: string; // Present only when collector fails
}
API Dependencies
apify~instagram-profile-scraperhttps://api.apify.com/v2/acts/apify~instagram-profile-scraper/runsAPIFY_API_TOKEN environment variableImplementation Pattern
Data Flow
1. Receivehandle string from the pipeline
2. Call apifyService.scrapeInstagramProfile(handle) which starts an Apify actor run
3. Apify runs asynchronously -- the service polls for completion (timeout: 60s)
4. Fetch the actor's dataset results once complete
5. Map the raw Apify response to the InstagramData interfaceEngagement Rate Calculation
engagementRate = ((avgLikes + avgComments) / followers) * 100;
followers is 0, set engagementRate to 0 to avoid division by zeroPosting Frequency Calculation
"X.X posts/day"
- < 1 post/day but >= 1/week: "X posts/week"
- < 1 post/week: "X posts/month"
- If no timestamp data available: "unknown"Top Hashtags Extraction
#hashtag tokens using regex: /#(\w+)/gApify Response Mapping
Key fields from Apify's raw output:followersCount -> followerspostsCount -> postslatestPosts[].likesCount -> used for avgLikeslatestPosts[].commentsCount -> used for avgCommentslatestPosts[].caption -> used for hashtag extractionlatestPosts[].timestamp -> used for posting frequencyError Handling
try/catchEMPTY_INSTAGRAM_DATA with error field set: return { ...EMPTY_INSTAGRAM_DATA, error: 'Instagram data unavailable: ' };
InstagramData object logger.error('Instagram collector failed', { handle, err });
Example Usage
import { collectInstagram } from '../collectors/instagramCollector';// Successful collection
const data = await collectInstagram('gymshark');
// Returns:
// {
// followers: 6800000,
// posts: 4520,
// engagementRate: 1.85,
// postingFrequency: "1.3 posts/day",
// avgLikes: 120000,
// avgComments: 5800,
// topHashtags: ["gymshark", "fitness", "gym", "workout", "fitnessmotivation", ...],
// }
// Failed collection (graceful degradation)
const failedData = await collectInstagram('nonexistent_handle_12345');
// Returns:
// {
// followers: 0,
// posts: 0,
// engagementRate: 0,
// postingFrequency: "unknown",
// avgLikes: 0,
// avgComments: 0,
// topHashtags: [],
// error: "Instagram data unavailable: Profile not found"
// }
Notes
apifyService.ts for the actual API communication. The collector handles only data mapping and calculations.apifyService.scrapeInstagramProfile to return fixture data.EMPTY_INSTAGRAM_DATA constant is defined in src/types/audit.types.ts and should be imported for fallback returns.π Tips & Best Practices
apifyService.ts for the actual API communication. The collector handles only data mapping and calculations.apifyService.scrapeInstagramProfile to return fixture data.EMPTY_INSTAGRAM_DATA constant is defined in src/types/audit.types.ts and should be imported for fallback returns.