Skip to main content

On This Page

Zero-Cost Facebook Auto-Poster: Build a Fully Automated Scheduler with Node.js and GitHub Actions

3 min read
Share

These articles are AI-generated summaries. Please check the original sources for full details.

Building a Fully Automated Facebook Post Scheduler using Node.js and GitHub Actions

Darshan Raval built a zero-cost Facebook auto-poster using Node.js and GitHub Actions. The system dynamically fetches Page Access Tokens via Meta’s Business System User to resolve strict token expiration issues.

Why This Matters

Meta has deprecated direct publish_actions for user tokens, making automated image uploads tricky without proper architecture. The professional solution uses a System User bound to a Business Portfolio, avoiding common token refresh failures that plague naive implementations relying on short-lived user tokens.

Key Insights

  • Meta’s deprecated publish_actions endpoint requires System Users for secure automation; Darshan Raval’s solution uses an Admin System User with ‘Full Control’ asset assignment (2026).
  • Dynamic Page Access Token resolution via /me/accounts endpoint avoids hardcoding tokens; the script fetches the exact token for the target Page ID at runtime (2026).
  • FormData streaming of local images to Meta Graph API /photos endpoint enables secure, multipart uploads without base64 encoding overhead (2026).
  • GitHub Actions cron scheduling (cron: '30 16 * * *') provides serverless automation at zero cost, with manual workflow_dispatch trigger for ad-hoc posts (2026).

Working Examples

The core automation script that dynamically resolves page access tokens from Meta Graph API and publishes photos with captions.


const fs = require('fs');
const path = require('path');
const axios = require('axios');
const FormData = require('form-data');
// Configuration
const PAGE_ID = "YOUR_FACEBOOK_PAGE_ID";
const SYSTEM_USER_TOKEN = process.env.FB_ACCESS_TOKEN;
if (!SYSTEM_USER_TOKEN) {
console.error("❌ Error: Missing FB_ACCESS_TOKEN in environment variables.");
process.exit(1);
}
// 🔑 Step A: Dynamically resolve the Page Access Token
async function getPageAccessToken() {
try {
console.log("🔑 Fetching Page Access Token from Meta...");
const url = `https://graph.facebook.com/v21.0/me/accounts?access_token=${SYSTEM_USER_TOKEN}`;
const response = await axios.get(url);
const pages = response.data.data;
const targetPage = pages.find(p => p.id === PAGE_ID);
if (!targetPage) {
throw new Error(`Could not find a Page Access Token for Page ID: ${PAGE_ID}`);
}
console.log(`✅ Successfully extracted Page Access Token for: ${targetPage.name}`);
return targetPage.access_token;
} catch (error) {
console.error("❌ Failed to get Page Access Token:", error.response ? error.response.data : error.message);
throw error;
}
}
// 📸 Step B: Choose local content and stream onto Facebook
async function publishDailyPost() {
try {
const PAGE_ACCESS_TOKEN = await getPageAccessToken();// 1. Pick a random text caption from quotes.json
const quotesPath = path.join(__dirname, 'quotes.json');
s.onst quotesData = JSON.parse(fs.readFileSync(quotesPath, 'utf8')); 
s.onst randomQuote = quotesData[Math.floor(Math.random() * quotesData.length)]; 
s.onst caption = `${randomQuote.text}\ n\ n${randomQuote.hashtags}`; 
s.onst imagesFolder = path.join(__dirname, 'images'); 
s.onst files = fs.readdirSync(imagesFolder); 
s.onst imageFiles = files.filter(file => /\ .(jpg|jpeg|png)$/i.test(file)); 
s.onst randomImage=imageFiles[Math.floor(Math.random()*imageFiles.length)]; 
s.onst imagePath=path.join(imagesFolder, randomImage); 
s.onsol e.log(`📸 Selected Image: ${randomImage}`) ; console .log(`📝 Selected Caption : ${randomQuote.text }`) ; const url=`https : //graph.facebook.com/v21.0/${PAGE_ID}/photos?access_token=${PAGE_ACCESS_TOKE N}` ; const formDat a=new Form Data(); form Dat a.append ('source', fs.createReadStream(image Path)); form Dat a.append ('caption', caption ); console .log(

Practical Applications

References:

  • From internal analysis

Continue reading

Next article

Building More Than Just an Agent Harness: Microsoft’s Jay Parikh on Enterprise AI at Scale

Related Content