@memberjunction/actions-bizapps-social
Version:
Social Media Actions for MemberJunction - Twitter, LinkedIn, Facebook, Instagram, TikTok, YouTube, HootSuite, Buffer
249 lines (222 loc) • 9.45 kB
text/typescript
import { RegisterClass } from '@memberjunction/global';
import { InstagramBaseAction } from '../instagram-base.action';
import { ActionParam, ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
import { LogError } from '@memberjunction/core';
import { BaseAction } from '@memberjunction/actions';
/**
* Schedules an Instagram post for future publication.
* Note: Instagram API has limited native scheduling support. This action provides
* scheduling information that needs to be integrated with Facebook Creator Studio
* or third-party scheduling tools.
*/
(BaseAction, 'Instagram - Schedule Post')
export class InstagramSchedulePostAction extends InstagramBaseAction {
protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
try {
const companyIntegrationId = this.getParamValue(params.Params, 'CompanyIntegrationID');
const content = this.getParamValue(params.Params, 'Content');
const mediaUrls = this.getParamValue(params.Params, 'MediaUrls') as string[];
const scheduledTime = this.getParamValue(params.Params, 'ScheduledTime');
const postType = this.getParamValue(params.Params, 'PostType') || 'FEED';
const locationId = this.getParamValue(params.Params, 'LocationID');
const taggedUsers = this.getParamValue(params.Params, 'TaggedUsers') as string[];
const firstComment = this.getParamValue(params.Params, 'FirstComment');
// Initialize OAuth
if (!await this.initializeOAuth(companyIntegrationId)) {
return {
Success: false,
Message: 'Failed to initialize Instagram authentication',
ResultCode: 'AUTH_FAILED'
};
}
// Validate inputs
if (!scheduledTime) {
return {
Success: false,
Message: 'ScheduledTime is required',
ResultCode: 'MISSING_PARAMS'
};
}
if (!mediaUrls || mediaUrls.length === 0) {
return {
Success: false,
Message: 'At least one media URL is required',
ResultCode: 'MISSING_MEDIA'
};
}
// Validate scheduled time
const scheduleDate = new Date(scheduledTime);
const now = new Date();
if (scheduleDate <= now) {
return {
Success: false,
Message: 'Scheduled time must be in the future',
ResultCode: 'INVALID_SCHEDULE_TIME'
};
}
// Instagram requires scheduling at least 10 minutes in the future
const minScheduleTime = new Date(now.getTime() + 10 * 60 * 1000);
if (scheduleDate < minScheduleTime) {
return {
Success: false,
Message: 'Posts must be scheduled at least 10 minutes in the future',
ResultCode: 'SCHEDULE_TOO_SOON'
};
}
// Instagram limits scheduling to 75 days in the future
const maxScheduleTime = new Date(now.getTime() + 75 * 24 * 60 * 60 * 1000);
if (scheduleDate > maxScheduleTime) {
return {
Success: false,
Message: 'Posts cannot be scheduled more than 75 days in the future',
ResultCode: 'SCHEDULE_TOO_FAR'
};
}
// Create scheduling payload
const schedulingData = {
content,
mediaUrls,
scheduledTime: scheduleDate.toISOString(),
postType,
locationId,
taggedUsers,
firstComment,
accountId: this.instagramBusinessAccountId,
pageId: this.facebookPageId
};
// Instagram doesn't have a direct scheduling API endpoint
// Instead, we need to use Facebook's Content Publishing API
// or integrate with Creator Studio
// For now, we'll store the scheduling data and return instructions
const schedulingId = this.generateSchedulingId();
// In a production environment, you would:
// 1. Store this in a database
// 2. Set up a cron job or scheduler to publish at the scheduled time
// 3. Or integrate with Facebook Creator Studio API
// Store scheduling data (this is a placeholder - implement your storage solution)
await this.storeSchedulingData(schedulingId, schedulingData);
// Store result in output params
const outputParams = [...params.Params];
outputParams.push({
Name: 'ResultData',
Type: 'Output',
Value: JSON.stringify({
schedulingId,
scheduledTime: scheduleDate.toISOString(),
postType,
mediaCount: mediaUrls.length,
instructions: {
creatorStudio: 'This post can be managed in Facebook Creator Studio',
api: 'Use the scheduling ID to retrieve and publish this post at the scheduled time',
webhook: 'Set up a webhook to be notified when it\'s time to publish'
},
schedulingData
})
});
return {
Success: true,
Message: 'Instagram post scheduled successfully',
ResultCode: 'SUCCESS',
Params: outputParams
};
} catch (error: any) {
LogError('Failed to schedule Instagram post', error);
if (error.code === 'RATE_LIMIT') {
return {
Success: false,
Message: 'Instagram API rate limit exceeded. Please try again later.',
ResultCode: 'RATE_LIMIT'
};
}
return {
Success: false,
Message: `Failed to schedule post: ${error.message}`,
ResultCode: 'ERROR'
};
}
}
/**
* Generate a unique scheduling ID
*/
private generateSchedulingId(): string {
const timestamp = Date.now();
const random = Math.random().toString(36).substring(2, 9);
return `ig_schedule_${timestamp}_${random}`;
}
/**
* Store scheduling data (placeholder - implement based on your storage solution)
*/
private async storeSchedulingData(schedulingId: string, data: any): Promise<void> {
// In a real implementation, this would:
// 1. Store in a database (e.g., in a ScheduledPosts table)
// 2. Set up a scheduled job in your job queue
// 3. Or send to a scheduling service
// For demonstration, we'll just log it
LogError('Scheduling data would be stored:', schedulingId, data);
// You could also use MemberJunction entities to store this
// For example, create a "Social Media Scheduled Posts" entity
// and save the scheduling data there
}
/**
* Create a scheduled post using Facebook Creator Studio API
* Note: This is a conceptual implementation as Creator Studio API
* has specific requirements and approval process
*/
private async createCreatorStudioScheduledPost(data: any): Promise<string> {
// This would require:
// 1. Creator Studio API access
// 2. Additional permissions
// 3. Different API endpoints
// For now, we return a placeholder
throw new Error('Creator Studio integration not implemented. Use the scheduling data to create your own scheduling solution.');
}
/**
* Define the parameters for this action
*/
public get Params(): ActionParam[] {
return [
...this.commonSocialParams,
{
Name: 'Content',
Type: 'Input',
Value: null
},
{
Name: 'MediaUrls',
Type: 'Input',
Value: null
},
{
Name: 'ScheduledTime',
Type: 'Input',
Value: null
},
{
Name: 'PostType',
Type: 'Input',
Value: 'FEED'
},
{
Name: 'LocationID',
Type: 'Input',
Value: null
},
{
Name: 'TaggedUsers',
Type: 'Input',
Value: null
},
{
Name: 'FirstComment',
Type: 'Input',
Value: null
}
];
}
/**
* Get the description for this action
*/
public get Description(): string {
return 'Schedules an Instagram post for future publication. Returns scheduling data that can be used with Creator Studio or custom scheduling solutions.';
}
}