@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.
Files changed (204) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +6 -6
  3. package/dist/base/base-social.action.d.ts.map +1 -1
  4. package/dist/base/base-social.action.js +18 -24
  5. package/dist/base/base-social.action.js.map +1 -1
  6. package/dist/providers/buffer/buffer-base.action.d.ts.map +1 -1
  7. package/dist/providers/buffer/buffer-base.action.js +35 -34
  8. package/dist/providers/buffer/buffer-base.action.js.map +1 -1
  9. package/dist/providers/facebook/actions/boost-post.action.d.ts.map +1 -1
  10. package/dist/providers/facebook/actions/boost-post.action.js +33 -33
  11. package/dist/providers/facebook/actions/boost-post.action.js.map +1 -1
  12. package/dist/providers/facebook/actions/create-album.action.d.ts.map +1 -1
  13. package/dist/providers/facebook/actions/create-album.action.js +34 -36
  14. package/dist/providers/facebook/actions/create-album.action.js.map +1 -1
  15. package/dist/providers/facebook/actions/create-post.action.d.ts.map +1 -1
  16. package/dist/providers/facebook/actions/create-post.action.js +20 -20
  17. package/dist/providers/facebook/actions/create-post.action.js.map +1 -1
  18. package/dist/providers/facebook/actions/get-page-insights.action.d.ts.map +1 -1
  19. package/dist/providers/facebook/actions/get-page-insights.action.js +25 -27
  20. package/dist/providers/facebook/actions/get-page-insights.action.js.map +1 -1
  21. package/dist/providers/facebook/actions/get-page-posts.action.d.ts.map +1 -1
  22. package/dist/providers/facebook/actions/get-page-posts.action.js +19 -23
  23. package/dist/providers/facebook/actions/get-page-posts.action.js.map +1 -1
  24. package/dist/providers/facebook/actions/get-post-insights.action.d.ts.map +1 -1
  25. package/dist/providers/facebook/actions/get-post-insights.action.js +28 -32
  26. package/dist/providers/facebook/actions/get-post-insights.action.js.map +1 -1
  27. package/dist/providers/facebook/actions/respond-to-comments.action.d.ts.map +1 -1
  28. package/dist/providers/facebook/actions/respond-to-comments.action.js +42 -44
  29. package/dist/providers/facebook/actions/respond-to-comments.action.js.map +1 -1
  30. package/dist/providers/facebook/actions/schedule-post.action.d.ts.map +1 -1
  31. package/dist/providers/facebook/actions/schedule-post.action.js +29 -29
  32. package/dist/providers/facebook/actions/schedule-post.action.js.map +1 -1
  33. package/dist/providers/facebook/actions/search-posts.action.d.ts.map +1 -1
  34. package/dist/providers/facebook/actions/search-posts.action.js +37 -39
  35. package/dist/providers/facebook/actions/search-posts.action.js.map +1 -1
  36. package/dist/providers/facebook/facebook-base.action.d.ts.map +1 -1
  37. package/dist/providers/facebook/facebook-base.action.js +44 -59
  38. package/dist/providers/facebook/facebook-base.action.js.map +1 -1
  39. package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.d.ts.map +1 -1
  40. package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.js +33 -31
  41. package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.js.map +1 -1
  42. package/dist/providers/hootsuite/actions/create-scheduled-post.action.d.ts.map +1 -1
  43. package/dist/providers/hootsuite/actions/create-scheduled-post.action.js +28 -32
  44. package/dist/providers/hootsuite/actions/create-scheduled-post.action.js.map +1 -1
  45. package/dist/providers/hootsuite/actions/delete-scheduled-post.action.d.ts.map +1 -1
  46. package/dist/providers/hootsuite/actions/delete-scheduled-post.action.js +19 -19
  47. package/dist/providers/hootsuite/actions/delete-scheduled-post.action.js.map +1 -1
  48. package/dist/providers/hootsuite/actions/get-analytics.action.d.ts.map +1 -1
  49. package/dist/providers/hootsuite/actions/get-analytics.action.js +24 -26
  50. package/dist/providers/hootsuite/actions/get-analytics.action.js.map +1 -1
  51. package/dist/providers/hootsuite/actions/get-scheduled-posts.action.d.ts.map +1 -1
  52. package/dist/providers/hootsuite/actions/get-scheduled-posts.action.js +22 -22
  53. package/dist/providers/hootsuite/actions/get-scheduled-posts.action.js.map +1 -1
  54. package/dist/providers/hootsuite/actions/get-social-profiles.action.d.ts.map +1 -1
  55. package/dist/providers/hootsuite/actions/get-social-profiles.action.js +32 -34
  56. package/dist/providers/hootsuite/actions/get-social-profiles.action.js.map +1 -1
  57. package/dist/providers/hootsuite/actions/search-posts.action.d.ts.map +1 -1
  58. package/dist/providers/hootsuite/actions/search-posts.action.js +43 -52
  59. package/dist/providers/hootsuite/actions/search-posts.action.js.map +1 -1
  60. package/dist/providers/hootsuite/actions/update-scheduled-post.action.d.ts.map +1 -1
  61. package/dist/providers/hootsuite/actions/update-scheduled-post.action.js +30 -28
  62. package/dist/providers/hootsuite/actions/update-scheduled-post.action.js.map +1 -1
  63. package/dist/providers/hootsuite/hootsuite-base.action.d.ts.map +1 -1
  64. package/dist/providers/hootsuite/hootsuite-base.action.js +18 -20
  65. package/dist/providers/hootsuite/hootsuite-base.action.js.map +1 -1
  66. package/dist/providers/instagram/actions/create-post.action.d.ts.map +1 -1
  67. package/dist/providers/instagram/actions/create-post.action.js +27 -26
  68. package/dist/providers/instagram/actions/create-post.action.js.map +1 -1
  69. package/dist/providers/instagram/actions/create-story.action.d.ts.map +1 -1
  70. package/dist/providers/instagram/actions/create-story.action.js +35 -35
  71. package/dist/providers/instagram/actions/create-story.action.js.map +1 -1
  72. package/dist/providers/instagram/actions/get-account-insights.action.d.ts.map +1 -1
  73. package/dist/providers/instagram/actions/get-account-insights.action.js +38 -59
  74. package/dist/providers/instagram/actions/get-account-insights.action.js.map +1 -1
  75. package/dist/providers/instagram/actions/get-business-posts.action.d.ts.map +1 -1
  76. package/dist/providers/instagram/actions/get-business-posts.action.js +29 -29
  77. package/dist/providers/instagram/actions/get-business-posts.action.js.map +1 -1
  78. package/dist/providers/instagram/actions/get-comments.action.d.ts.map +1 -1
  79. package/dist/providers/instagram/actions/get-comments.action.js +36 -36
  80. package/dist/providers/instagram/actions/get-comments.action.js.map +1 -1
  81. package/dist/providers/instagram/actions/get-post-insights.action.d.ts.map +1 -1
  82. package/dist/providers/instagram/actions/get-post-insights.action.js +23 -25
  83. package/dist/providers/instagram/actions/get-post-insights.action.js.map +1 -1
  84. package/dist/providers/instagram/actions/schedule-post.action.d.ts.map +1 -1
  85. package/dist/providers/instagram/actions/schedule-post.action.js +25 -25
  86. package/dist/providers/instagram/actions/schedule-post.action.js.map +1 -1
  87. package/dist/providers/instagram/actions/search-posts.action.d.ts.map +1 -1
  88. package/dist/providers/instagram/actions/search-posts.action.js +56 -60
  89. package/dist/providers/instagram/actions/search-posts.action.js.map +1 -1
  90. package/dist/providers/instagram/instagram-base.action.d.ts.map +1 -1
  91. package/dist/providers/instagram/instagram-base.action.js +25 -27
  92. package/dist/providers/instagram/instagram-base.action.js.map +1 -1
  93. package/dist/providers/linkedin/actions/create-article.action.d.ts.map +1 -1
  94. package/dist/providers/linkedin/actions/create-article.action.js +55 -45
  95. package/dist/providers/linkedin/actions/create-article.action.js.map +1 -1
  96. package/dist/providers/linkedin/actions/create-post.action.d.ts.map +1 -1
  97. package/dist/providers/linkedin/actions/create-post.action.js +31 -29
  98. package/dist/providers/linkedin/actions/create-post.action.js.map +1 -1
  99. package/dist/providers/linkedin/actions/get-followers.action.d.ts.map +1 -1
  100. package/dist/providers/linkedin/actions/get-followers.action.js +28 -28
  101. package/dist/providers/linkedin/actions/get-followers.action.js.map +1 -1
  102. package/dist/providers/linkedin/actions/get-organization-posts.action.d.ts.map +1 -1
  103. package/dist/providers/linkedin/actions/get-organization-posts.action.js +20 -20
  104. package/dist/providers/linkedin/actions/get-organization-posts.action.js.map +1 -1
  105. package/dist/providers/linkedin/actions/get-personal-posts.action.d.ts.map +1 -1
  106. package/dist/providers/linkedin/actions/get-personal-posts.action.js +19 -19
  107. package/dist/providers/linkedin/actions/get-personal-posts.action.js.map +1 -1
  108. package/dist/providers/linkedin/actions/get-post-analytics.action.d.ts.map +1 -1
  109. package/dist/providers/linkedin/actions/get-post-analytics.action.js +25 -23
  110. package/dist/providers/linkedin/actions/get-post-analytics.action.js.map +1 -1
  111. package/dist/providers/linkedin/actions/schedule-post.action.d.ts.map +1 -1
  112. package/dist/providers/linkedin/actions/schedule-post.action.js +32 -30
  113. package/dist/providers/linkedin/actions/schedule-post.action.js.map +1 -1
  114. package/dist/providers/linkedin/actions/search-posts.action.d.ts.map +1 -1
  115. package/dist/providers/linkedin/actions/search-posts.action.js +28 -30
  116. package/dist/providers/linkedin/actions/search-posts.action.js.map +1 -1
  117. package/dist/providers/linkedin/linkedin-base.action.d.ts.map +1 -1
  118. package/dist/providers/linkedin/linkedin-base.action.js +33 -38
  119. package/dist/providers/linkedin/linkedin-base.action.js.map +1 -1
  120. package/dist/providers/tiktok/tiktok-base.action.d.ts.map +1 -1
  121. package/dist/providers/tiktok/tiktok-base.action.js +25 -26
  122. package/dist/providers/tiktok/tiktok-base.action.js.map +1 -1
  123. package/dist/providers/twitter/actions/create-thread.action.d.ts.map +1 -1
  124. package/dist/providers/twitter/actions/create-thread.action.js +25 -29
  125. package/dist/providers/twitter/actions/create-thread.action.js.map +1 -1
  126. package/dist/providers/twitter/actions/create-tweet.action.d.ts.map +1 -1
  127. package/dist/providers/twitter/actions/create-tweet.action.js +23 -23
  128. package/dist/providers/twitter/actions/create-tweet.action.js.map +1 -1
  129. package/dist/providers/twitter/actions/delete-tweet.action.d.ts.map +1 -1
  130. package/dist/providers/twitter/actions/delete-tweet.action.js +19 -19
  131. package/dist/providers/twitter/actions/delete-tweet.action.js.map +1 -1
  132. package/dist/providers/twitter/actions/get-analytics.action.d.ts.map +1 -1
  133. package/dist/providers/twitter/actions/get-analytics.action.js +40 -47
  134. package/dist/providers/twitter/actions/get-analytics.action.js.map +1 -1
  135. package/dist/providers/twitter/actions/get-mentions.action.d.ts.map +1 -1
  136. package/dist/providers/twitter/actions/get-mentions.action.js +30 -31
  137. package/dist/providers/twitter/actions/get-mentions.action.js.map +1 -1
  138. package/dist/providers/twitter/actions/get-timeline.action.d.ts.map +1 -1
  139. package/dist/providers/twitter/actions/get-timeline.action.js +29 -29
  140. package/dist/providers/twitter/actions/get-timeline.action.js.map +1 -1
  141. package/dist/providers/twitter/actions/schedule-tweet.action.d.ts.map +1 -1
  142. package/dist/providers/twitter/actions/schedule-tweet.action.js +26 -26
  143. package/dist/providers/twitter/actions/schedule-tweet.action.js.map +1 -1
  144. package/dist/providers/twitter/actions/search-tweets.action.d.ts.map +1 -1
  145. package/dist/providers/twitter/actions/search-tweets.action.js +56 -58
  146. package/dist/providers/twitter/actions/search-tweets.action.js.map +1 -1
  147. package/dist/providers/twitter/twitter-base.action.d.ts.map +1 -1
  148. package/dist/providers/twitter/twitter-base.action.js +58 -68
  149. package/dist/providers/twitter/twitter-base.action.js.map +1 -1
  150. package/dist/providers/youtube/youtube-base.action.d.ts +1 -1
  151. package/dist/providers/youtube/youtube-base.action.d.ts.map +1 -1
  152. package/dist/providers/youtube/youtube-base.action.js +22 -25
  153. package/dist/providers/youtube/youtube-base.action.js.map +1 -1
  154. package/package.json +5 -6
  155. package/src/base/base-social.action.ts +217 -224
  156. package/src/providers/buffer/buffer-base.action.ts +435 -441
  157. package/src/providers/facebook/actions/boost-post.action.ts +350 -386
  158. package/src/providers/facebook/actions/create-album.action.ts +291 -307
  159. package/src/providers/facebook/actions/create-post.action.ts +224 -227
  160. package/src/providers/facebook/actions/get-page-insights.action.ts +383 -403
  161. package/src/providers/facebook/actions/get-page-posts.action.ts +214 -225
  162. package/src/providers/facebook/actions/get-post-insights.action.ts +300 -316
  163. package/src/providers/facebook/actions/respond-to-comments.action.ts +319 -336
  164. package/src/providers/facebook/actions/schedule-post.action.ts +289 -292
  165. package/src/providers/facebook/actions/search-posts.action.ts +399 -413
  166. package/src/providers/facebook/facebook-base.action.ts +653 -670
  167. package/src/providers/hootsuite/actions/bulk-schedule-posts.action.ts +257 -257
  168. package/src/providers/hootsuite/actions/create-scheduled-post.action.ts +184 -189
  169. package/src/providers/hootsuite/actions/delete-scheduled-post.action.ts +160 -161
  170. package/src/providers/hootsuite/actions/get-analytics.action.ts +249 -254
  171. package/src/providers/hootsuite/actions/get-scheduled-posts.action.ts +206 -207
  172. package/src/providers/hootsuite/actions/get-social-profiles.action.ts +206 -205
  173. package/src/providers/hootsuite/actions/search-posts.action.ts +351 -369
  174. package/src/providers/hootsuite/actions/update-scheduled-post.action.ts +211 -209
  175. package/src/providers/hootsuite/hootsuite-base.action.ts +301 -307
  176. package/src/providers/instagram/actions/create-post.action.ts +276 -296
  177. package/src/providers/instagram/actions/create-story.action.ts +378 -394
  178. package/src/providers/instagram/actions/get-account-insights.action.ts +384 -420
  179. package/src/providers/instagram/actions/get-business-posts.action.ts +233 -242
  180. package/src/providers/instagram/actions/get-comments.action.ts +365 -377
  181. package/src/providers/instagram/actions/get-post-insights.action.ts +265 -273
  182. package/src/providers/instagram/actions/schedule-post.action.ts +233 -235
  183. package/src/providers/instagram/actions/search-posts.action.ts +512 -538
  184. package/src/providers/instagram/instagram-base.action.ts +368 -393
  185. package/src/providers/linkedin/actions/create-article.action.ts +275 -266
  186. package/src/providers/linkedin/actions/create-post.action.ts +179 -177
  187. package/src/providers/linkedin/actions/get-followers.action.ts +211 -211
  188. package/src/providers/linkedin/actions/get-organization-posts.action.ts +146 -147
  189. package/src/providers/linkedin/actions/get-personal-posts.action.ts +138 -139
  190. package/src/providers/linkedin/actions/get-post-analytics.action.ts +190 -189
  191. package/src/providers/linkedin/actions/schedule-post.action.ts +191 -189
  192. package/src/providers/linkedin/actions/search-posts.action.ts +275 -283
  193. package/src/providers/linkedin/linkedin-base.action.ts +407 -421
  194. package/src/providers/tiktok/tiktok-base.action.ts +305 -320
  195. package/src/providers/twitter/actions/create-thread.action.ts +203 -207
  196. package/src/providers/twitter/actions/create-tweet.action.ts +187 -188
  197. package/src/providers/twitter/actions/delete-tweet.action.ts +128 -129
  198. package/src/providers/twitter/actions/get-analytics.action.ts +402 -411
  199. package/src/providers/twitter/actions/get-mentions.action.ts +218 -219
  200. package/src/providers/twitter/actions/get-timeline.action.ts +232 -233
  201. package/src/providers/twitter/actions/schedule-tweet.action.ts +221 -222
  202. package/src/providers/twitter/actions/search-tweets.action.ts +540 -543
  203. package/src/providers/twitter/twitter-base.action.ts +541 -560
  204. 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/core';
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
- protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
15
- try {
16
- const companyIntegrationId = this.getParamValue(params.Params, 'CompanyIntegrationID');
17
- const postId = this.getParamValue(params.Params, 'PostID');
18
- const metricTypes = this.getParamValue(params.Params, 'MetricTypes') as string[];
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
- * Get post details including media type
129
- */
130
- private async getPostDetails(postId: string): Promise<any> {
131
- try {
132
- const response = await this.makeInstagramRequest(
133
- postId,
134
- 'GET',
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
- * Get available metrics based on post type
149
- */
150
- private getAvailableMetrics(mediaType: string): string[] {
151
- const baseMetrics = ['impressions', 'reach', 'engagement'];
152
-
153
- switch (mediaType) {
154
- case 'IMAGE':
155
- case 'CAROUSEL_ALBUM':
156
- return [...baseMetrics, 'saved', 'shares'];
157
-
158
- case 'VIDEO':
159
- case 'REELS':
160
- return [...baseMetrics, 'saved', 'shares', 'video_views', 'avg_watch_time', 'completion_rate'];
161
-
162
- case 'STORY':
163
- return ['impressions', 'reach', 'exits', 'replies', 'taps_forward', 'taps_back'];
164
-
165
- default:
166
- return baseMetrics;
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
- * Parse insights data into a structured format
172
- */
173
- private parseInsightsData(insights: any[]): Record<string, any> {
174
- const parsed: Record<string, any> = {};
175
-
176
- insights.forEach(metric => {
177
- const name = metric.name;
178
- const values = metric.values || [];
179
-
180
- if (values.length > 0) {
181
- // For lifetime metrics, there's usually only one value
182
- const primaryValue = values[0];
183
-
184
- parsed[name] = {
185
- value: primaryValue.value || 0,
186
- title: metric.title,
187
- description: metric.description,
188
- period: metric.period
189
- };
190
-
191
- // For time series data (like daily metrics)
192
- if (values.length > 1) {
193
- parsed[name].timeSeries = values.map((v: any) => ({
194
- value: v.value,
195
- endTime: v.end_time
196
- }));
197
- }
198
- }
199
- });
200
-
201
- return parsed;
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
- * Calculate engagement rate
206
- */
207
- private calculateEngagementRate(insights: Record<string, any>, postDetails: any): number {
208
- const reach = insights.reach?.value || postDetails.reach || 0;
209
- const engagement = insights.engagement?.value || 0;
210
-
211
- if (reach === 0) return 0;
212
-
213
- return Number(((engagement / reach) * 100).toFixed(2));
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
- * Calculate total engagements
218
- */
219
- private calculateTotalEngagements(insights: Record<string, any>): number {
220
- const engagement = insights.engagement?.value || 0;
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
- * Calculate a performance score (0-100)
229
- */
230
- private calculatePerformanceScore(insights: Record<string, any>): number {
231
- // Simple scoring algorithm based on key metrics
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
- // Reach factor (compared to impressions)
245
- const impressions = insights.impressions?.value || 0;
246
- if (impressions > 0) {
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
- // Saves factor
253
- const saves = insights.saved?.value || 0;
254
- if (reach > 0) {
255
- const saveRate = (saves / reach) * 100;
256
- score += Math.min(saveRate * 20, 25); // Max 25 points
257
- factors++;
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
- // Video completion rate (for videos)
261
- const completionRate = insights.completion_rate?.value || 0;
262
- if (completionRate > 0) {
263
- score += Math.min(completionRate, 25); // Max 25 points
264
- factors++;
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
- // Normalize score
268
- if (factors === 0) return 0;
269
-
270
- return Math.round(Math.min(score, 100));
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
- * Define the parameters for this action
275
- */
276
- public get Params(): ActionParam[] {
277
- return [
278
- ...this.commonSocialParams,
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
- * Get the description for this action
299
- */
300
- public get Description(): string {
301
- return 'Retrieves detailed analytics and insights for a specific Instagram post including impressions, reach, engagement, and more.';
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
+ }