interact-fb
v2.0.0
Published
A comprehensive NPM package for interacting with Facebook Graph API across frontend frameworks (React, Vue, Angular, Svelte, Vanilla JS)
Maintainers
Readme
Interact FB
A robust, developer-friendly client for Facebook Graph API. Works in modern browsers with the Facebook JS SDK and in Node.js when you provide an access token.
- Easy token handling: pass a token or let the SDK resolve it automatically
- Strong error handling: consistent custom error classes and retry logic
- Sensible defaults with opt-in overrides
Installation
npm install interact-fbQuick start
import { initFacebookSdk, getProfile } from 'interact-fb';
await initFacebookSdk('YOUR_APP_ID');
const me = await getProfile();
console.log(me); // { id, name, email?, picture?, ... }If you already have an access token (e.g., server-side), pass it explicitly to any function instead of relying on the SDK.
import { getPages } from 'interact-fb';
const pages = await getPages('USER_ACCESS_TOKEN');Which function to use when
- You are building a browser app and need the FB SDK: use
initFacebookSdk, thengetSDKStatusorisSDKReady/waitForSDK. - You need the user to log in and grant permissions: use
loginWithFacebook(pass scopes you need). - You just want to know if a user is logged in or get their token: use
isLoggedInandgetAccessToken. - You need the current user's profile:
- Basic info only:
getBasicProfile - Custom fields:
getProfile({ fields: 'id,name,email,picture' }) - Profile picture:
getProfilePicture
- Basic info only:
- You need the pages a user manages or info about a page:
- List managed pages:
getPages - Pages owned by user:
fetchOwnedPages - Client pages (advertiser access):
fetchClientPages - All managed pages:
fetchManagedPages - All pages (owned, client, managed):
fetchAllPages - Get one page by id from managed list:
getManagedPage - Check whether a user manages a page:
managesPage - Fetch public page info:
getPageInfo - Pages with extra counts (insights-like fields):
getPagesWithInsights
- List managed pages:
- You are working with posts and engagement:
- Recent page posts:
getPagePosts - Full post details:
getPostDetails - Post comments:
getPostComments(or shortcutgetComments) - Post likes:
getPostLikes(or shortcutgetLikes) - Posts with embedded comments/likes in one call:
getPagePostsWithEngagement
- Recent page posts:
- You are working with lead forms:
- List lead forms for a page:
getLeadForms - Only active forms:
getActiveLeadForms - Form details (questions, counts):
getLeadFormDetails - Forms across multiple pages:
getLeadFormsFromMultiplePages - Quick counts/summary:
getLeadFormStats
- List lead forms for a page:
- You are working with leads:
- Fetch page-by-page:
getLeads - Fetch all (auto-pagination):
getAllLeads - Fetch from many forms:
getLeadsFromMultipleForms - Recent leads window:
getRecentLeads({ hours }) - Developer-friendly shape (flatten field_data):
getFormattedLeads - Export to CSV:
getLeadsAsCSV - Computed stats:
getLeadStats
- Fetch page-by-page:
- You need to handle permissions:
- Proactively request during login: use
loginWithFacebook(scopes) - Inspect current scopes if needed:
getAllRequiredPermissions,getAllPermissions,fetchAllPermissions - If an API call fails with PERMISSION_DENIED, prompt the user to re-login with required scopes
- Proactively request during login: use
- You need maximum control over the Graph API:
- Single request:
graphAPI - Many requests together:
batchGraphAPI
- Single request:
Notes:
- In the browser, if you don’t pass a token, functions auto-resolve it from the SDK (user must be logged in).
- On the server, always pass a user or page token explicitly.
Errors
All functions may throw custom error types:
- FacebookSDKError
- FacebookAuthError
- FacebookAPIError
- FacebookPermissionError
- FacebookTimeoutError
Errors are automatically logged to console in development mode only after all retry attempts fail. You can also import handleError and logError for consistent processing.
Configuration
import { setConfig, getConfig, resetConfig, DEFAULT_CONFIG } from 'interact-fb';
setConfig({ version: 'v23.0', timeout: 15000 });Config defaults include:
- version, timeout, retryAttempts, retryDelay
- defaultFields: profile, pages, posts, leadForms, leads
- defaultPermissions: basic, pages, leads, posts
SDK Initialization
initFacebookSdk(appId, options?)
Initializes the FB JS SDK in the browser.
- Returns: Promise<{ sdk: 'initialized'|'already_loaded', version, appId, options }>
- Throws: FacebookSDKError on load/init failures
await initFacebookSdk('APP_ID', { xfbml: true, locale: 'en_US' });getSDKStatus()
- Returns: { isReady, version, appId, options } | null
Auth
loginWithFacebook(scope?, options?)
Prompts login via the SDK. scope can be string or string[].
- Returns: Promise<{ accessToken, expiresIn, userID, grantedScopes[], deniedScopes[], status }>
- Throws: FacebookSDKError, FacebookAuthError
logoutFromFacebook()
- Returns: Promise
getLoginStatus()
- Returns: Promise<{ status: 'connected'|'not_authorized'|'unknown', authResponse? }>
isLoggedIn(), getAccessToken()
- Returns: Promise or Promise<string|null>
Graph API
graphAPI(endpoint, accessToken, method='GET', params={}, options={})
Low-level client with retries and timeouts.
- Returns: Promise (raw Graph response)
- Throws: FacebookAPIError and friends
batchGraphAPI(requests, accessToken, options?)
- Returns: Promise<Array>
Profile
getProfile(accessToken?, options?)
Fetches current user profile.
- Options: { fields=DEFAULT.profile, apiOptions }
- Returns: Promise
getBasicProfile(accessToken?)
- Returns: Promise<{ id, name }>
getProfilePicture(accessToken, options?)
Fetches me/picture.
- Options: { width=200, height=200, type='normal', redirect=false }
- Returns: Promise (picture metadata or URL depending on params)
Pages
getPages(accessToken?, options?)
Fetches pages the user manages.
- Options: { fields=DEFAULT.pages, limit?, apiOptions }
- Returns: Promise<{ data: Array<{ id, name, access_token, ... }>, paging? }>
fetchOwnedPages(accessToken?, options?)
Fetches pages owned by the user (pages where user has MANAGE task).
- Options: { fields=DEFAULT.pages, limit?, apiOptions }
- Returns: Promise<{ data: Array<{ id, name, access_token, tasks, ... }>, paging? }>
fetchClientPages(accessToken?, options?)
Fetches client pages (pages where user has ADVERTISE task but not MANAGE).
- Options: { fields=DEFAULT.pages, limit?, apiOptions }
- Returns: Promise<{ data: Array<{ id, name, access_token, tasks, ... }>, paging? }>
fetchManagedPages(accessToken?, options?)
Fetches all pages managed by the user (all pages with any management task).
- Options: { fields=DEFAULT.pages, limit?, apiOptions }
- Returns: Promise<{ data: Array<{ id, name, access_token, ... }>, paging? }>
fetchAllPages(accessToken?, options?)
Fetches all pages (owned, managed, or task-based) associated with the user. Combines owned, client, and managed pages with deduplication.
- Options: { fields=DEFAULT.pages, limit?, deduplicate=true, apiOptions }
- Returns: Promise<{ data: Array<{ id, name, access_token, pageType, ... }>, summary: { total, owned, client, managed }, paging? }>
- Note: Each page in the response includes a
pageTypearray indicating which types it belongs to (e.g., ['owned', 'managed'])
getPageInfo(pageId, accessToken, options?)
- Options: { fields, apiOptions }
- Returns: Promise
getManagedPage(pageId, accessToken, options?)
- Returns: Promise<object|null>
managesPage(pageId, accessToken)
- Returns: Promise
Posts
getPagePosts(pageId, pageAccessToken?, options?)
- Options: { limit=10, fields=DEFAULT.posts, since?, until?, apiOptions }
- Returns: Promise<{ data: Array, paging? }>
getPostDetails(postId, accessToken?, options?)
- Options: { fields, apiOptions }
- Returns: Promise
Comments (shortcuts)
getComments(postId, accessToken?, options?)
- Same as getPostComments
getLikes(postId, accessToken?, options?)
- Same as getPostLikes
Lead Forms
getLeadForms(pageId, accessToken?, options?)
- Options: { fields=DEFAULT.leadForms, limit?, status?, apiOptions }
- Returns: Promise<{ data: Array, paging? }>
getLeadFormDetails(formId, accessToken?, options?)
- Options: { fields, apiOptions }
- Returns: Promise
getActiveLeadForms(pageId, accessToken?, options?)
- Returns: Promise<{ data: Array, paging? }>
getLeadFormsFromMultiplePages(pageIds, accessToken?, options?)
- Options: { parallel=true, ...getLeadForms options }
- Returns: Promise<Record<pageId, forms|{error}>>
getLeadFormStats(formId, accessToken?, options?)
- Returns: Promise<{ leads_count, expired_leads_count, created_time, status }>
Leads
getLeads(formId, accessToken?, options?)
- Options: { fields=DEFAULT.leads, limit=25, after?, since?, until?, apiOptions }
- Returns: Promise<{ data: Array, paging? }>
getAllLeads(formId, accessToken?, options?)
Auto-paginates until all fetched or maxLeads reached.
- Options: { maxLeads=10000, ...getLeads options }
- Returns: Promise<Array>
getLeadsFromMultipleForms(formIds, accessToken?, options?)
- Options: { parallel=true, ...getLeads options }
- Returns: Promise<Record<formId, leads|{error}>>
getRecentLeads(formId, accessToken?, options?)
- Options: { hours=24, ...getLeads options }
- Returns: Promise<{ data: Array, paging? }>
getLeadStats(formId, accessToken?, options?)
- Returns: Promise<{ formId, totalLeads, expiredLeads, formStatus, formCreated, leadsLast24Hours, activeLeads }>
Permissions
getAllRequirePermissions(requiredPermissions, accessToken?)
Throws if any required permission is missing. Use this for explicit permission validation when needed.
- Returns: Promise
fetchAllPermissions(accessToken?)
Fetches me?fields=permissions.
- Returns: Promise<{ permissions: { data: Array<{ permission, status }> } } | { data: Array<{ permission, status }> }>
getAllPermissions(accessToken?)
- Returns: Promise<string[]> (granted permissions only)
Token handling and caching
This package can automatically resolve tokens from the FB SDK in the browser and caches them to avoid repeated lookups.
resolveAccessToken(maybeToken, missingContext?, { useCache=true, forceRefresh=false }): resolves a token (returns input if provided) and caches SDK tokens with their expiry. In-flight lookups are deduplicated.setAccessToken(token, expiresInSeconds?): manually seed the cache (useful on server after login flow). If no expiry is provided, defaults to 1 hour.clearAccessToken(): clears the cache and any in-flight resolution.getCachedAccessToken(): returns the cached token if valid, otherwise null.
Recommendations:
- Browser: you can rely on auto-resolution; functions will request a token from the SDK once and reuse it.
- Server: always pass a user/page token explicitly, or pre-seed with
setAccessTokenper request scope.
Notes
- If you do not pass an access token, the SDK must be loaded in the browser and the user must be logged in.
- On servers, always pass a token explicitly.
- Pay attentions to scopes that you pass in as fields. (eg. {fields:"id,name,status,leads_count,created_time"})
License
MIT
