@memberjunction/actions-bizapps-social 2.112.0 → 2.113.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 +13 -0
  3. package/dist/base/base-social.action.d.ts.map +1 -1
  4. package/dist/base/base-social.action.js +24 -18
  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 +34 -35
  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 +36 -34
  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 +27 -25
  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 +23 -19
  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 +32 -28
  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 +44 -42
  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 +39 -37
  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 +59 -44
  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 +31 -33
  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 +32 -28
  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 +26 -24
  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 +34 -32
  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 +52 -43
  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 +28 -30
  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 +20 -18
  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 +26 -27
  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 +59 -38
  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 +25 -23
  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 +60 -56
  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 +27 -25
  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 +45 -55
  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 +29 -31
  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 +23 -25
  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 +30 -32
  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 +30 -28
  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 +38 -33
  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 +26 -25
  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 +29 -25
  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 +47 -40
  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 +31 -30
  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 +58 -56
  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 +68 -58
  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 +25 -22
  153. package/dist/providers/youtube/youtube-base.action.js.map +1 -1
  154. package/package.json +6 -5
  155. package/src/base/base-social.action.ts +224 -217
  156. package/src/providers/buffer/buffer-base.action.ts +441 -435
  157. package/src/providers/facebook/actions/boost-post.action.ts +386 -350
  158. package/src/providers/facebook/actions/create-album.action.ts +307 -291
  159. package/src/providers/facebook/actions/create-post.action.ts +227 -224
  160. package/src/providers/facebook/actions/get-page-insights.action.ts +403 -383
  161. package/src/providers/facebook/actions/get-page-posts.action.ts +225 -214
  162. package/src/providers/facebook/actions/get-post-insights.action.ts +316 -300
  163. package/src/providers/facebook/actions/respond-to-comments.action.ts +336 -319
  164. package/src/providers/facebook/actions/schedule-post.action.ts +292 -289
  165. package/src/providers/facebook/actions/search-posts.action.ts +413 -399
  166. package/src/providers/facebook/facebook-base.action.ts +670 -653
  167. package/src/providers/hootsuite/actions/bulk-schedule-posts.action.ts +257 -257
  168. package/src/providers/hootsuite/actions/create-scheduled-post.action.ts +189 -184
  169. package/src/providers/hootsuite/actions/delete-scheduled-post.action.ts +161 -160
  170. package/src/providers/hootsuite/actions/get-analytics.action.ts +254 -249
  171. package/src/providers/hootsuite/actions/get-scheduled-posts.action.ts +207 -206
  172. package/src/providers/hootsuite/actions/get-social-profiles.action.ts +205 -206
  173. package/src/providers/hootsuite/actions/search-posts.action.ts +369 -351
  174. package/src/providers/hootsuite/actions/update-scheduled-post.action.ts +209 -211
  175. package/src/providers/hootsuite/hootsuite-base.action.ts +307 -301
  176. package/src/providers/instagram/actions/create-post.action.ts +296 -276
  177. package/src/providers/instagram/actions/create-story.action.ts +394 -378
  178. package/src/providers/instagram/actions/get-account-insights.action.ts +420 -384
  179. package/src/providers/instagram/actions/get-business-posts.action.ts +242 -233
  180. package/src/providers/instagram/actions/get-comments.action.ts +377 -365
  181. package/src/providers/instagram/actions/get-post-insights.action.ts +273 -265
  182. package/src/providers/instagram/actions/schedule-post.action.ts +235 -233
  183. package/src/providers/instagram/actions/search-posts.action.ts +538 -512
  184. package/src/providers/instagram/instagram-base.action.ts +393 -368
  185. package/src/providers/linkedin/actions/create-article.action.ts +266 -275
  186. package/src/providers/linkedin/actions/create-post.action.ts +177 -179
  187. package/src/providers/linkedin/actions/get-followers.action.ts +211 -211
  188. package/src/providers/linkedin/actions/get-organization-posts.action.ts +147 -146
  189. package/src/providers/linkedin/actions/get-personal-posts.action.ts +139 -138
  190. package/src/providers/linkedin/actions/get-post-analytics.action.ts +189 -190
  191. package/src/providers/linkedin/actions/schedule-post.action.ts +189 -191
  192. package/src/providers/linkedin/actions/search-posts.action.ts +283 -275
  193. package/src/providers/linkedin/linkedin-base.action.ts +421 -407
  194. package/src/providers/tiktok/tiktok-base.action.ts +320 -305
  195. package/src/providers/twitter/actions/create-thread.action.ts +207 -203
  196. package/src/providers/twitter/actions/create-tweet.action.ts +188 -187
  197. package/src/providers/twitter/actions/delete-tweet.action.ts +129 -128
  198. package/src/providers/twitter/actions/get-analytics.action.ts +411 -402
  199. package/src/providers/twitter/actions/get-mentions.action.ts +219 -218
  200. package/src/providers/twitter/actions/get-timeline.action.ts +233 -232
  201. package/src/providers/twitter/actions/schedule-tweet.action.ts +222 -221
  202. package/src/providers/twitter/actions/search-tweets.action.ts +543 -540
  203. package/src/providers/twitter/twitter-base.action.ts +560 -541
  204. package/src/providers/youtube/youtube-base.action.ts +333 -320
@@ -2,7 +2,7 @@ import { RegisterClass } from '@memberjunction/global';
2
2
  import { FacebookBaseAction, FacebookInsight } from '../facebook-base.action';
3
3
  import { ActionParam, ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
4
4
  import { SocialMediaErrorCode } from '../../../base/base-social.action';
5
- import { LogStatus, LogError } from '@memberjunction/global';
5
+ import { LogStatus, LogError } from '@memberjunction/core';
6
6
  import axios from 'axios';
7
7
  import { BaseAction } from '@memberjunction/actions';
8
8
 
@@ -12,397 +12,417 @@ import { BaseAction } from '@memberjunction/actions';
12
12
  */
13
13
  @RegisterClass(BaseAction, 'FacebookGetPageInsightsAction')
14
14
  export class FacebookGetPageInsightsAction extends FacebookBaseAction {
15
- /**
16
- * Get action description
17
- */
18
- public get Description(): string {
19
- return 'Retrieves comprehensive analytics for a Facebook page including views, engagement, demographics, and performance metrics';
20
- }
21
-
22
- /**
23
- * Define the parameters for this action
24
- */
25
- public get Params(): ActionParam[] {
26
- return [
27
- ...this.commonSocialParams,
28
- {
29
- Name: 'PageID',
30
- Type: 'Input',
31
- Value: null,
32
- },
33
- {
34
- Name: 'MetricTypes',
35
- Type: 'Input',
36
- Value: null,
37
- },
38
- {
39
- Name: 'Period',
40
- Type: 'Input',
41
- Value: 'day',
42
- },
43
- {
44
- Name: 'StartDate',
45
- Type: 'Input',
46
- Value: null,
47
- },
48
- {
49
- Name: 'EndDate',
50
- Type: 'Input',
51
- Value: null,
52
- },
53
- {
54
- Name: 'IncludeDemographics',
55
- Type: 'Input',
56
- Value: true,
57
- },
58
- {
59
- Name: 'IncludeVideoMetrics',
60
- Type: 'Input',
61
- Value: true,
62
- },
63
- {
64
- Name: 'CompareWithPrevious',
65
- Type: 'Input',
66
- Value: false,
67
- },
68
- ];
69
- }
70
-
71
- /**
72
- * Execute the action
73
- */
74
- protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
75
- const { Params, ContextUser } = params;
76
-
77
- try {
78
- // Validate required parameters
79
- const companyIntegrationId = this.getParamValue(Params, 'CompanyIntegrationID');
80
- const pageId = this.getParamValue(Params, 'PageID');
81
-
82
- if (!companyIntegrationId) {
83
- return {
84
- Success: false,
85
- Message: 'CompanyIntegrationID is required',
86
- ResultCode: 'INVALID_TOKEN',
87
- };
88
- }
89
-
90
- if (!pageId) {
91
- return {
92
- Success: false,
93
- Message: 'PageID is required',
94
- ResultCode: 'MISSING_REQUIRED_PARAM',
95
- };
96
- }
97
-
98
- // Initialize OAuth
99
- if (!(await this.initializeOAuth(companyIntegrationId))) {
100
- return {
101
- Success: false,
102
- Message: 'Failed to initialize Facebook OAuth connection',
103
- ResultCode: 'INVALID_TOKEN',
104
- };
105
- }
106
-
107
- // Get parameters
108
- const metricTypes = this.getParamValue(Params, 'MetricTypes') as string[];
109
- const period = (this.getParamValue(Params, 'Period') as string) || 'day';
110
- const startDate = this.getParamValue(Params, 'StartDate') as string;
111
- const endDate = this.getParamValue(Params, 'EndDate') as string;
112
- const includeDemographics = this.getParamValue(Params, 'IncludeDemographics') !== false;
113
- const includeVideoMetrics = this.getParamValue(Params, 'IncludeVideoMetrics') !== false;
114
- const compareWithPrevious = this.getParamValue(Params, 'CompareWithPrevious') as boolean;
115
-
116
- LogStatus(`Retrieving insights for Facebook page ${pageId}...`);
117
-
118
- // Get page access token
119
- const pageToken = await this.getPageAccessToken(pageId);
120
-
121
- // Build metrics list
122
- const metrics =
123
- metricTypes && metricTypes.length > 0 ? metricTypes : this.getDefaultPageMetrics(includeDemographics, includeVideoMetrics);
124
-
125
- // Build date range parameters
126
- const dateParams: any = {};
127
- if (startDate && endDate) {
128
- dateParams.since = new Date(startDate).toISOString();
129
- dateParams.until = new Date(endDate).toISOString();
130
- } else if (period !== 'lifetime') {
131
- // Default to last 30 days if no date range specified
132
- const end = new Date();
133
- const start = new Date();
134
- start.setDate(start.getDate() - 30);
135
- dateParams.since = start.toISOString();
136
- dateParams.until = end.toISOString();
137
- }
138
-
139
- // Get page insights
140
- const insightsResponse = await axios.get(`${this.apiBaseUrl}/${pageId}/insights`, {
141
- params: {
142
- access_token: pageToken,
143
- metric: metrics.join(','),
144
- period: period,
145
- ...dateParams,
146
- },
147
- });
148
-
149
- const insights: FacebookInsight[] = insightsResponse.data.data || [];
150
-
151
- // Get page info for context
152
- const pageInfoResponse = await axios.get(`${this.apiBaseUrl}/${pageId}`, {
153
- params: {
154
- access_token: pageToken,
155
- fields: 'id,name,category,fan_count,followers_count,about,cover,picture',
156
- },
157
- });
158
-
159
- const pageInfo = pageInfoResponse.data;
160
-
161
- // Process insights into categories
162
- const processedInsights = this.categorizeInsights(insights);
163
-
164
- // Get comparison data if requested
165
- let comparison = null;
166
- if (compareWithPrevious && startDate && endDate) {
167
- comparison = await this.getComparisonData(pageId, pageToken, metrics, period, new Date(startDate), new Date(endDate));
168
- }
169
-
170
- // Calculate summary metrics
171
- const summary = this.calculateSummaryMetrics(processedInsights, pageInfo);
172
-
173
- LogStatus(`Successfully retrieved insights for page ${pageId}`);
174
-
175
- return {
176
- Success: true,
177
- Message: 'Page insights retrieved successfully',
178
- ResultCode: 'SUCCESS',
179
- Params,
180
- };
181
- } catch (error) {
182
- LogError(`Failed to get Facebook page insights: ${error instanceof Error ? error.message : 'Unknown error'}`);
183
-
184
- if (this.isAuthError(error)) {
185
- return this.handleOAuthError(error);
186
- }
187
-
188
- return {
189
- Success: false,
190
- Message: error instanceof Error ? error.message : 'Unknown error occurred',
191
- ResultCode: 'ERROR',
192
- };
15
+ /**
16
+ * Get action description
17
+ */
18
+ public get Description(): string {
19
+ return 'Retrieves comprehensive analytics for a Facebook page including views, engagement, demographics, and performance metrics';
193
20
  }
194
- }
195
-
196
- /**
197
- * Get default page metrics based on options
198
- */
199
- private getDefaultPageMetrics(includeDemographics: boolean, includeVideo: boolean): string[] {
200
- const metrics = [
201
- // Page Views
202
- 'page_views_total',
203
- 'page_views_logged_in_unique',
204
- 'page_views_by_site_logged_in_unique',
205
-
206
- // Page Likes
207
- 'page_fan_adds',
208
- 'page_fan_removes',
209
- 'page_fan_adds_unique',
210
- 'page_fans',
211
-
212
- // Engagement
213
- 'page_engaged_users',
214
- 'page_post_engagements',
215
- 'page_consumptions',
216
- 'page_consumptions_unique',
217
- 'page_places_checkin_total',
218
-
219
- // Impressions
220
- 'page_impressions',
221
- 'page_impressions_unique',
222
- 'page_impressions_paid',
223
- 'page_impressions_paid_unique',
224
- 'page_impressions_organic',
225
- 'page_impressions_organic_unique',
226
-
227
- // Posts
228
- 'page_posts_impressions',
229
- 'page_posts_impressions_unique',
230
-
231
- // Actions
232
- 'page_actions_post_reactions_total',
233
- 'page_actions_post_reactions_like_total',
234
- 'page_actions_post_reactions_love_total',
235
- 'page_actions_post_reactions_wow_total',
236
- 'page_actions_post_reactions_haha_total',
237
- 'page_actions_post_reactions_sorry_total',
238
- 'page_actions_post_reactions_anger_total',
239
-
240
- // CTA Clicks
241
- 'page_total_actions',
242
- 'page_cta_clicks_logged_in_total',
243
-
244
- // Messages
245
- 'page_messages_total_messaging_connections',
246
- 'page_messages_new_conversations',
247
-
248
- // Negative Feedback
249
- 'page_negative_feedback',
250
- 'page_negative_feedback_unique',
251
- ];
252
-
253
- if (includeDemographics) {
254
- metrics.push(
255
- 'page_fans_gender_age',
256
- 'page_fans_country',
257
- 'page_fans_city',
258
- 'page_fans_locale',
259
- 'page_impressions_by_age_gender_unique',
260
- 'page_engaged_users_by_age_gender'
261
- );
21
+
22
+ /**
23
+ * Define the parameters for this action
24
+ */
25
+ public get Params(): ActionParam[] {
26
+ return [
27
+ ...this.commonSocialParams,
28
+ {
29
+ Name: 'PageID',
30
+ Type: 'Input',
31
+ Value: null,
32
+ },
33
+ {
34
+ Name: 'MetricTypes',
35
+ Type: 'Input',
36
+ Value: null,
37
+ },
38
+ {
39
+ Name: 'Period',
40
+ Type: 'Input',
41
+ Value: 'day',
42
+ },
43
+ {
44
+ Name: 'StartDate',
45
+ Type: 'Input',
46
+ Value: null,
47
+ },
48
+ {
49
+ Name: 'EndDate',
50
+ Type: 'Input',
51
+ Value: null,
52
+ },
53
+ {
54
+ Name: 'IncludeDemographics',
55
+ Type: 'Input',
56
+ Value: true,
57
+ },
58
+ {
59
+ Name: 'IncludeVideoMetrics',
60
+ Type: 'Input',
61
+ Value: true,
62
+ },
63
+ {
64
+ Name: 'CompareWithPrevious',
65
+ Type: 'Input',
66
+ Value: false,
67
+ }
68
+ ];
262
69
  }
263
70
 
264
- if (includeVideo) {
265
- metrics.push(
266
- 'page_video_views',
267
- 'page_video_views_paid',
268
- 'page_video_views_organic',
269
- 'page_video_views_autoplayed',
270
- 'page_video_views_click_to_play',
271
- 'page_video_views_unique',
272
- 'page_video_repeat_views',
273
- 'page_video_complete_views_30s',
274
- 'page_video_complete_views_30s_paid',
275
- 'page_video_complete_views_30s_organic',
276
- 'page_video_views_10s',
277
- 'page_video_views_10s_paid',
278
- 'page_video_views_10s_organic'
279
- );
71
+ /**
72
+ * Execute the action
73
+ */
74
+ protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
75
+ const { Params, ContextUser } = params;
76
+
77
+ try {
78
+ // Validate required parameters
79
+ const companyIntegrationId = this.getParamValue(Params, 'CompanyIntegrationID');
80
+ const pageId = this.getParamValue(Params, 'PageID');
81
+
82
+ if (!companyIntegrationId) {
83
+ return {
84
+ Success: false,
85
+ Message: 'CompanyIntegrationID is required',
86
+ ResultCode: 'INVALID_TOKEN'
87
+ };
88
+ }
89
+
90
+ if (!pageId) {
91
+ return {
92
+ Success: false,
93
+ Message: 'PageID is required',
94
+ ResultCode: 'MISSING_REQUIRED_PARAM'
95
+ };
96
+ }
97
+
98
+ // Initialize OAuth
99
+ if (!await this.initializeOAuth(companyIntegrationId)) {
100
+ return {
101
+ Success: false,
102
+ Message: 'Failed to initialize Facebook OAuth connection',
103
+ ResultCode: 'INVALID_TOKEN'
104
+ };
105
+ }
106
+
107
+ // Get parameters
108
+ const metricTypes = this.getParamValue(Params, 'MetricTypes') as string[];
109
+ const period = this.getParamValue(Params, 'Period') as string || 'day';
110
+ const startDate = this.getParamValue(Params, 'StartDate') as string;
111
+ const endDate = this.getParamValue(Params, 'EndDate') as string;
112
+ const includeDemographics = this.getParamValue(Params, 'IncludeDemographics') !== false;
113
+ const includeVideoMetrics = this.getParamValue(Params, 'IncludeVideoMetrics') !== false;
114
+ const compareWithPrevious = this.getParamValue(Params, 'CompareWithPrevious') as boolean;
115
+
116
+ LogStatus(`Retrieving insights for Facebook page ${pageId}...`);
117
+
118
+ // Get page access token
119
+ const pageToken = await this.getPageAccessToken(pageId);
120
+
121
+ // Build metrics list
122
+ const metrics = metricTypes && metricTypes.length > 0
123
+ ? metricTypes
124
+ : this.getDefaultPageMetrics(includeDemographics, includeVideoMetrics);
125
+
126
+ // Build date range parameters
127
+ const dateParams: any = {};
128
+ if (startDate && endDate) {
129
+ dateParams.since = new Date(startDate).toISOString();
130
+ dateParams.until = new Date(endDate).toISOString();
131
+ } else if (period !== 'lifetime') {
132
+ // Default to last 30 days if no date range specified
133
+ const end = new Date();
134
+ const start = new Date();
135
+ start.setDate(start.getDate() - 30);
136
+ dateParams.since = start.toISOString();
137
+ dateParams.until = end.toISOString();
138
+ }
139
+
140
+ // Get page insights
141
+ const insightsResponse = await axios.get(
142
+ `${this.apiBaseUrl}/${pageId}/insights`,
143
+ {
144
+ params: {
145
+ access_token: pageToken,
146
+ metric: metrics.join(','),
147
+ period: period,
148
+ ...dateParams
149
+ }
150
+ }
151
+ );
152
+
153
+ const insights: FacebookInsight[] = insightsResponse.data.data || [];
154
+
155
+ // Get page info for context
156
+ const pageInfoResponse = await axios.get(
157
+ `${this.apiBaseUrl}/${pageId}`,
158
+ {
159
+ params: {
160
+ access_token: pageToken,
161
+ fields: 'id,name,category,fan_count,followers_count,about,cover,picture'
162
+ }
163
+ }
164
+ );
165
+
166
+ const pageInfo = pageInfoResponse.data;
167
+
168
+ // Process insights into categories
169
+ const processedInsights = this.categorizeInsights(insights);
170
+
171
+ // Get comparison data if requested
172
+ let comparison = null;
173
+ if (compareWithPrevious && startDate && endDate) {
174
+ comparison = await this.getComparisonData(
175
+ pageId,
176
+ pageToken,
177
+ metrics,
178
+ period,
179
+ new Date(startDate),
180
+ new Date(endDate)
181
+ );
182
+ }
183
+
184
+ // Calculate summary metrics
185
+ const summary = this.calculateSummaryMetrics(processedInsights, pageInfo);
186
+
187
+ LogStatus(`Successfully retrieved insights for page ${pageId}`);
188
+
189
+ return {
190
+ Success: true,
191
+ Message: 'Page insights retrieved successfully',
192
+ ResultCode: 'SUCCESS',
193
+ Params
194
+ };
195
+
196
+ } catch (error) {
197
+ LogError(`Failed to get Facebook page insights: ${error instanceof Error ? error.message : 'Unknown error'}`);
198
+
199
+ if (this.isAuthError(error)) {
200
+ return this.handleOAuthError(error);
201
+ }
202
+
203
+ return {
204
+ Success: false,
205
+ Message: error instanceof Error ? error.message : 'Unknown error occurred',
206
+ ResultCode: 'ERROR'
207
+ };
208
+ }
280
209
  }
281
210
 
282
- return metrics;
283
- }
284
-
285
- /**
286
- * Categorize insights by type for better organization
287
- */
288
- private categorizeInsights(insights: FacebookInsight[]): Record<string, any> {
289
- const categories: Record<string, any> = {
290
- pageViews: {},
291
- engagement: {},
292
- likes: {},
293
- impressions: {},
294
- posts: {},
295
- reactions: {},
296
- demographics: {},
297
- video: {},
298
- messages: {},
299
- negativeFeedback: {},
300
- };
301
-
302
- for (const insight of insights) {
303
- const name = insight.name;
304
- const value = insight.values?.[0]?.value;
305
-
306
- if (name.includes('page_views')) {
307
- categories.pageViews[name] = value;
308
- } else if (name.includes('engaged') || name.includes('engagement')) {
309
- categories.engagement[name] = value;
310
- } else if (name.includes('fan') || name === 'page_fans') {
311
- categories.likes[name] = value;
312
- } else if (name.includes('impressions')) {
313
- categories.impressions[name] = value;
314
- } else if (name.includes('posts')) {
315
- categories.posts[name] = value;
316
- } else if (name.includes('reactions')) {
317
- categories.reactions[name] = value;
318
- } else if (name.includes('gender') || name.includes('country') || name.includes('city') || name.includes('locale')) {
319
- categories.demographics[name] = value;
320
- } else if (name.includes('video')) {
321
- categories.video[name] = value;
322
- } else if (name.includes('messages')) {
323
- categories.messages[name] = value;
324
- } else if (name.includes('negative')) {
325
- categories.negativeFeedback[name] = value;
326
- }
211
+ /**
212
+ * Get default page metrics based on options
213
+ */
214
+ private getDefaultPageMetrics(includeDemographics: boolean, includeVideo: boolean): string[] {
215
+ const metrics = [
216
+ // Page Views
217
+ 'page_views_total',
218
+ 'page_views_logged_in_unique',
219
+ 'page_views_by_site_logged_in_unique',
220
+
221
+ // Page Likes
222
+ 'page_fan_adds',
223
+ 'page_fan_removes',
224
+ 'page_fan_adds_unique',
225
+ 'page_fans',
226
+
227
+ // Engagement
228
+ 'page_engaged_users',
229
+ 'page_post_engagements',
230
+ 'page_consumptions',
231
+ 'page_consumptions_unique',
232
+ 'page_places_checkin_total',
233
+
234
+ // Impressions
235
+ 'page_impressions',
236
+ 'page_impressions_unique',
237
+ 'page_impressions_paid',
238
+ 'page_impressions_paid_unique',
239
+ 'page_impressions_organic',
240
+ 'page_impressions_organic_unique',
241
+
242
+ // Posts
243
+ 'page_posts_impressions',
244
+ 'page_posts_impressions_unique',
245
+
246
+ // Actions
247
+ 'page_actions_post_reactions_total',
248
+ 'page_actions_post_reactions_like_total',
249
+ 'page_actions_post_reactions_love_total',
250
+ 'page_actions_post_reactions_wow_total',
251
+ 'page_actions_post_reactions_haha_total',
252
+ 'page_actions_post_reactions_sorry_total',
253
+ 'page_actions_post_reactions_anger_total',
254
+
255
+ // CTA Clicks
256
+ 'page_total_actions',
257
+ 'page_cta_clicks_logged_in_total',
258
+
259
+ // Messages
260
+ 'page_messages_total_messaging_connections',
261
+ 'page_messages_new_conversations',
262
+
263
+ // Negative Feedback
264
+ 'page_negative_feedback',
265
+ 'page_negative_feedback_unique'
266
+ ];
267
+
268
+ if (includeDemographics) {
269
+ metrics.push(
270
+ 'page_fans_gender_age',
271
+ 'page_fans_country',
272
+ 'page_fans_city',
273
+ 'page_fans_locale',
274
+ 'page_impressions_by_age_gender_unique',
275
+ 'page_engaged_users_by_age_gender'
276
+ );
277
+ }
278
+
279
+ if (includeVideo) {
280
+ metrics.push(
281
+ 'page_video_views',
282
+ 'page_video_views_paid',
283
+ 'page_video_views_organic',
284
+ 'page_video_views_autoplayed',
285
+ 'page_video_views_click_to_play',
286
+ 'page_video_views_unique',
287
+ 'page_video_repeat_views',
288
+ 'page_video_complete_views_30s',
289
+ 'page_video_complete_views_30s_paid',
290
+ 'page_video_complete_views_30s_organic',
291
+ 'page_video_views_10s',
292
+ 'page_video_views_10s_paid',
293
+ 'page_video_views_10s_organic'
294
+ );
295
+ }
296
+
297
+ return metrics;
327
298
  }
328
299
 
329
- return categories;
330
- }
331
-
332
- /**
333
- * Calculate summary metrics
334
- */
335
- private calculateSummaryMetrics(insights: Record<string, any>, pageInfo: any): any {
336
- const summary: any = {
337
- totalFans: pageInfo.fan_count || 0,
338
- totalFollowers: pageInfo.followers_count || 0,
339
- totalPageViews: insights.pageViews.page_views_total || 0,
340
- totalEngagements: insights.engagement.page_engaged_users || 0,
341
- totalImpressions: insights.impressions.page_impressions || 0,
342
- netNewFans: (insights.likes.page_fan_adds || 0) - (insights.likes.page_fan_removes || 0),
343
- };
344
-
345
- // Calculate engagement rate if we have the data
346
- if (summary.totalImpressions > 0) {
347
- summary.engagementRate = (summary.totalEngagements / summary.totalImpressions) * 100;
300
+ /**
301
+ * Categorize insights by type for better organization
302
+ */
303
+ private categorizeInsights(insights: FacebookInsight[]): Record<string, any> {
304
+ const categories: Record<string, any> = {
305
+ pageViews: {},
306
+ engagement: {},
307
+ likes: {},
308
+ impressions: {},
309
+ posts: {},
310
+ reactions: {},
311
+ demographics: {},
312
+ video: {},
313
+ messages: {},
314
+ negativeFeedback: {}
315
+ };
316
+
317
+ for (const insight of insights) {
318
+ const name = insight.name;
319
+ const value = insight.values?.[0]?.value;
320
+
321
+ if (name.includes('page_views')) {
322
+ categories.pageViews[name] = value;
323
+ } else if (name.includes('engaged') || name.includes('engagement')) {
324
+ categories.engagement[name] = value;
325
+ } else if (name.includes('fan') || name === 'page_fans') {
326
+ categories.likes[name] = value;
327
+ } else if (name.includes('impressions')) {
328
+ categories.impressions[name] = value;
329
+ } else if (name.includes('posts')) {
330
+ categories.posts[name] = value;
331
+ } else if (name.includes('reactions')) {
332
+ categories.reactions[name] = value;
333
+ } else if (name.includes('gender') || name.includes('country') || name.includes('city') || name.includes('locale')) {
334
+ categories.demographics[name] = value;
335
+ } else if (name.includes('video')) {
336
+ categories.video[name] = value;
337
+ } else if (name.includes('messages')) {
338
+ categories.messages[name] = value;
339
+ } else if (name.includes('negative')) {
340
+ categories.negativeFeedback[name] = value;
341
+ }
342
+ }
343
+
344
+ return categories;
348
345
  }
349
346
 
350
- // Add reaction breakdown
351
- const reactions = insights.reactions;
352
- if (reactions) {
353
- summary.reactionBreakdown = {
354
- total: reactions.page_actions_post_reactions_total || 0,
355
- like: reactions.page_actions_post_reactions_like_total || 0,
356
- love: reactions.page_actions_post_reactions_love_total || 0,
357
- wow: reactions.page_actions_post_reactions_wow_total || 0,
358
- haha: reactions.page_actions_post_reactions_haha_total || 0,
359
- sorry: reactions.page_actions_post_reactions_sorry_total || 0,
360
- anger: reactions.page_actions_post_reactions_anger_total || 0,
361
- };
347
+ /**
348
+ * Calculate summary metrics
349
+ */
350
+ private calculateSummaryMetrics(insights: Record<string, any>, pageInfo: any): any {
351
+ const summary: any = {
352
+ totalFans: pageInfo.fan_count || 0,
353
+ totalFollowers: pageInfo.followers_count || 0,
354
+ totalPageViews: insights.pageViews.page_views_total || 0,
355
+ totalEngagements: insights.engagement.page_engaged_users || 0,
356
+ totalImpressions: insights.impressions.page_impressions || 0,
357
+ netNewFans: (insights.likes.page_fan_adds || 0) - (insights.likes.page_fan_removes || 0)
358
+ };
359
+
360
+ // Calculate engagement rate if we have the data
361
+ if (summary.totalImpressions > 0) {
362
+ summary.engagementRate = (summary.totalEngagements / summary.totalImpressions) * 100;
363
+ }
364
+
365
+ // Add reaction breakdown
366
+ const reactions = insights.reactions;
367
+ if (reactions) {
368
+ summary.reactionBreakdown = {
369
+ total: reactions.page_actions_post_reactions_total || 0,
370
+ like: reactions.page_actions_post_reactions_like_total || 0,
371
+ love: reactions.page_actions_post_reactions_love_total || 0,
372
+ wow: reactions.page_actions_post_reactions_wow_total || 0,
373
+ haha: reactions.page_actions_post_reactions_haha_total || 0,
374
+ sorry: reactions.page_actions_post_reactions_sorry_total || 0,
375
+ anger: reactions.page_actions_post_reactions_anger_total || 0
376
+ };
377
+ }
378
+
379
+ return summary;
362
380
  }
363
381
 
364
- return summary;
365
- }
366
-
367
- /**
368
- * Get comparison data for previous period
369
- */
370
- private async getComparisonData(
371
- pageId: string,
372
- pageToken: string,
373
- metrics: string[],
374
- period: string,
375
- startDate: Date,
376
- endDate: Date
377
- ): Promise<any> {
378
- try {
379
- const duration = endDate.getTime() - startDate.getTime();
380
- const previousStart = new Date(startDate.getTime() - duration);
381
- const previousEnd = new Date(startDate.getTime());
382
-
383
- const response = await axios.get(`${this.apiBaseUrl}/${pageId}/insights`, {
384
- params: {
385
- access_token: pageToken,
386
- metric: metrics.join(','),
387
- period: period,
388
- since: previousStart.toISOString(),
389
- until: previousEnd.toISOString(),
390
- },
391
- });
392
-
393
- const previousInsights = response.data.data || [];
394
- const processedPrevious = this.categorizeInsights(previousInsights);
395
-
396
- return {
397
- period: {
398
- start: previousStart.toISOString(),
399
- end: previousEnd.toISOString(),
400
- },
401
- insights: processedPrevious,
402
- };
403
- } catch (error) {
404
- LogError(`Failed to get comparison data: ${error}`);
405
- return null;
382
+ /**
383
+ * Get comparison data for previous period
384
+ */
385
+ private async getComparisonData(
386
+ pageId: string,
387
+ pageToken: string,
388
+ metrics: string[],
389
+ period: string,
390
+ startDate: Date,
391
+ endDate: Date
392
+ ): Promise<any> {
393
+ try {
394
+ const duration = endDate.getTime() - startDate.getTime();
395
+ const previousStart = new Date(startDate.getTime() - duration);
396
+ const previousEnd = new Date(startDate.getTime());
397
+
398
+ const response = await axios.get(
399
+ `${this.apiBaseUrl}/${pageId}/insights`,
400
+ {
401
+ params: {
402
+ access_token: pageToken,
403
+ metric: metrics.join(','),
404
+ period: period,
405
+ since: previousStart.toISOString(),
406
+ until: previousEnd.toISOString()
407
+ }
408
+ }
409
+ );
410
+
411
+ const previousInsights = response.data.data || [];
412
+ const processedPrevious = this.categorizeInsights(previousInsights);
413
+
414
+ return {
415
+ period: {
416
+ start: previousStart.toISOString(),
417
+ end: previousEnd.toISOString()
418
+ },
419
+ insights: processedPrevious
420
+ };
421
+ } catch (error) {
422
+ LogError(`Failed to get comparison data: ${error}`);
423
+ return null;
424
+ }
406
425
  }
407
- }
408
- }
426
+
427
+
428
+ }