UNPKG

@memberjunction/actions-bizapps-social

Version:

Social Media Actions for MemberJunction - Twitter, LinkedIn, Facebook, Instagram, TikTok, YouTube, HootSuite, Buffer

270 lines 11.1 kB
"use strict"; 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; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.InstagramCreatePostAction = void 0; const global_1 = require("@memberjunction/global"); const instagram_base_action_1 = require("../instagram-base.action"); const core_1 = require("@memberjunction/core"); const actions_1 = require("@memberjunction/actions"); /** * Creates a new Instagram post (feed post, carousel, or reel). * Supports images and videos with captions, hashtags, and location tagging. */ let InstagramCreatePostAction = class InstagramCreatePostAction extends instagram_base_action_1.InstagramBaseAction { async InternalRunAction(params) { try { const companyIntegrationId = this.getParamValue(params.Params, 'CompanyIntegrationID'); const content = this.getParamValue(params.Params, 'Content'); const mediaFiles = this.getParamValue(params.Params, 'MediaFiles'); const postType = this.getParamValue(params.Params, 'PostType') || 'FEED'; const locationId = this.getParamValue(params.Params, 'LocationID'); const taggedUsers = this.getParamValue(params.Params, 'TaggedUsers'); const scheduledTime = this.getParamValue(params.Params, 'ScheduledTime'); // Initialize OAuth if (!await this.initializeOAuth(companyIntegrationId)) { return { Success: false, Message: 'Failed to initialize Instagram authentication', ResultCode: 'AUTH_FAILED' }; } // Validate inputs if (!mediaFiles || mediaFiles.length === 0) { return { Success: false, Message: 'At least one media file is required for Instagram posts', ResultCode: 'MISSING_MEDIA' }; } // Instagram has specific requirements for different post types if (postType === 'CAROUSEL' && mediaFiles.length < 2) { return { Success: false, Message: 'Carousel posts require at least 2 media files', ResultCode: 'INVALID_CAROUSEL' }; } if (postType === 'REELS' && (!mediaFiles[0].mimeType.startsWith('video/') || mediaFiles.length > 1)) { return { Success: false, Message: 'Reels require exactly one video file', ResultCode: 'INVALID_REEL' }; } // Handle scheduled posts differently if (scheduledTime) { const scheduleDate = new Date(scheduledTime); if (scheduleDate <= new Date()) { return { Success: false, Message: 'Scheduled time must be in the future', ResultCode: 'INVALID_SCHEDULE_TIME' }; } // Instagram requires Facebook Creator Studio for scheduling return { Success: false, Message: 'Instagram post scheduling requires Facebook Creator Studio integration', ResultCode: 'SCHEDULING_NOT_SUPPORTED' }; } let postId; if (postType === 'CAROUSEL') { postId = await this.createCarouselPost(mediaFiles, content, locationId, taggedUsers); } else if (postType === 'REELS') { postId = await this.createReelPost(mediaFiles[0], content, locationId, taggedUsers); } else { postId = await this.createFeedPost(mediaFiles[0], content, locationId, taggedUsers); } // Store result in output params const outputParams = [...params.Params]; outputParams.push({ Name: 'PostID', Type: 'Output', Value: postId }); outputParams.push({ Name: 'Permalink', Type: 'Output', Value: `https://www.instagram.com/p/${postId}/` }); outputParams.push({ Name: 'PostType', Type: 'Output', Value: postType }); return { Success: true, Message: `Instagram ${postType.toLowerCase()} created successfully`, ResultCode: 'SUCCESS', Params: outputParams }; } catch (error) { (0, core_1.LogError)('Failed to create Instagram post', error); if (error.code === 'RATE_LIMIT') { return { Success: false, Message: 'Instagram API rate limit exceeded. Please try again later.', ResultCode: 'RATE_LIMIT' }; } if (error.code === 'INVALID_MEDIA') { return { Success: false, Message: error.message, ResultCode: 'INVALID_MEDIA' }; } return { Success: false, Message: `Failed to create Instagram post: ${error.message}`, ResultCode: 'ERROR' }; } } /** * Create a standard feed post (single image or video) */ async createFeedPost(mediaFile, caption, locationId, taggedUsers) { // Add metadata to media file mediaFile.metadata = { caption }; // Upload media and get container ID const containerId = await this.uploadSingleMedia(mediaFile); // Wait for media to be processed await this.waitForMediaContainer(containerId); // Add additional parameters if provided const publishParams = { creation_id: containerId, access_token: this.getAccessToken() }; if (locationId) { publishParams.location_id = locationId; } if (taggedUsers && taggedUsers.length > 0) { publishParams.user_tags = taggedUsers.map(userId => ({ username: userId, x: 0.5, // Center of image y: 0.5 })); } // Publish the post const response = await this.makeInstagramRequest(`${this.instagramBusinessAccountId}/media_publish`, 'POST', publishParams); return response.id; } /** * Create a carousel post (multiple images/videos) */ async createCarouselPost(mediaFiles, caption, locationId, taggedUsers) { // Upload all media items as carousel items const containerIds = []; for (const file of mediaFiles.slice(0, 10)) { // Instagram allows max 10 items file.filename = `carousel_${file.filename}`; // Mark as carousel item const containerId = await this.uploadSingleMedia(file); containerIds.push(containerId); } // Wait for all media to be processed await Promise.all(containerIds.map(id => this.waitForMediaContainer(id))); // Create carousel container const carouselParams = { media_type: 'CAROUSEL', children: containerIds, caption: caption, access_token: this.getAccessToken() }; if (locationId) { carouselParams.location_id = locationId; } const carouselResponse = await this.makeInstagramRequest(`${this.instagramBusinessAccountId}/media`, 'POST', carouselParams); // Wait for carousel container to be ready await this.waitForMediaContainer(carouselResponse.id); // Publish the carousel const publishResponse = await this.makeInstagramRequest(`${this.instagramBusinessAccountId}/media_publish`, 'POST', { creation_id: carouselResponse.id, access_token: this.getAccessToken() }); return publishResponse.id; } /** * Create a Reel post */ async createReelPost(videoFile, caption, locationId, taggedUsers) { // Validate video duration (Reels must be 90 seconds or less) // In production, you'd check the actual video duration // Add metadata videoFile.metadata = { caption, media_type: 'REELS' }; // Upload video const containerId = await this.uploadSingleMedia(videoFile); // Wait for video to be processed (videos take longer) await this.waitForMediaContainer(containerId, 300000); // 5 minute timeout for videos // Publish the reel const publishParams = { creation_id: containerId, access_token: this.getAccessToken() }; if (locationId) { publishParams.location_id = locationId; } const response = await this.makeInstagramRequest(`${this.instagramBusinessAccountId}/media_publish`, 'POST', publishParams); return response.id; } /** * Define the parameters for this action */ get Params() { return [ ...this.commonSocialParams, { Name: 'Content', Type: 'Input', Value: null, }, { Name: 'MediaFiles', Type: 'Input', Value: null, }, { Name: 'PostType', Type: 'Input', Value: 'FEED', }, { Name: 'LocationID', Type: 'Input', Value: null, }, { Name: 'TaggedUsers', Type: 'Input', Value: null, }, { Name: 'ScheduledTime', Type: 'Input', Value: null, } ]; } /** * Get the description for this action */ get Description() { return 'Creates a new Instagram post with images or videos. Supports feed posts, carousels, and reels.'; } }; exports.InstagramCreatePostAction = InstagramCreatePostAction; exports.InstagramCreatePostAction = InstagramCreatePostAction = __decorate([ (0, global_1.RegisterClass)(actions_1.BaseAction, 'Instagram - Create Post') ], InstagramCreatePostAction); //# sourceMappingURL=create-post.action.js.map