← back to Dear Bubbe Nextjs
archived/social-posters/instagram-business-poster.js
215 lines
#!/usr/bin/env node
const fs = require('fs').promises;
const path = require('path');
const axios = require('axios');
const FormData = require('form-data');
const { exec } = require('child_process');
const util = require('util');
const execPromise = util.promisify(exec);
const { generateInstagramImage, generateCaption } = require('./instagram-image-generator');
// Configuration for Instagram Business API
const CONFIG = {
// You'll need to get these from Facebook Developer Console
// 1. Create Facebook App at developers.facebook.com
// 2. Add Instagram Basic Display or Instagram Graph API
// 3. Get access tokens
INSTAGRAM_BUSINESS_ID: process.env.INSTAGRAM_BUSINESS_ID || 'YOUR_IG_BUSINESS_ID',
FACEBOOK_PAGE_ID: process.env.FACEBOOK_PAGE_ID || 'YOUR_FB_PAGE_ID',
ACCESS_TOKEN: process.env.META_ACCESS_TOKEN || 'YOUR_ACCESS_TOKEN',
// API endpoints
GRAPH_API_URL: 'https://graph.facebook.com/v18.0',
// Local config
STATE_FILE: '/root/Projects/dear-bubbe-admin/logs/instagram-business-state.json',
POSTS_PER_DAY: 3
};
// Get random user message
async function getRandomMessage() {
try {
const { stdout } = await execPromise(
`pm2 logs bubbe-ai --lines 1000 --nostream | grep -E "message:" | grep -v "__" | grep -v "test" | head -30`
);
const messages = [];
const lines = stdout.split('\n').filter(line => line.trim());
for (const line of lines) {
const match = line.match(/message:\s*["'](.+?)["']/);
if (match && match[1] && match[1].length > 20) {
messages.push(match[1].trim());
}
}
return messages.length > 0 ?
messages[Math.floor(Math.random() * messages.length)] :
"Should I quit my job without another lined up?";
} catch (error) {
return "My mother-in-law criticizes everything I do";
}
}
// Upload image to Instagram via Graph API
async function uploadToInstagram(imagePath, caption) {
try {
// First, upload image to get media ID
const imageUrl = `http://45.61.58.125:7902/${path.basename(imagePath)}`;
// Step 1: Create media object
const createMediaUrl = `${CONFIG.GRAPH_API_URL}/${CONFIG.INSTAGRAM_BUSINESS_ID}/media`;
const createResponse = await axios.post(createMediaUrl, {
image_url: imageUrl,
caption: caption,
access_token: CONFIG.ACCESS_TOKEN
});
const mediaId = createResponse.data.id;
console.log('✅ Media uploaded, ID:', mediaId);
// Step 2: Publish the media
const publishUrl = `${CONFIG.GRAPH_API_URL}/${CONFIG.INSTAGRAM_BUSINESS_ID}/media_publish`;
const publishResponse = await axios.post(publishUrl, {
creation_id: mediaId,
access_token: CONFIG.ACCESS_TOKEN
});
console.log('✅ Posted to Instagram!');
return { success: true, id: publishResponse.data.id };
} catch (error) {
console.error('❌ API Error:', error.response?.data || error.message);
return { success: false, error: error.message };
}
}
// Alternative: Use Creator Studio scheduling
async function scheduleViaCreatorStudio() {
console.log('\n📅 SCHEDULE VIA CREATOR STUDIO:');
console.log('========================================');
console.log('1. Go to: https://business.facebook.com/creatorstudio');
console.log('2. Click "Create Post" → "Instagram Feed"');
console.log('3. Upload the generated image');
console.log('4. Paste the caption');
console.log('5. Schedule for optimal time');
console.log('\n✨ Creator Studio allows:');
console.log(' - Scheduling posts in advance');
console.log(' - Cross-posting to Facebook');
console.log(' - Analytics and insights');
console.log(' - Bulk uploading');
}
// Generate webhook for automation tools
async function generateWebhook(imagePath, caption) {
const webhookData = {
platform: 'instagram',
image_url: `http://45.61.58.125:7902/${path.basename(imagePath)}`,
caption: caption,
hashtags: caption.match(/#\w+/g) || [],
timestamp: new Date().toISOString(),
webhook_url: 'http://45.61.58.125:7902/instagram-webhook.json'
};
const webhookPath = '/root/Projects/dear-bubbe-admin/public/instagram-webhook.json';
await fs.writeFile(webhookPath, JSON.stringify(webhookData, null, 2));
console.log('\n🔗 WEBHOOK DATA READY:');
console.log(' http://45.61.58.125:7902/instagram-webhook.json');
console.log('\n Use with:');
console.log(' - Zapier (Instagram Business)');
console.log(' - IFTTT Pro');
console.log(' - Make (Integromat)');
console.log(' - Buffer API');
console.log(' - Later API');
}
// Main posting function
async function postToInstagramBusiness() {
console.log('📸 Instagram Business Poster');
console.log('========================================');
// Get message
const message = await getRandomMessage();
console.log(`📝 Message: "${message}"`);
// Generate image
const timestamp = Date.now();
const imagePath = `/root/Projects/dear-bubbe-admin/public/instagram-${timestamp}.png`;
await generateInstagramImage(message, imagePath);
console.log('🎨 Image created');
// Generate caption
const caption = generateCaption(message);
console.log('📝 Caption ready');
// Save files for easy access
await fs.writeFile(
`/root/Projects/dear-bubbe-admin/public/instagram-latest-caption.txt`,
caption
);
// Check if API credentials are configured
if (CONFIG.ACCESS_TOKEN === 'YOUR_ACCESS_TOKEN') {
console.log('\n⚠️ Instagram Business API not configured');
console.log('\nTo set up:');
console.log('1. Go to https://developers.facebook.com');
console.log('2. Create new app → Business');
console.log('3. Add Instagram Graph API');
console.log('4. Get Access Token');
console.log('5. Set environment variables:');
console.log(' export INSTAGRAM_BUSINESS_ID=xxx');
console.log(' export FACEBOOK_PAGE_ID=xxx');
console.log(' export META_ACCESS_TOKEN=xxx');
await scheduleViaCreatorStudio();
await generateWebhook(imagePath, caption);
} else {
// Try to post via API
const result = await uploadToInstagram(imagePath, caption);
if (!result.success) {
await scheduleViaCreatorStudio();
await generateWebhook(imagePath, caption);
}
}
// Create scheduling file for Buffer/Later
const scheduleData = {
posts: [{
text: caption,
media: {
photo: `http://45.61.58.125:7902/instagram-${timestamp}.png`,
thumbnail: `http://45.61.58.125:7902/instagram-${timestamp}.png`
},
platforms: ['instagram'],
scheduled_at: new Date(Date.now() + 2 * 60 * 60 * 1000).toISOString() // 2 hours from now
}]
};
await fs.writeFile(
'/root/Projects/dear-bubbe-admin/public/instagram-schedule.json',
JSON.stringify(scheduleData, null, 2)
);
console.log('\n✅ INSTAGRAM CONTENT READY:');
console.log(`📸 Image: http://45.61.58.125:7902/instagram-${timestamp}.png`);
console.log(`📝 Caption: http://45.61.58.125:7902/instagram-latest-caption.txt`);
console.log(`📅 Schedule: http://45.61.58.125:7902/instagram-schedule.json`);
console.log(`🔗 Webhook: http://45.61.58.125:7902/instagram-webhook.json`);
return {
image: `http://45.61.58.125:7902/instagram-${timestamp}.png`,
caption: caption,
success: true
};
}
// Run if called directly
if (require.main === module) {
postToInstagramBusiness().catch(console.error);
}
module.exports = { postToInstagramBusiness };