@memberjunction/actions-bizapps-social
Version:
Social Media Actions for MemberJunction - Twitter, LinkedIn, Facebook, Instagram, TikTok, YouTube, HootSuite, Buffer
172 lines • 5.89 kB
JavaScript
import { BaseOAuthAction } from '@memberjunction/actions';
import { LogStatus } from '@memberjunction/core';
export var SocialMediaErrorCode;
(function (SocialMediaErrorCode) {
SocialMediaErrorCode["RATE_LIMIT_EXCEEDED"] = "RATE_LIMIT";
SocialMediaErrorCode["INVALID_TOKEN"] = "INVALID_TOKEN";
SocialMediaErrorCode["TOKEN_EXPIRED"] = "TOKEN_EXPIRED";
SocialMediaErrorCode["PLATFORM_ERROR"] = "PLATFORM_ERROR";
SocialMediaErrorCode["INVALID_MEDIA"] = "INVALID_MEDIA";
SocialMediaErrorCode["POST_NOT_FOUND"] = "POST_NOT_FOUND";
SocialMediaErrorCode["INSUFFICIENT_PERMISSIONS"] = "INSUFFICIENT_PERMISSIONS";
})(SocialMediaErrorCode || (SocialMediaErrorCode = {}));
/**
* Base class for all social media actions.
* Provides common functionality for authentication, media handling,
* analytics normalization, and rate limiting.
*/
export class BaseSocialMediaAction extends BaseOAuthAction {
/**
* Common parameters for all social media actions
*/
get commonSocialParams() {
return [
...this.oauthParams,
{
Name: 'ProfileID',
Type: 'Input',
Value: null
}
];
}
/**
* Normalize platform-specific analytics to common format
*/
normalizeAnalytics(platformData) {
// Default implementation - override in platform-specific classes
return {
impressions: platformData.impressions || 0,
engagements: platformData.engagements || 0,
clicks: platformData.clicks || 0,
shares: platformData.shares || 0,
comments: platformData.comments || 0,
likes: platformData.likes || 0,
reach: platformData.reach || 0,
saves: platformData.saves,
videoViews: platformData.videoViews,
platformMetrics: platformData
};
}
/**
* Upload media files to the platform
*/
async uploadMedia(files) {
const uploadedUrls = [];
for (const file of files) {
// Validate file
this.validateMediaFile(file);
// Upload file (platform-specific implementation)
const url = await this.uploadSingleMedia(file);
uploadedUrls.push(url);
}
return uploadedUrls;
}
/**
* Validate media file meets platform requirements
*/
validateMediaFile(file) {
const maxSizes = {
'image/jpeg': 5 * 1024 * 1024, // 5MB
'image/png': 5 * 1024 * 1024, // 5MB
'image/gif': 15 * 1024 * 1024, // 15MB
'video/mp4': 512 * 1024 * 1024 // 512MB
};
const maxSize = maxSizes[file.mimeType];
if (!maxSize) {
throw new Error(`Unsupported media type: ${file.mimeType}`);
}
if (file.size > maxSize) {
throw new Error(`File size exceeds limit. Max ${maxSize} bytes, got ${file.size} bytes`);
}
}
/**
* Handle rate limiting with exponential backoff
*/
async handleRateLimit(retryAfter) {
const waitTime = retryAfter || 60; // Default to 60 seconds
LogStatus(`Rate limit hit. Waiting ${waitTime} seconds...`);
await new Promise(resolve => setTimeout(resolve, waitTime * 1000));
}
/**
* Parse rate limit headers from API response
*/
parseRateLimitHeaders(headers) {
// Common header patterns across platforms
const remaining = headers['x-rate-limit-remaining'] ||
headers['x-ratelimit-remaining'] ||
headers['rate-limit-remaining'];
const reset = headers['x-rate-limit-reset'] ||
headers['x-ratelimit-reset'] ||
headers['rate-limit-reset'];
const limit = headers['x-rate-limit-limit'] ||
headers['x-ratelimit-limit'] ||
headers['rate-limit-limit'];
if (remaining !== undefined && reset && limit) {
return {
remaining: parseInt(remaining),
reset: new Date(parseInt(reset) * 1000), // Usually Unix timestamp
limit: parseInt(limit)
};
}
return null;
}
/**
* Build common API headers including authentication
*/
buildHeaders(additionalHeaders) {
const token = this.getAccessToken();
if (!token) {
throw new Error('No access token available');
}
return {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
'Accept': 'application/json',
...additionalHeaders
};
}
/**
* Format date for API requests (ISO 8601)
*/
formatDate(date) {
if (typeof date === 'string') {
date = new Date(date);
}
return date.toISOString();
}
/**
* Parse date from API response
*/
parseDate(dateString) {
return new Date(dateString);
}
/**
* Get profile ID from parameters or default from integration
*/
getProfileId(params) {
return params.ProfileID || this.getCustomAttribute(1) || '';
}
/**
* Log API request for debugging
*/
logApiRequest(method, url, data) {
LogStatus(`${this.platformName} API Request: ${method} ${url}`);
if (data) {
LogStatus(`Request Data: ${JSON.stringify(data, null, 2)}`);
}
}
/**
* Log API response for debugging
*/
logApiResponse(response) {
LogStatus(`${this.platformName} API Response: ${JSON.stringify(response, null, 2)}`);
}
/**
* Helper to get parameter value from params array
*/
getParamValue(params, paramName) {
const param = params.find(p => p.Name === paramName);
return param?.Value;
}
}
//# sourceMappingURL=base-social.action.js.map