UNPKG

@yaring/n8n-nodes-meta

Version:

N8N node for publishing content to Facebook, Instagram, and Threads with access token authentication. Supports text posts, photos, videos, Reels, carousels, and stories.

382 lines 18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FacebookInstagramThreads = void 0; const n8n_workflow_1 = require("n8n-workflow"); const FacebookInstagramThreadsDescription_1 = require("./FacebookInstagramThreadsDescription"); class FacebookInstagramThreads { constructor() { this.description = { displayName: 'Facebook, Instagram & Threads', name: 'facebookInstagramThreads', icon: 'file:facebook-instagram-threads.svg', group: ['output'], version: 1, subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', description: 'Create and publish content to Facebook, Instagram, and Threads', defaults: { name: 'Facebook, Instagram & Threads', }, inputs: ["main"], outputs: ["main"], usableAsTool: true, credentials: [ { name: 'facebookInstagramThreadsApi', required: true, }, ], requestDefaults: { baseURL: 'https://graph.facebook.com/v23.0', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, }, properties: [ { displayName: 'Resource', name: 'resource', type: 'options', noDataExpression: true, options: [ { name: 'Facebook', value: 'facebook', description: 'Create content on Facebook', }, { name: 'Instagram', value: 'instagram', description: 'Create content on Instagram', }, { name: 'Thread', value: 'threads', description: 'Create content on Threads', }, ], default: 'facebook', }, ...FacebookInstagramThreadsDescription_1.facebookOperations, ...FacebookInstagramThreadsDescription_1.facebookFields, ...FacebookInstagramThreadsDescription_1.instagramOperations, ...FacebookInstagramThreadsDescription_1.instagramFields, ...FacebookInstagramThreadsDescription_1.threadsOperations, ...FacebookInstagramThreadsDescription_1.threadsFields, ], }; } async execute() { var _a, _b; const items = this.getInputData(); const returnData = []; async function handleFacebookOperation(itemIndex, operation) { const targetId = this.getNodeParameter('targetId', itemIndex); let endpoint = ''; let body = {}; switch (operation) { case 'createTextPost': const message = this.getNodeParameter('message', itemIndex); endpoint = `/${targetId}/feed`; body = { message }; break; case 'createPhotoPost': const photoUrl = this.getNodeParameter('photoUrl', itemIndex); const caption = this.getNodeParameter('caption', itemIndex, ''); endpoint = `/${targetId}/photos`; body = { url: photoUrl, ...(caption && { caption }) }; break; case 'createVideoPost': const videoUrl = this.getNodeParameter('videoUrl', itemIndex); const videoDescription = this.getNodeParameter('videoDescription', itemIndex, ''); endpoint = `/${targetId}/videos`; body = { file_url: videoUrl, ...(videoDescription && { description: videoDescription }) }; break; case 'createLinkPost': const linkUrl = this.getNodeParameter('linkUrl', itemIndex); const linkMessage = this.getNodeParameter('linkMessage', itemIndex, ''); endpoint = `/${targetId}/feed`; body = { link: linkUrl, ...(linkMessage && { message: linkMessage }) }; break; default: throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`); } const requestOptions = { method: 'POST', url: endpoint, body, json: true, }; return await this.helpers.httpRequestWithAuthentication.call(this, 'facebookInstagramThreadsApi', requestOptions); } async function handleInstagramOperation(itemIndex, operation) { const instagramBusinessAccountId = this.getNodeParameter('instagramBusinessAccountId', itemIndex); switch (operation) { case 'createPhotoPost': return await createInstagramPhoto.call(this, itemIndex, instagramBusinessAccountId); case 'createVideoPost': return await createInstagramVideo.call(this, itemIndex, instagramBusinessAccountId); case 'createReels': return await createInstagramReels.call(this, itemIndex, instagramBusinessAccountId); case 'createCarouselPost': return await createInstagramCarousel.call(this, itemIndex, instagramBusinessAccountId); case 'createStory': return await createInstagramStory.call(this, itemIndex, instagramBusinessAccountId); default: throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`); } } async function createInstagramPhoto(itemIndex, accountId) { const imageUrl = this.getNodeParameter('imageUrl', itemIndex); const caption = this.getNodeParameter('caption', itemIndex, ''); const createRequestOptions = { method: 'POST', url: `/${accountId}/media`, body: { image_url: imageUrl, ...(caption && { caption }), }, json: true, }; const createResponse = await this.helpers.httpRequestWithAuthentication.call(this, 'facebookInstagramThreadsApi', createRequestOptions); const publishRequestOptions = { method: 'POST', url: `/${accountId}/media_publish`, body: { creation_id: createResponse.id, }, json: true, }; return await this.helpers.httpRequestWithAuthentication.call(this, 'facebookInstagramThreadsApi', publishRequestOptions); } async function createInstagramVideo(itemIndex, accountId) { const videoUrl = this.getNodeParameter('videoUrl', itemIndex); const videoCaption = this.getNodeParameter('videoCaption', itemIndex, ''); const createRequestOptions = { method: 'POST', url: `/${accountId}/media`, body: { video_url: videoUrl, media_type: 'VIDEO', ...(videoCaption && { caption: videoCaption }), }, json: true, }; const createResponse = await this.helpers.httpRequestWithAuthentication.call(this, 'facebookInstagramThreadsApi', createRequestOptions); const publishRequestOptions = { method: 'POST', url: `/${accountId}/media_publish`, body: { creation_id: createResponse.id, }, json: true, }; return await this.helpers.httpRequestWithAuthentication.call(this, 'facebookInstagramThreadsApi', publishRequestOptions); } async function createInstagramReels(itemIndex, accountId) { const reelsVideoUrl = this.getNodeParameter('reelsVideoUrl', itemIndex); const reelsCaption = this.getNodeParameter('reelsCaption', itemIndex, ''); const coverImageUrl = this.getNodeParameter('coverImageUrl', itemIndex, ''); const createRequestOptions = { method: 'POST', url: `/${accountId}/media`, body: { video_url: reelsVideoUrl, media_type: 'REELS', ...(reelsCaption && { caption: reelsCaption }), ...(coverImageUrl && { cover_url: coverImageUrl }), }, json: true, }; const createResponse = await this.helpers.httpRequestWithAuthentication.call(this, 'facebookInstagramThreadsApi', createRequestOptions); const publishRequestOptions = { method: 'POST', url: `/${accountId}/media_publish`, body: { creation_id: createResponse.id, }, json: true, }; return await this.helpers.httpRequestWithAuthentication.call(this, 'facebookInstagramThreadsApi', publishRequestOptions); } async function createInstagramCarousel(itemIndex, accountId) { const mediaItems = this.getNodeParameter('mediaItems.mediaItem', itemIndex, []); const carouselCaption = this.getNodeParameter('carouselCaption', itemIndex, ''); const mediaContainerIds = []; for (const mediaItem of mediaItems) { const createRequestOptions = { method: 'POST', url: `/${accountId}/media`, body: { ...(mediaItem.mediaType === 'IMAGE' ? { image_url: mediaItem.mediaUrl } : { video_url: mediaItem.mediaUrl, media_type: 'VIDEO' }), is_carousel_item: true, }, json: true, }; const response = await this.helpers.httpRequestWithAuthentication.call(this, 'facebookInstagramThreadsApi', createRequestOptions); mediaContainerIds.push(response.id); } const carouselRequestOptions = { method: 'POST', url: `/${accountId}/media`, body: { media_type: 'CAROUSEL', children: mediaContainerIds.join(','), ...(carouselCaption && { caption: carouselCaption }), }, json: true, }; const carouselResponse = await this.helpers.httpRequestWithAuthentication.call(this, 'facebookInstagramThreadsApi', carouselRequestOptions); const publishRequestOptions = { method: 'POST', url: `/${accountId}/media_publish`, body: { creation_id: carouselResponse.id, }, json: true, }; return await this.helpers.httpRequestWithAuthentication.call(this, 'facebookInstagramThreadsApi', publishRequestOptions); } async function createInstagramStory(itemIndex, accountId) { const storyMediaUrl = this.getNodeParameter('storyMediaUrl', itemIndex); const storyMediaType = this.getNodeParameter('storyMediaType', itemIndex); const requestOptions = { method: 'POST', url: `/${accountId}/media`, body: { ...(storyMediaType === 'IMAGE' ? { image_url: storyMediaUrl } : { video_url: storyMediaUrl }), media_type: 'STORIES', }, json: true, }; const createResponse = await this.helpers.httpRequestWithAuthentication.call(this, 'facebookInstagramThreadsApi', requestOptions); const publishRequestOptions = { method: 'POST', url: `/${accountId}/media_publish`, body: { creation_id: createResponse.id, }, json: true, }; return await this.helpers.httpRequestWithAuthentication.call(this, 'facebookInstagramThreadsApi', publishRequestOptions); } async function handleThreadsOperation(itemIndex, operation) { const threadsUserId = this.getNodeParameter('threadsUserId', itemIndex); let endpoint = ''; let body = {}; switch (operation) { case 'createTextPost': const text = this.getNodeParameter('text', itemIndex); endpoint = `/${threadsUserId}/threads`; body = { text }; break; case 'createPhotoPost': const imageUrl = this.getNodeParameter('imageUrl', itemIndex); const photoText = this.getNodeParameter('photoText', itemIndex, ''); endpoint = `/${threadsUserId}/threads`; body = { image_url: imageUrl, ...(photoText && { text: photoText }) }; break; case 'createVideoPost': const videoUrl = this.getNodeParameter('videoUrl', itemIndex); const videoText = this.getNodeParameter('videoText', itemIndex, ''); endpoint = `/${threadsUserId}/threads`; body = { video_url: videoUrl, ...(videoText && { text: videoText }) }; break; default: throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`); } const createRequestOptions = { method: 'POST', url: endpoint, body, json: true, }; const createResponse = await this.helpers.httpRequestWithAuthentication.call(this, 'facebookInstagramThreadsApi', createRequestOptions); const publishRequestOptions = { method: 'POST', url: `/${threadsUserId}/threads_publish`, body: { creation_id: createResponse.id, }, json: true, }; return await this.helpers.httpRequestWithAuthentication.call(this, 'facebookInstagramThreadsApi', publishRequestOptions); } for (let itemIndex = 0; itemIndex < items.length; itemIndex++) { try { const resource = this.getNodeParameter('resource', itemIndex); const operation = this.getNodeParameter('operation', itemIndex); let responseData = {}; if (resource === 'facebook') { responseData = await handleFacebookOperation.call(this, itemIndex, operation); } else if (resource === 'instagram') { responseData = await handleInstagramOperation.call(this, itemIndex, operation); } else if (resource === 'threads') { responseData = await handleThreadsOperation.call(this, itemIndex, operation); } returnData.push({ json: responseData, pairedItem: itemIndex }); } catch (error) { let errorMessage = 'Unknown error occurred'; let errorDetails = {}; if ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error) { const fbError = error.response.data.error; errorMessage = `${fbError.type}: ${fbError.message}`; errorDetails = { code: fbError.code, type: fbError.type, message: fbError.message, fbtrace_id: fbError.fbtrace_id, }; } else if (error.message) { errorMessage = error.message; } if (this.continueOnFail()) { returnData.push({ json: { ...this.getInputData(itemIndex)[0].json, error: errorMessage, errorDetails, }, error, pairedItem: itemIndex }); } else { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Facebook/Instagram/Threads API Error: ${errorMessage}`, { itemIndex, description: JSON.stringify(errorDetails, null, 2), }); } } } return [returnData]; } } exports.FacebookInstagramThreads = FacebookInstagramThreads; //# sourceMappingURL=FacebookInstagramThreads.node.js.map