@memberjunction/actions-bizapps-social 2.111.0 → 2.112.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +6 -6
- package/dist/base/base-social.action.d.ts.map +1 -1
- package/dist/base/base-social.action.js +18 -24
- package/dist/base/base-social.action.js.map +1 -1
- package/dist/providers/buffer/buffer-base.action.d.ts.map +1 -1
- package/dist/providers/buffer/buffer-base.action.js +35 -34
- package/dist/providers/buffer/buffer-base.action.js.map +1 -1
- package/dist/providers/facebook/actions/boost-post.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/boost-post.action.js +33 -33
- package/dist/providers/facebook/actions/boost-post.action.js.map +1 -1
- package/dist/providers/facebook/actions/create-album.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/create-album.action.js +34 -36
- package/dist/providers/facebook/actions/create-album.action.js.map +1 -1
- package/dist/providers/facebook/actions/create-post.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/create-post.action.js +20 -20
- package/dist/providers/facebook/actions/create-post.action.js.map +1 -1
- package/dist/providers/facebook/actions/get-page-insights.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/get-page-insights.action.js +25 -27
- package/dist/providers/facebook/actions/get-page-insights.action.js.map +1 -1
- package/dist/providers/facebook/actions/get-page-posts.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/get-page-posts.action.js +19 -23
- package/dist/providers/facebook/actions/get-page-posts.action.js.map +1 -1
- package/dist/providers/facebook/actions/get-post-insights.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/get-post-insights.action.js +28 -32
- package/dist/providers/facebook/actions/get-post-insights.action.js.map +1 -1
- package/dist/providers/facebook/actions/respond-to-comments.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/respond-to-comments.action.js +42 -44
- package/dist/providers/facebook/actions/respond-to-comments.action.js.map +1 -1
- package/dist/providers/facebook/actions/schedule-post.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/schedule-post.action.js +29 -29
- package/dist/providers/facebook/actions/schedule-post.action.js.map +1 -1
- package/dist/providers/facebook/actions/search-posts.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/search-posts.action.js +37 -39
- package/dist/providers/facebook/actions/search-posts.action.js.map +1 -1
- package/dist/providers/facebook/facebook-base.action.d.ts.map +1 -1
- package/dist/providers/facebook/facebook-base.action.js +44 -59
- package/dist/providers/facebook/facebook-base.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.js +33 -31
- package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/create-scheduled-post.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/create-scheduled-post.action.js +28 -32
- package/dist/providers/hootsuite/actions/create-scheduled-post.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/delete-scheduled-post.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/delete-scheduled-post.action.js +19 -19
- package/dist/providers/hootsuite/actions/delete-scheduled-post.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/get-analytics.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/get-analytics.action.js +24 -26
- package/dist/providers/hootsuite/actions/get-analytics.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/get-scheduled-posts.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/get-scheduled-posts.action.js +22 -22
- package/dist/providers/hootsuite/actions/get-scheduled-posts.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/get-social-profiles.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/get-social-profiles.action.js +32 -34
- package/dist/providers/hootsuite/actions/get-social-profiles.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/search-posts.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/search-posts.action.js +43 -52
- package/dist/providers/hootsuite/actions/search-posts.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/update-scheduled-post.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/update-scheduled-post.action.js +30 -28
- package/dist/providers/hootsuite/actions/update-scheduled-post.action.js.map +1 -1
- package/dist/providers/hootsuite/hootsuite-base.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/hootsuite-base.action.js +18 -20
- package/dist/providers/hootsuite/hootsuite-base.action.js.map +1 -1
- package/dist/providers/instagram/actions/create-post.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/create-post.action.js +27 -26
- package/dist/providers/instagram/actions/create-post.action.js.map +1 -1
- package/dist/providers/instagram/actions/create-story.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/create-story.action.js +35 -35
- package/dist/providers/instagram/actions/create-story.action.js.map +1 -1
- package/dist/providers/instagram/actions/get-account-insights.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/get-account-insights.action.js +38 -59
- package/dist/providers/instagram/actions/get-account-insights.action.js.map +1 -1
- package/dist/providers/instagram/actions/get-business-posts.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/get-business-posts.action.js +29 -29
- package/dist/providers/instagram/actions/get-business-posts.action.js.map +1 -1
- package/dist/providers/instagram/actions/get-comments.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/get-comments.action.js +36 -36
- package/dist/providers/instagram/actions/get-comments.action.js.map +1 -1
- package/dist/providers/instagram/actions/get-post-insights.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/get-post-insights.action.js +23 -25
- package/dist/providers/instagram/actions/get-post-insights.action.js.map +1 -1
- package/dist/providers/instagram/actions/schedule-post.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/schedule-post.action.js +25 -25
- package/dist/providers/instagram/actions/schedule-post.action.js.map +1 -1
- package/dist/providers/instagram/actions/search-posts.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/search-posts.action.js +56 -60
- package/dist/providers/instagram/actions/search-posts.action.js.map +1 -1
- package/dist/providers/instagram/instagram-base.action.d.ts.map +1 -1
- package/dist/providers/instagram/instagram-base.action.js +25 -27
- package/dist/providers/instagram/instagram-base.action.js.map +1 -1
- package/dist/providers/linkedin/actions/create-article.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/create-article.action.js +55 -45
- package/dist/providers/linkedin/actions/create-article.action.js.map +1 -1
- package/dist/providers/linkedin/actions/create-post.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/create-post.action.js +31 -29
- package/dist/providers/linkedin/actions/create-post.action.js.map +1 -1
- package/dist/providers/linkedin/actions/get-followers.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/get-followers.action.js +28 -28
- package/dist/providers/linkedin/actions/get-followers.action.js.map +1 -1
- package/dist/providers/linkedin/actions/get-organization-posts.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/get-organization-posts.action.js +20 -20
- package/dist/providers/linkedin/actions/get-organization-posts.action.js.map +1 -1
- package/dist/providers/linkedin/actions/get-personal-posts.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/get-personal-posts.action.js +19 -19
- package/dist/providers/linkedin/actions/get-personal-posts.action.js.map +1 -1
- package/dist/providers/linkedin/actions/get-post-analytics.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/get-post-analytics.action.js +25 -23
- package/dist/providers/linkedin/actions/get-post-analytics.action.js.map +1 -1
- package/dist/providers/linkedin/actions/schedule-post.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/schedule-post.action.js +32 -30
- package/dist/providers/linkedin/actions/schedule-post.action.js.map +1 -1
- package/dist/providers/linkedin/actions/search-posts.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/search-posts.action.js +28 -30
- package/dist/providers/linkedin/actions/search-posts.action.js.map +1 -1
- package/dist/providers/linkedin/linkedin-base.action.d.ts.map +1 -1
- package/dist/providers/linkedin/linkedin-base.action.js +33 -38
- package/dist/providers/linkedin/linkedin-base.action.js.map +1 -1
- package/dist/providers/tiktok/tiktok-base.action.d.ts.map +1 -1
- package/dist/providers/tiktok/tiktok-base.action.js +25 -26
- package/dist/providers/tiktok/tiktok-base.action.js.map +1 -1
- package/dist/providers/twitter/actions/create-thread.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/create-thread.action.js +25 -29
- package/dist/providers/twitter/actions/create-thread.action.js.map +1 -1
- package/dist/providers/twitter/actions/create-tweet.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/create-tweet.action.js +23 -23
- package/dist/providers/twitter/actions/create-tweet.action.js.map +1 -1
- package/dist/providers/twitter/actions/delete-tweet.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/delete-tweet.action.js +19 -19
- package/dist/providers/twitter/actions/delete-tweet.action.js.map +1 -1
- package/dist/providers/twitter/actions/get-analytics.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/get-analytics.action.js +40 -47
- package/dist/providers/twitter/actions/get-analytics.action.js.map +1 -1
- package/dist/providers/twitter/actions/get-mentions.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/get-mentions.action.js +30 -31
- package/dist/providers/twitter/actions/get-mentions.action.js.map +1 -1
- package/dist/providers/twitter/actions/get-timeline.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/get-timeline.action.js +29 -29
- package/dist/providers/twitter/actions/get-timeline.action.js.map +1 -1
- package/dist/providers/twitter/actions/schedule-tweet.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/schedule-tweet.action.js +26 -26
- package/dist/providers/twitter/actions/schedule-tweet.action.js.map +1 -1
- package/dist/providers/twitter/actions/search-tweets.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/search-tweets.action.js +56 -58
- package/dist/providers/twitter/actions/search-tweets.action.js.map +1 -1
- package/dist/providers/twitter/twitter-base.action.d.ts.map +1 -1
- package/dist/providers/twitter/twitter-base.action.js +58 -68
- package/dist/providers/twitter/twitter-base.action.js.map +1 -1
- package/dist/providers/youtube/youtube-base.action.d.ts +1 -1
- package/dist/providers/youtube/youtube-base.action.d.ts.map +1 -1
- package/dist/providers/youtube/youtube-base.action.js +22 -25
- package/dist/providers/youtube/youtube-base.action.js.map +1 -1
- package/package.json +5 -6
- package/src/base/base-social.action.ts +217 -224
- package/src/providers/buffer/buffer-base.action.ts +435 -441
- package/src/providers/facebook/actions/boost-post.action.ts +350 -386
- package/src/providers/facebook/actions/create-album.action.ts +291 -307
- package/src/providers/facebook/actions/create-post.action.ts +224 -227
- package/src/providers/facebook/actions/get-page-insights.action.ts +383 -403
- package/src/providers/facebook/actions/get-page-posts.action.ts +214 -225
- package/src/providers/facebook/actions/get-post-insights.action.ts +300 -316
- package/src/providers/facebook/actions/respond-to-comments.action.ts +319 -336
- package/src/providers/facebook/actions/schedule-post.action.ts +289 -292
- package/src/providers/facebook/actions/search-posts.action.ts +399 -413
- package/src/providers/facebook/facebook-base.action.ts +653 -670
- package/src/providers/hootsuite/actions/bulk-schedule-posts.action.ts +257 -257
- package/src/providers/hootsuite/actions/create-scheduled-post.action.ts +184 -189
- package/src/providers/hootsuite/actions/delete-scheduled-post.action.ts +160 -161
- package/src/providers/hootsuite/actions/get-analytics.action.ts +249 -254
- package/src/providers/hootsuite/actions/get-scheduled-posts.action.ts +206 -207
- package/src/providers/hootsuite/actions/get-social-profiles.action.ts +206 -205
- package/src/providers/hootsuite/actions/search-posts.action.ts +351 -369
- package/src/providers/hootsuite/actions/update-scheduled-post.action.ts +211 -209
- package/src/providers/hootsuite/hootsuite-base.action.ts +301 -307
- package/src/providers/instagram/actions/create-post.action.ts +276 -296
- package/src/providers/instagram/actions/create-story.action.ts +378 -394
- package/src/providers/instagram/actions/get-account-insights.action.ts +384 -420
- package/src/providers/instagram/actions/get-business-posts.action.ts +233 -242
- package/src/providers/instagram/actions/get-comments.action.ts +365 -377
- package/src/providers/instagram/actions/get-post-insights.action.ts +265 -273
- package/src/providers/instagram/actions/schedule-post.action.ts +233 -235
- package/src/providers/instagram/actions/search-posts.action.ts +512 -538
- package/src/providers/instagram/instagram-base.action.ts +368 -393
- package/src/providers/linkedin/actions/create-article.action.ts +275 -266
- package/src/providers/linkedin/actions/create-post.action.ts +179 -177
- package/src/providers/linkedin/actions/get-followers.action.ts +211 -211
- package/src/providers/linkedin/actions/get-organization-posts.action.ts +146 -147
- package/src/providers/linkedin/actions/get-personal-posts.action.ts +138 -139
- package/src/providers/linkedin/actions/get-post-analytics.action.ts +190 -189
- package/src/providers/linkedin/actions/schedule-post.action.ts +191 -189
- package/src/providers/linkedin/actions/search-posts.action.ts +275 -283
- package/src/providers/linkedin/linkedin-base.action.ts +407 -421
- package/src/providers/tiktok/tiktok-base.action.ts +305 -320
- package/src/providers/twitter/actions/create-thread.action.ts +203 -207
- package/src/providers/twitter/actions/create-tweet.action.ts +187 -188
- package/src/providers/twitter/actions/delete-tweet.action.ts +128 -129
- package/src/providers/twitter/actions/get-analytics.action.ts +402 -411
- package/src/providers/twitter/actions/get-mentions.action.ts +218 -219
- package/src/providers/twitter/actions/get-timeline.action.ts +232 -233
- package/src/providers/twitter/actions/schedule-tweet.action.ts +221 -222
- package/src/providers/twitter/actions/search-tweets.action.ts +540 -543
- package/src/providers/twitter/twitter-base.action.ts +541 -560
- package/src/providers/youtube/youtube-base.action.ts +320 -333
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RegisterClass } from '@memberjunction/global';
|
|
2
2
|
import { InstagramBaseAction } from '../instagram-base.action';
|
|
3
3
|
import { ActionParam, ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
|
|
4
|
-
import { LogError } from '@memberjunction/
|
|
4
|
+
import { LogError } from '@memberjunction/global';
|
|
5
5
|
import { BaseAction } from '@memberjunction/actions';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -10,294 +10,286 @@ import { BaseAction } from '@memberjunction/actions';
|
|
|
10
10
|
*/
|
|
11
11
|
@RegisterClass(BaseAction, 'Instagram - Get Post Insights')
|
|
12
12
|
export class InstagramGetPostInsightsAction extends InstagramBaseAction {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const period = this.getParamValue(params.Params, 'Period') || 'lifetime';
|
|
20
|
-
|
|
21
|
-
// Initialize OAuth
|
|
22
|
-
if (!await this.initializeOAuth(companyIntegrationId)) {
|
|
23
|
-
return {
|
|
24
|
-
Success: false,
|
|
25
|
-
Message: 'Failed to initialize Instagram authentication',
|
|
26
|
-
ResultCode: 'AUTH_FAILED'
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Validate inputs
|
|
31
|
-
if (!postId) {
|
|
32
|
-
return {
|
|
33
|
-
Success: false,
|
|
34
|
-
Message: 'PostID is required',
|
|
35
|
-
ResultCode: 'MISSING_PARAMS'
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// First, get the post details to determine its type
|
|
40
|
-
const postDetails = await this.getPostDetails(postId);
|
|
41
|
-
if (!postDetails) {
|
|
42
|
-
return {
|
|
43
|
-
Success: false,
|
|
44
|
-
Message: 'Post not found or access denied',
|
|
45
|
-
ResultCode: 'POST_NOT_FOUND'
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Determine available metrics based on post type
|
|
50
|
-
const availableMetrics = this.getAvailableMetrics(postDetails.media_type);
|
|
51
|
-
const requestedMetrics = metricTypes && metricTypes.length > 0
|
|
52
|
-
? metricTypes.filter(m => availableMetrics.includes(m))
|
|
53
|
-
: availableMetrics;
|
|
54
|
-
|
|
55
|
-
if (requestedMetrics.length === 0) {
|
|
56
|
-
return {
|
|
57
|
-
Success: false,
|
|
58
|
-
Message: 'No valid metrics specified for this post type',
|
|
59
|
-
ResultCode: 'INVALID_METRICS'
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Get insights
|
|
64
|
-
const insights = await this.getInsights(postId, requestedMetrics, period as any);
|
|
65
|
-
|
|
66
|
-
// Parse and structure the insights data
|
|
67
|
-
const parsedInsights = this.parseInsightsData(insights);
|
|
68
|
-
|
|
69
|
-
// Calculate engagement rate
|
|
70
|
-
const engagementRate = this.calculateEngagementRate(parsedInsights, postDetails);
|
|
71
|
-
|
|
72
|
-
// Store result in output params
|
|
73
|
-
const outputParams = [...params.Params];
|
|
74
|
-
outputParams.push({
|
|
75
|
-
Name: 'ResultData',
|
|
76
|
-
Type: 'Output',
|
|
77
|
-
Value: JSON.stringify({
|
|
78
|
-
postId,
|
|
79
|
-
postType: postDetails.media_type,
|
|
80
|
-
permalink: postDetails.permalink,
|
|
81
|
-
publishedAt: postDetails.timestamp,
|
|
82
|
-
metrics: parsedInsights,
|
|
83
|
-
summary: {
|
|
84
|
-
engagementRate,
|
|
85
|
-
totalEngagements: this.calculateTotalEngagements(parsedInsights),
|
|
86
|
-
performanceScore: this.calculatePerformanceScore(parsedInsights)
|
|
87
|
-
},
|
|
88
|
-
period,
|
|
89
|
-
dataCollectedAt: new Date().toISOString()
|
|
90
|
-
})
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
return {
|
|
94
|
-
Success: true,
|
|
95
|
-
Message: 'Successfully retrieved post insights',
|
|
96
|
-
ResultCode: 'SUCCESS',
|
|
97
|
-
Params: outputParams
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
} catch (error: any) {
|
|
101
|
-
LogError('Failed to retrieve Instagram post insights', error);
|
|
102
|
-
|
|
103
|
-
if (error.code === 'RATE_LIMIT') {
|
|
104
|
-
return {
|
|
105
|
-
Success: false,
|
|
106
|
-
Message: 'Instagram API rate limit exceeded. Please try again later.',
|
|
107
|
-
ResultCode: 'RATE_LIMIT'
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (error.code === 'POST_NOT_FOUND') {
|
|
112
|
-
return {
|
|
113
|
-
Success: false,
|
|
114
|
-
Message: 'Instagram post not found or access denied',
|
|
115
|
-
ResultCode: 'POST_NOT_FOUND'
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return {
|
|
120
|
-
Success: false,
|
|
121
|
-
Message: `Failed to retrieve post insights: ${error.message}`,
|
|
122
|
-
ResultCode: 'ERROR'
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
}
|
|
13
|
+
protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
|
|
14
|
+
try {
|
|
15
|
+
const companyIntegrationId = this.getParamValue(params.Params, 'CompanyIntegrationID');
|
|
16
|
+
const postId = this.getParamValue(params.Params, 'PostID');
|
|
17
|
+
const metricTypes = this.getParamValue(params.Params, 'MetricTypes') as string[];
|
|
18
|
+
const period = this.getParamValue(params.Params, 'Period') || 'lifetime';
|
|
126
19
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
null,
|
|
136
|
-
{
|
|
137
|
-
fields: 'id,media_type,permalink,timestamp,caption,like_count,comments_count',
|
|
138
|
-
access_token: this.getAccessToken()
|
|
139
|
-
}
|
|
140
|
-
);
|
|
141
|
-
return response;
|
|
142
|
-
} catch (error) {
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
20
|
+
// Initialize OAuth
|
|
21
|
+
if (!(await this.initializeOAuth(companyIntegrationId))) {
|
|
22
|
+
return {
|
|
23
|
+
Success: false,
|
|
24
|
+
Message: 'Failed to initialize Instagram authentication',
|
|
25
|
+
ResultCode: 'AUTH_FAILED',
|
|
26
|
+
};
|
|
27
|
+
}
|
|
146
28
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
29
|
+
// Validate inputs
|
|
30
|
+
if (!postId) {
|
|
31
|
+
return {
|
|
32
|
+
Success: false,
|
|
33
|
+
Message: 'PostID is required',
|
|
34
|
+
ResultCode: 'MISSING_PARAMS',
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// First, get the post details to determine its type
|
|
39
|
+
const postDetails = await this.getPostDetails(postId);
|
|
40
|
+
if (!postDetails) {
|
|
41
|
+
return {
|
|
42
|
+
Success: false,
|
|
43
|
+
Message: 'Post not found or access denied',
|
|
44
|
+
ResultCode: 'POST_NOT_FOUND',
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Determine available metrics based on post type
|
|
49
|
+
const availableMetrics = this.getAvailableMetrics(postDetails.media_type);
|
|
50
|
+
const requestedMetrics =
|
|
51
|
+
metricTypes && metricTypes.length > 0 ? metricTypes.filter((m) => availableMetrics.includes(m)) : availableMetrics;
|
|
52
|
+
|
|
53
|
+
if (requestedMetrics.length === 0) {
|
|
54
|
+
return {
|
|
55
|
+
Success: false,
|
|
56
|
+
Message: 'No valid metrics specified for this post type',
|
|
57
|
+
ResultCode: 'INVALID_METRICS',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Get insights
|
|
62
|
+
const insights = await this.getInsights(postId, requestedMetrics, period as any);
|
|
169
63
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
64
|
+
// Parse and structure the insights data
|
|
65
|
+
const parsedInsights = this.parseInsightsData(insights);
|
|
66
|
+
|
|
67
|
+
// Calculate engagement rate
|
|
68
|
+
const engagementRate = this.calculateEngagementRate(parsedInsights, postDetails);
|
|
69
|
+
|
|
70
|
+
// Store result in output params
|
|
71
|
+
const outputParams = [...params.Params];
|
|
72
|
+
outputParams.push({
|
|
73
|
+
Name: 'ResultData',
|
|
74
|
+
Type: 'Output',
|
|
75
|
+
Value: JSON.stringify({
|
|
76
|
+
postId,
|
|
77
|
+
postType: postDetails.media_type,
|
|
78
|
+
permalink: postDetails.permalink,
|
|
79
|
+
publishedAt: postDetails.timestamp,
|
|
80
|
+
metrics: parsedInsights,
|
|
81
|
+
summary: {
|
|
82
|
+
engagementRate,
|
|
83
|
+
totalEngagements: this.calculateTotalEngagements(parsedInsights),
|
|
84
|
+
performanceScore: this.calculatePerformanceScore(parsedInsights),
|
|
85
|
+
},
|
|
86
|
+
period,
|
|
87
|
+
dataCollectedAt: new Date().toISOString(),
|
|
88
|
+
}),
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
Success: true,
|
|
93
|
+
Message: 'Successfully retrieved post insights',
|
|
94
|
+
ResultCode: 'SUCCESS',
|
|
95
|
+
Params: outputParams,
|
|
96
|
+
};
|
|
97
|
+
} catch (error: any) {
|
|
98
|
+
LogError('Failed to retrieve Instagram post insights', error);
|
|
99
|
+
|
|
100
|
+
if (error.code === 'RATE_LIMIT') {
|
|
101
|
+
return {
|
|
102
|
+
Success: false,
|
|
103
|
+
Message: 'Instagram API rate limit exceeded. Please try again later.',
|
|
104
|
+
ResultCode: 'RATE_LIMIT',
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (error.code === 'POST_NOT_FOUND') {
|
|
109
|
+
return {
|
|
110
|
+
Success: false,
|
|
111
|
+
Message: 'Instagram post not found or access denied',
|
|
112
|
+
ResultCode: 'POST_NOT_FOUND',
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
Success: false,
|
|
118
|
+
Message: `Failed to retrieve post insights: ${error.message}`,
|
|
119
|
+
ResultCode: 'ERROR',
|
|
120
|
+
};
|
|
202
121
|
}
|
|
122
|
+
}
|
|
203
123
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
124
|
+
/**
|
|
125
|
+
* Get post details including media type
|
|
126
|
+
*/
|
|
127
|
+
private async getPostDetails(postId: string): Promise<any> {
|
|
128
|
+
try {
|
|
129
|
+
const response = await this.makeInstagramRequest(postId, 'GET', null, {
|
|
130
|
+
fields: 'id,media_type,permalink,timestamp,caption,like_count,comments_count',
|
|
131
|
+
access_token: this.getAccessToken(),
|
|
132
|
+
});
|
|
133
|
+
return response;
|
|
134
|
+
} catch (error) {
|
|
135
|
+
return null;
|
|
214
136
|
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Get available metrics based on post type
|
|
141
|
+
*/
|
|
142
|
+
private getAvailableMetrics(mediaType: string): string[] {
|
|
143
|
+
const baseMetrics = ['impressions', 'reach', 'engagement'];
|
|
144
|
+
|
|
145
|
+
switch (mediaType) {
|
|
146
|
+
case 'IMAGE':
|
|
147
|
+
case 'CAROUSEL_ALBUM':
|
|
148
|
+
return [...baseMetrics, 'saved', 'shares'];
|
|
149
|
+
|
|
150
|
+
case 'VIDEO':
|
|
151
|
+
case 'REELS':
|
|
152
|
+
return [...baseMetrics, 'saved', 'shares', 'video_views', 'avg_watch_time', 'completion_rate'];
|
|
215
153
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const saves = insights.saved?.value || 0;
|
|
222
|
-
const shares = insights.shares?.value || 0;
|
|
223
|
-
|
|
224
|
-
return engagement + saves + shares;
|
|
154
|
+
case 'STORY':
|
|
155
|
+
return ['impressions', 'reach', 'exits', 'replies', 'taps_forward', 'taps_back'];
|
|
156
|
+
|
|
157
|
+
default:
|
|
158
|
+
return baseMetrics;
|
|
225
159
|
}
|
|
160
|
+
}
|
|
226
161
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
let score = 0;
|
|
233
|
-
let factors = 0;
|
|
234
|
-
|
|
235
|
-
// Engagement rate factor
|
|
236
|
-
const reach = insights.reach?.value || 0;
|
|
237
|
-
const engagement = insights.engagement?.value || 0;
|
|
238
|
-
if (reach > 0) {
|
|
239
|
-
const engagementRate = (engagement / reach) * 100;
|
|
240
|
-
score += Math.min(engagementRate * 10, 30); // Max 30 points
|
|
241
|
-
factors++;
|
|
242
|
-
}
|
|
162
|
+
/**
|
|
163
|
+
* Parse insights data into a structured format
|
|
164
|
+
*/
|
|
165
|
+
private parseInsightsData(insights: any[]): Record<string, any> {
|
|
166
|
+
const parsed: Record<string, any> = {};
|
|
243
167
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
const reachRate = (reach / impressions) * 100;
|
|
248
|
-
score += Math.min(reachRate, 20); // Max 20 points
|
|
249
|
-
factors++;
|
|
250
|
-
}
|
|
168
|
+
insights.forEach((metric) => {
|
|
169
|
+
const name = metric.name;
|
|
170
|
+
const values = metric.values || [];
|
|
251
171
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
172
|
+
if (values.length > 0) {
|
|
173
|
+
// For lifetime metrics, there's usually only one value
|
|
174
|
+
const primaryValue = values[0];
|
|
175
|
+
|
|
176
|
+
parsed[name] = {
|
|
177
|
+
value: primaryValue.value || 0,
|
|
178
|
+
title: metric.title,
|
|
179
|
+
description: metric.description,
|
|
180
|
+
period: metric.period,
|
|
181
|
+
};
|
|
259
182
|
|
|
260
|
-
//
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
183
|
+
// For time series data (like daily metrics)
|
|
184
|
+
if (values.length > 1) {
|
|
185
|
+
parsed[name].timeSeries = values.map((v: any) => ({
|
|
186
|
+
value: v.value,
|
|
187
|
+
endTime: v.end_time,
|
|
188
|
+
}));
|
|
265
189
|
}
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
return parsed;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Calculate engagement rate
|
|
198
|
+
*/
|
|
199
|
+
private calculateEngagementRate(insights: Record<string, any>, postDetails: any): number {
|
|
200
|
+
const reach = insights.reach?.value || postDetails.reach || 0;
|
|
201
|
+
const engagement = insights.engagement?.value || 0;
|
|
202
|
+
|
|
203
|
+
if (reach === 0) return 0;
|
|
204
|
+
|
|
205
|
+
return Number(((engagement / reach) * 100).toFixed(2));
|
|
206
|
+
}
|
|
266
207
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
208
|
+
/**
|
|
209
|
+
* Calculate total engagements
|
|
210
|
+
*/
|
|
211
|
+
private calculateTotalEngagements(insights: Record<string, any>): number {
|
|
212
|
+
const engagement = insights.engagement?.value || 0;
|
|
213
|
+
const saves = insights.saved?.value || 0;
|
|
214
|
+
const shares = insights.shares?.value || 0;
|
|
215
|
+
|
|
216
|
+
return engagement + saves + shares;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Calculate a performance score (0-100)
|
|
221
|
+
*/
|
|
222
|
+
private calculatePerformanceScore(insights: Record<string, any>): number {
|
|
223
|
+
// Simple scoring algorithm based on key metrics
|
|
224
|
+
let score = 0;
|
|
225
|
+
let factors = 0;
|
|
226
|
+
|
|
227
|
+
// Engagement rate factor
|
|
228
|
+
const reach = insights.reach?.value || 0;
|
|
229
|
+
const engagement = insights.engagement?.value || 0;
|
|
230
|
+
if (reach > 0) {
|
|
231
|
+
const engagementRate = (engagement / reach) * 100;
|
|
232
|
+
score += Math.min(engagementRate * 10, 30); // Max 30 points
|
|
233
|
+
factors++;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Reach factor (compared to impressions)
|
|
237
|
+
const impressions = insights.impressions?.value || 0;
|
|
238
|
+
if (impressions > 0) {
|
|
239
|
+
const reachRate = (reach / impressions) * 100;
|
|
240
|
+
score += Math.min(reachRate, 20); // Max 20 points
|
|
241
|
+
factors++;
|
|
271
242
|
}
|
|
272
243
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
{
|
|
280
|
-
Name: 'PostID',
|
|
281
|
-
Type: 'Input',
|
|
282
|
-
Value: null
|
|
283
|
-
},
|
|
284
|
-
{
|
|
285
|
-
Name: 'MetricTypes',
|
|
286
|
-
Type: 'Input',
|
|
287
|
-
Value: null
|
|
288
|
-
},
|
|
289
|
-
{
|
|
290
|
-
Name: 'Period',
|
|
291
|
-
Type: 'Input',
|
|
292
|
-
Value: 'lifetime'
|
|
293
|
-
}
|
|
294
|
-
];
|
|
244
|
+
// Saves factor
|
|
245
|
+
const saves = insights.saved?.value || 0;
|
|
246
|
+
if (reach > 0) {
|
|
247
|
+
const saveRate = (saves / reach) * 100;
|
|
248
|
+
score += Math.min(saveRate * 20, 25); // Max 25 points
|
|
249
|
+
factors++;
|
|
295
250
|
}
|
|
296
251
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
252
|
+
// Video completion rate (for videos)
|
|
253
|
+
const completionRate = insights.completion_rate?.value || 0;
|
|
254
|
+
if (completionRate > 0) {
|
|
255
|
+
score += Math.min(completionRate, 25); // Max 25 points
|
|
256
|
+
factors++;
|
|
302
257
|
}
|
|
303
|
-
|
|
258
|
+
|
|
259
|
+
// Normalize score
|
|
260
|
+
if (factors === 0) return 0;
|
|
261
|
+
|
|
262
|
+
return Math.round(Math.min(score, 100));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Define the parameters for this action
|
|
267
|
+
*/
|
|
268
|
+
public get Params(): ActionParam[] {
|
|
269
|
+
return [
|
|
270
|
+
...this.commonSocialParams,
|
|
271
|
+
{
|
|
272
|
+
Name: 'PostID',
|
|
273
|
+
Type: 'Input',
|
|
274
|
+
Value: null,
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
Name: 'MetricTypes',
|
|
278
|
+
Type: 'Input',
|
|
279
|
+
Value: null,
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
Name: 'Period',
|
|
283
|
+
Type: 'Input',
|
|
284
|
+
Value: 'lifetime',
|
|
285
|
+
},
|
|
286
|
+
];
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Get the description for this action
|
|
291
|
+
*/
|
|
292
|
+
public get Description(): string {
|
|
293
|
+
return 'Retrieves detailed analytics and insights for a specific Instagram post including impressions, reach, engagement, and more.';
|
|
294
|
+
}
|
|
295
|
+
}
|