npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

social-media-poster

v1.0.5

Published

A Node.js SDK for posting to multiple social media platforms, including Facebook, Instagram, Twitter (X), Threads, TikTok, and Bluesky.

Readme

SocialSDK

A Node.js SDK for posting to multiple social media platforms, including Facebook, Instagram, Twitter (X), Threads, TikTok, and Bluesky.

Caching

To enable caching, set ALLOW_CACHE. The cache.json file will be created and used for storing token refresh details and will allow the SDK to refresh your long-lived tokens, where applicable, so you do not need to manually refresh your tokens and update your configuration. Note, you must call isValid to refresh these tokens.

Installation

To install the SocialSDK, run the following command:

npm i social-media-poster

Optional Peer-Dependencies:

  • twitter-api-v2: For Twitter/X integration (tested on v1.17.2).
  • nodemailer: For email notifications (tested on v6.10.0).
  • @aws-sdk/client-s3: For media uploads when using buffers on platforms that only allow URL uploads (tested on v3.758.0).

NodeJS-only Options

Nodemailer and caching are only available in NodeJS environments. It will not work in a client-side environment.

Usage

To use the SDK, first require it in your Node.js project:

// If you are directly passing a config object, do this the first time
const { init } = require('social-media-poster')
const SocialSDK = init(config)

// Otherwise, use this
const SocialSDK = require('social-media-poster')

Configuration

The SDK accepts a configuration object with the following optional properties. It defaults to using environment variables if no configuration is provided.

{
  // Facebook
  FACEBOOK_API_VERSION: '22.0',
  FACEBOOK_ACCESS_TOKEN: 'your-token',
  FACEBOOK_APP_ID: 'your-app-id',
  FACEBOOK_APP_SECRET: 'your-app-secret',
  FACEBOOK_PAGE_ID: 'your-page-id',

  // Instagram
  INSTAGRAM_USER_ID: 'your-user-id',
  INSTAGRAM_ACCESS_TOKEN: 'your-token',

  // Threads
  THREADS_API_VERSION: '1.0',
  THREADS_USER_ID: 'your-user-id',
  THREADS_ACCESS_TOKEN: 'your-token',

  // TikTok
  TIKTOK_ACCESS_TOKEN: 'your-access-token',
  TIKTOK_REFRESH_TOKEN: 'your-refresh-token',

  // Twitter/X
  X_APP_KEY: 'your-key', // Consumer Key
  X_APP_SECRET: 'your-secret', // Consumer Secret
  X_ACCESS_TOKEN: 'your-token',
  X_ACCESS_SECRET: 'your-secret',

  // Bluesky
  BLUESKY_HANDLE: 'your-handle',
  BLUESKY_PASSWORD: 'your-password',

  // YouTube
  YOUTUBE_ACCESS_TOKEN: 'your-access-token',
  YOUTUBE_REFRESH_TOKEN: 'your-refresh-token',

  // Misc
  PROJECT_NAME: 'Your project',
  ALLOW_CACHE: true,

  // Email
  IS_SENDING_EMAILS: false, // set to true and install nodemailer to receive email notifications
  EMAIL_RECIPIENTS: '[email protected]', // multiple recipients should be a string with a space between each email
  EMAIL: 'your-email',
  EMAIL_PASSWORD: 'your-password',

  // AWS S3 (for media uploads)
  AWS_S3_ACCESS_KEY_ID: 'your-key',
  AWS_S3_SECRET_ACCESS_KEY: 'your-secret',
  AWS_S3_PATH: 'your-path', // S3 path (key) where any uploaded media will be stored
  AWS_S3_BUCKET: 'your-bucket',
  AWS_S3_BUCKET_REGION: 'your-region'
}

Methods

Facebook (sdk.fb)

  • isValid():
    • If ALLOW_CACHE is enabled, this will refresh the access token for either another 60 days or, if given the correct permissions, permanently
    • If a permanent token is created, calling this function will instead check the expiry date rather than refresh the token
    • Otherwise, this will check how long until the token expires and send an email, if applicable, when it expires within two weeks
  • post (fb.post)
    • reel(data, media)
      • data: An object containing the following properties:
        {
            description = null,
            time = null, // UNIX timestamp of when the post should go live
        }
      • media: URL string or Buffer
    • video(data, media)
      • data: An object containing the following properties:
        {
            description = null,
            time = null, // UNIX timestamp of when the post should go live
        }
      • media: URL string or Buffer
    • default(data, media): Text or Image posts
      • data: An object containing the following properties:
        {
            description = null,
            time = null, // UNIX timestamp of when the post should go live
            regions = null // Array of country codes for region-specific posting
        }
      • media: URL string or Buffer (Optional)
  • comment(postId, message):
    • postId: The ID of the Facebook post to comment on
    • message: The comment text
  • characters(text):
    • Get the character count of text as Facebook would calculate it
      • text: The text to count

Instagram (sdk.ig)

  • isValid(): Checks Instagram token validity and sends expiration warnings.
  • post(data, media):
    • data: An object containing the following properties:
      {
          description = null
      }
    • media: URL string or Buffer (Images passed as a Buffer require AWS S3 for upload)
  • characters(text):
    • Get the character count of text as Instagram would calculate it
      • text: The text to count

Twitter/X (sdk.x) (Requires twitter-api-v2 to be installed)

  • post(data, media):
    • data: An object containing the following properties:
      {
          description = '', // Text content
      }
    • media: URL string or Buffer

Threads (sdk.threads)

  • getLongLivedToken():
    • Exchanges your short-lived token for a long-lived token (expires in 1 hour to expires in 60 days)
    • Note that you must replace your Threads access token with the newly-returned access token
  • isValid():
    • If ALLOW_CACHE is set, this function will attempt to refresh your refresh token to extend its life another 60 days
    • The token will not refresh unless you call this function
  • post(data, media):
    • data: An object containing the following properties:
      {
          description = '', // Text content
      }
    • media: URL string or Buffer (Buffer requires AWS S3) (optional)
  • characters(text):
    • Get the character count of text as Threads would calculate it
      • text: The text to count

TikTok (sdk.tiktok)

TikTok support is pending app verification and will be available once verified

  • user(): Gets TikTok User Info
  • post(data, media):
    • data: An object containing the following properties:
      {
          title = '', // Caption
          privacy_level = "SELF_ONLY",
          disable_duet = false,
          disable_comment = false,
          disable_stitch = false,
          video_cover_timestamp_ms = 1000,
          is_branded_content = true
      }
    • media: URL string or Buffer
  • status(id): Gets post status
  • revoke(): Revokes TikTok access

Bluesky (sdk.bluesky)

  • post(data, media):
    • data: An object containing the following properties:
      {
          description = '', // Text content
      }
    • media: Object or an Array of Objects of { source: URL String or Buffer, alt: String, aspectRatio: { width: Number, height: Number } }
  • characters(text):
    • Get the character count of text as BlueSky would calculate it
      • text: The text to count

YouTube (sdk.youtube)

Go to https://social.pomley.com/youtube to obtain your YouTube access and refresh token.

  • refresh(): Refreshes YouTube Access Token. This automatically runs when YouTube returns a 401 auth error. Access Tokens last one hour, so you should run this if its been an hour since you last called to YouTube to avoid excessive calls
  • post(data, media):
    • data: An object containing the following properties:
      {
          title = '',
          description = '',
          privacy = 'public' // "public", "private", or "unlisted"
      }
    • media: Buffer or URL String of a video

Notes

  • Media uploads may require AWS S3 configuration
  • Some platforms have specific media requirements
  • Facebook token expiration warnings are sent via email if configured

Contact

Report any bugs and/or feedback to [email protected]

Examples

Check out https://social.pomley.com for more examples and a quickstart download option

Setup

    // Imports
    const SocialPoster = require('social-media-poster')
    const fs = require('fs').promises

    // Create Instance
    const Social = new SocialPoster(config)

    // Get Buffer using fs (if reading from file)
    const buffer = await fs.readFile('./media.mp4')

YouTube

    await Social.youtube.post(
        {
            title: 'This package is amazing!',
            description: 'Pomley has an amazing social media poster that quickly lets you upload your photos and videos to all the mainstream social media platforms.'
            privacy: 'public'
        },
        buffer
    )