@memberjunction/actions-bizapps-social
Version:
Social Media Actions for MemberJunction - Twitter, LinkedIn, Facebook, Instagram, TikTok, YouTube, HootSuite, Buffer
214 lines • 8.71 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { RegisterClass } from '@memberjunction/global';
import { FacebookBaseAction } from '../facebook-base.action.js';
import { LogStatus, LogError } from '@memberjunction/core';
import { BaseAction } from '@memberjunction/actions';
/**
* Retrieves posts from a Facebook page with optional date filtering.
* Includes post content, media, and basic engagement metrics.
*/
let FacebookGetPagePostsAction = class FacebookGetPagePostsAction extends FacebookBaseAction {
/**
* Get action description
*/
get Description() {
return 'Retrieves posts from a Facebook page with optional date range filtering and pagination';
}
/**
* Define the parameters for this action
*/
get Params() {
return [
...this.commonSocialParams,
{
Name: 'PageID',
Type: 'Input',
Value: null,
},
{
Name: 'StartDate',
Type: 'Input',
Value: null,
},
{
Name: 'EndDate',
Type: 'Input',
Value: null,
},
{
Name: 'Limit',
Type: 'Input',
Value: 100,
},
{
Name: 'MaxResults',
Type: 'Input',
Value: null,
},
{
Name: 'IncludeUnpublished',
Type: 'Input',
Value: false,
},
{
Name: 'IncludeInsights',
Type: 'Input',
Value: true,
}
];
}
/**
* Execute the action
*/
async InternalRunAction(params) {
const { Params, ContextUser } = params;
try {
// Validate required parameters
const companyIntegrationId = this.getParamValue(Params, 'CompanyIntegrationID');
const pageId = this.getParamValue(Params, 'PageID');
if (!companyIntegrationId) {
return {
Success: false,
Message: 'CompanyIntegrationID is required',
ResultCode: 'INVALID_TOKEN'
};
}
if (!pageId) {
return {
Success: false,
Message: 'PageID is required',
ResultCode: 'MISSING_REQUIRED_PARAM'
};
}
// Initialize OAuth
if (!await this.initializeOAuth(companyIntegrationId, params)) {
return {
Success: false,
Message: 'Failed to initialize Facebook OAuth connection',
ResultCode: 'INVALID_TOKEN'
};
}
// Get parameters
const startDate = this.getParamValue(Params, 'StartDate');
const endDate = this.getParamValue(Params, 'EndDate');
const limit = this.getParamValue(Params, 'Limit') || 100;
const maxResults = this.getParamValue(Params, 'MaxResults');
const includeUnpublished = this.getParamValue(Params, 'IncludeUnpublished');
const includeInsights = this.getParamValue(Params, 'IncludeInsights');
// Build query parameters
const queryParams = {
limit: Math.min(limit, 100), // Facebook max is 100 per request
published: includeUnpublished ? undefined : true
};
if (startDate) {
queryParams.since = new Date(startDate);
}
if (endDate) {
queryParams.until = new Date(endDate);
}
LogStatus(`Retrieving posts from Facebook page ${pageId}...`);
// Get posts with pagination support
let allPosts = await this.getPagePosts(pageId, queryParams);
// If we need more posts and have a maxResults, use pagination
if (maxResults && allPosts.length < maxResults && allPosts.length === queryParams.limit) {
LogStatus(`Fetching additional pages of posts...`);
const pageToken = await this.getPageAccessToken(pageId);
const fields = includeInsights ? this.getPostFields() : this.getPostFieldsWithoutInsights();
allPosts = await this.getPaginatedResults(`${this.apiBaseUrl}/${pageId}/posts`, {
access_token: pageToken,
fields,
...queryParams,
since: queryParams.since ? Math.floor(queryParams.since.getTime() / 1000) : undefined,
until: queryParams.until ? Math.floor(queryParams.until.getTime() / 1000) : undefined
}, maxResults);
}
// Limit results if maxResults specified
if (maxResults && allPosts.length > maxResults) {
allPosts = allPosts.slice(0, maxResults);
}
LogStatus(`Retrieved ${allPosts.length} posts from Facebook page`);
// Normalize posts to common format
const normalizedPosts = allPosts.map(post => this.normalizePost(post));
// Calculate summary statistics
const summary = {
totalPosts: normalizedPosts.length,
dateRange: {
earliest: normalizedPosts.length > 0
? normalizedPosts[normalizedPosts.length - 1].publishedAt
: null,
latest: normalizedPosts.length > 0
? normalizedPosts[0].publishedAt
: null
},
postTypes: this.categorizePostTypes(allPosts),
totalEngagements: normalizedPosts.reduce((sum, post) => sum + (post.analytics?.engagements || 0), 0),
totalImpressions: normalizedPosts.reduce((sum, post) => sum + (post.analytics?.impressions || 0), 0)
};
// Update output parameters
const outputParams = [...Params];
// TODO: Set output parameters based on result
return {
Success: true,
Message: `Successfully retrieved ${normalizedPosts.length} posts`,
ResultCode: 'SUCCESS',
Params: outputParams
};
}
catch (error) {
LogError(`Failed to get Facebook page posts: ${error instanceof Error ? error.message : 'Unknown error'}`);
if (this.isAuthError(error)) {
return this.handleOAuthError(error);
}
return {
Success: false,
Message: error instanceof Error ? error.message : 'Unknown error occurred',
ResultCode: 'ERROR'
};
}
}
/**
* Get post fields without insights (for faster queries or when insights not available)
*/
getPostFieldsWithoutInsights() {
return 'id,message,created_time,updated_time,from,story,permalink_url,attachments,shares,reactions.summary(true),comments.summary(true)';
}
/**
* Categorize posts by type based on attachments
*/
categorizePostTypes(posts) {
const types = {
status: 0,
photo: 0,
video: 0,
link: 0,
event: 0,
offer: 0,
album: 0
};
for (const post of posts) {
if (post.attachments?.data?.[0]?.type) {
const type = post.attachments.data[0].type.toLowerCase();
if (type in types) {
types[type]++;
}
else {
types.status++;
}
}
else {
types.status++;
}
}
return types;
}
};
FacebookGetPagePostsAction = __decorate([
RegisterClass(BaseAction, 'FacebookGetPagePostsAction')
], FacebookGetPagePostsAction);
export { FacebookGetPagePostsAction };
//# sourceMappingURL=get-page-posts.action.js.map