@memberjunction/actions-bizapps-social
Version:
Social Media Actions for MemberJunction - Twitter, LinkedIn, Facebook, Instagram, TikTok, YouTube, HootSuite, Buffer
391 lines • 15.3 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.InstagramGetAccountInsightsAction = void 0;
const global_1 = require("@memberjunction/global");
const instagram_base_action_1 = require("../instagram-base.action");
const core_1 = require("@memberjunction/core");
const actions_1 = require("@memberjunction/actions");
/**
* Retrieves account-level insights for an Instagram Business account.
* Includes follower demographics, reach, impressions, and profile activity.
*/
let InstagramGetAccountInsightsAction = class InstagramGetAccountInsightsAction extends instagram_base_action_1.InstagramBaseAction {
async InternalRunAction(params) {
try {
const companyIntegrationId = this.getParamValue(params.Params, 'CompanyIntegrationID');
const period = this.getParamValue(params.Params, 'Period') || 'day';
const startDate = this.getParamValue(params.Params, 'StartDate');
const endDate = this.getParamValue(params.Params, 'EndDate');
const includeDemographics = this.getParamValue(params.Params, 'IncludeDemographics') !== false;
// Initialize OAuth
if (!await this.initializeOAuth(companyIntegrationId)) {
return {
Success: false,
Message: 'Failed to initialize Instagram authentication',
ResultCode: 'AUTH_FAILED'
};
}
// Define metrics based on period
const metrics = this.getAccountMetrics(period);
// Get account insights
const insights = await this.getInsights(this.instagramBusinessAccountId, metrics, period);
// Parse insights data
const parsedInsights = this.parseAccountInsights(insights);
// Get account info
const accountInfo = await this.getAccountInfo();
// Get demographics if requested
let demographics = null;
if (includeDemographics) {
demographics = await this.getAccountDemographics();
}
// Get content performance summary
const contentSummary = await this.getContentPerformanceSummary(startDate, endDate);
// Calculate growth metrics
const growthMetrics = this.calculateGrowthMetrics(parsedInsights, accountInfo);
// Store result in output params
const outputParams = [...params.Params];
outputParams.push({
Name: 'ResultData',
Type: 'Output',
Value: JSON.stringify({
account: {
id: this.instagramBusinessAccountId,
username: accountInfo.username,
name: accountInfo.name,
biography: accountInfo.biography,
followersCount: accountInfo.followers_count,
followsCount: accountInfo.follows_count,
mediaCount: accountInfo.media_count,
profilePictureUrl: accountInfo.profile_picture_url,
websiteUrl: accountInfo.website
},
insights: parsedInsights,
demographics,
growth: growthMetrics,
contentPerformance: contentSummary,
period,
dataCollectedAt: new Date().toISOString()
})
});
return {
Success: true,
Message: 'Successfully retrieved Instagram account insights',
ResultCode: 'SUCCESS',
Params: outputParams
};
}
catch (error) {
(0, core_1.LogError)('Failed to retrieve Instagram account insights', error);
if (error.code === 'RATE_LIMIT') {
return {
Success: false,
Message: 'Instagram API rate limit exceeded. Please try again later.',
ResultCode: 'RATE_LIMIT'
};
}
if (error.code === 'INSUFFICIENT_PERMISSIONS') {
return {
Success: false,
Message: 'Insufficient permissions to access Instagram account insights',
ResultCode: 'INSUFFICIENT_PERMISSIONS'
};
}
return {
Success: false,
Message: `Failed to retrieve account insights: ${error.message}`,
ResultCode: 'ERROR'
};
}
}
/**
* Get appropriate metrics based on period
*/
getAccountMetrics(period) {
const baseMetrics = [
'impressions',
'reach',
'profile_views',
'website_clicks'
];
if (period === 'day') {
return [
...baseMetrics,
'follower_count',
'email_contacts',
'phone_call_clicks',
'text_message_clicks',
'get_directions_clicks'
];
}
else if (period === 'week' || period === 'days_28') {
return [
...baseMetrics,
'accounts_engaged'
];
}
return baseMetrics;
}
/**
* Get account information
*/
async getAccountInfo() {
const response = await this.makeInstagramRequest(this.instagramBusinessAccountId, 'GET', null, {
fields: 'username,name,biography,followers_count,follows_count,media_count,profile_picture_url,website',
access_token: this.getAccessToken()
});
return response;
}
/**
* Get account demographics
*/
async getAccountDemographics() {
try {
// Get follower demographics
const demographicMetrics = [
'audience_city',
'audience_country',
'audience_gender_age',
'audience_locale',
'online_followers'
];
const demographics = await this.getInsights(this.instagramBusinessAccountId, demographicMetrics, 'lifetime');
// Parse demographic data
const parsed = {
locations: {
cities: {},
countries: {}
},
genderAge: {},
languages: {},
onlineHours: {}
};
demographics.forEach((metric) => {
const value = metric.values?.[0]?.value;
switch (metric.name) {
case 'audience_city':
parsed.locations.cities = value || {};
break;
case 'audience_country':
parsed.locations.countries = value || {};
break;
case 'audience_gender_age':
parsed.genderAge = this.parseGenderAge(value || {});
break;
case 'audience_locale':
parsed.languages = value || {};
break;
case 'online_followers':
parsed.onlineHours = this.parseOnlineHours(value || {});
break;
}
});
return parsed;
}
catch (error) {
(0, core_1.LogError)('Failed to get demographics', error);
return null;
}
}
/**
* Parse gender/age demographics
*/
parseGenderAge(data) {
const parsed = {
male: {},
female: {},
unknown: {}
};
Object.keys(data).forEach(key => {
const [gender, ageRange] = key.split('.');
if (parsed[gender]) {
parsed[gender][ageRange] = data[key];
}
});
return parsed;
}
/**
* Parse online hours data
*/
parseOnlineHours(data) {
const parsed = {};
Object.keys(data).forEach(hour => {
parsed[hour] = {
count: data[hour],
hour: parseInt(hour),
label: `${hour}:00`
};
});
return parsed;
}
/**
* Get content performance summary
*/
async getContentPerformanceSummary(startDate, endDate) {
try {
// Get recent posts
const queryParams = {
fields: 'id,media_type,like_count,comments_count,timestamp',
access_token: this.getAccessToken(),
limit: 50
};
if (startDate) {
queryParams.since = Math.floor(new Date(startDate).getTime() / 1000);
}
if (endDate) {
queryParams.until = Math.floor(new Date(endDate).getTime() / 1000);
}
const response = await this.makeInstagramRequest(`${this.instagramBusinessAccountId}/media`, 'GET', null, queryParams);
const posts = response.data || [];
// Calculate performance metrics
const summary = {
totalPosts: posts.length,
avgLikes: 0,
avgComments: 0,
totalEngagements: 0,
topPerformingPost: null,
mediaTypeBreakdown: {
IMAGE: 0,
VIDEO: 0,
CAROUSEL_ALBUM: 0,
REELS: 0
}
};
if (posts.length > 0) {
let totalLikes = 0;
let totalComments = 0;
let topPost = posts[0];
posts.forEach(post => {
totalLikes += post.like_count || 0;
totalComments += post.comments_count || 0;
// Track media types
if (summary.mediaTypeBreakdown[post.media_type] !== undefined) {
summary.mediaTypeBreakdown[post.media_type]++;
}
// Find top performing post
const engagement = (post.like_count || 0) + (post.comments_count || 0);
const topEngagement = (topPost.like_count || 0) + (topPost.comments_count || 0);
if (engagement > topEngagement) {
topPost = post;
}
});
summary.avgLikes = Math.round(totalLikes / posts.length);
summary.avgComments = Math.round(totalComments / posts.length);
summary.totalEngagements = totalLikes + totalComments;
summary.topPerformingPost = {
id: topPost.id,
likes: topPost.like_count,
comments: topPost.comments_count,
engagement: (topPost.like_count || 0) + (topPost.comments_count || 0),
publishedAt: topPost.timestamp
};
}
return summary;
}
catch (error) {
(0, core_1.LogError)('Failed to get content performance', error);
return null;
}
}
/**
* Parse account insights
*/
parseAccountInsights(insights) {
const parsed = {};
insights.forEach(metric => {
const name = metric.name;
const values = metric.values || [];
if (values.length > 0) {
parsed[name] = {
value: values[0].value || 0,
title: metric.title,
description: metric.description,
period: metric.period
};
// For time series data
if (values.length > 1) {
parsed[name].timeSeries = values.map((v) => ({
value: v.value,
endTime: v.end_time
}));
}
}
});
return parsed;
}
/**
* Calculate growth metrics
*/
calculateGrowthMetrics(insights, accountInfo) {
const growth = {
followersGrowth: 0,
followersGrowthRate: 0,
reachGrowth: 0,
impressionsGrowth: 0,
engagementRate: 0
};
// Calculate follower growth if we have time series data
const followerData = insights.follower_count;
if (followerData?.timeSeries && followerData.timeSeries.length > 1) {
const firstValue = followerData.timeSeries[0].value;
const lastValue = followerData.timeSeries[followerData.timeSeries.length - 1].value;
growth.followersGrowth = lastValue - firstValue;
if (firstValue > 0) {
growth.followersGrowthRate = ((lastValue - firstValue) / firstValue) * 100;
}
}
// Calculate engagement rate
const reach = insights.reach?.value || 0;
const profileViews = insights.profile_views?.value || 0;
const websiteClicks = insights.website_clicks?.value || 0;
if (reach > 0) {
const totalEngagements = profileViews + websiteClicks;
growth.engagementRate = (totalEngagements / reach) * 100;
}
return growth;
}
/**
* Define the parameters for this action
*/
get Params() {
return [
...this.commonSocialParams,
{
Name: 'Period',
Type: 'Input',
Value: 'day'
},
{
Name: 'StartDate',
Type: 'Input',
Value: null
},
{
Name: 'EndDate',
Type: 'Input',
Value: null
},
{
Name: 'IncludeDemographics',
Type: 'Input',
Value: true
}
];
}
/**
* Get the description for this action
*/
get Description() {
return 'Retrieves comprehensive account-level insights including follower demographics, reach, impressions, and growth metrics.';
}
};
exports.InstagramGetAccountInsightsAction = InstagramGetAccountInsightsAction;
exports.InstagramGetAccountInsightsAction = InstagramGetAccountInsightsAction = __decorate([
(0, global_1.RegisterClass)(actions_1.BaseAction, 'Instagram - Get Account Insights')
], InstagramGetAccountInsightsAction);
//# sourceMappingURL=get-account-insights.action.js.map