@memberjunction/actions-bizapps-social 2.111.1 → 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
@@ -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/core';
5
+ import { LogStatus, LogError } from '@memberjunction/global';
6
6
  import axios from 'axios';
7
7
  import { BaseAction } from '@memberjunction/actions';
8
8
 
@@ -12,417 +12,397 @@ 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
- }
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
+ }
21
89
 
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
- ];
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
+ };
69
193
  }
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 = 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
- }
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
+ );
209
262
  }
210
263
 
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;
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
+ );
298
280
  }
299
281
 
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;
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
+ }
345
327
  }
346
328
 
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;
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;
380
348
  }
381
349
 
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
- }
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
+ };
425
362
  }
426
363
 
427
-
428
- }
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;
406
+ }
407
+ }
408
+ }