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 🙏

© 2026 – Pkg Stats / Ryan Hefner

social-posts-sdk

v0.1.2

Published

TypeScript SDK for posting to social media: Facebook, Instagram, Threads, Twitter/X, LinkedIn, TikTok, YouTube, Pinterest, Telegram, Zalo

Readme

social-posts-sdk

TypeScript SDK để đăng bài lên mạng xã hội.

🇬🇧 View English documentation

Nền tảng hỗ trợ

| Nền tảng | Các method | |----------|-----------| | Facebook (Fanpage) | postText, postPhoto, postAlbum, postVideo | | Instagram (Business/Creator) | postImage, postVideo, postCarousel | | Threads | postText, postImage, postVideo, postCarousel | | Twitter / X | postText, postImages, postVideo | | LinkedIn (Trang & Cá nhân) | postText, postImage, postVideo | | TikTok | postVideo, postPhotos | | YouTube | uploadVideo | | Pinterest | createPin | | Telegram (Bot) | sendMessage, sendPhoto, sendVideo, sendAlbum | | Zalo (Official Account) | postFeed |


Yêu cầu

  • Node.js >= 22

Cài đặt

npm install social-posts-sdk

Bắt đầu nhanh

import { SocialPostsClient } from 'social-posts-sdk'

const client = new SocialPostsClient({
  facebook:  { pageId: '...', accessToken: '...' },
  instagram: { igUserId: '...', accessToken: '...' },
  threads:   { userId: '...', accessToken: '...' },
  twitter:   { accessToken: '...' },
  linkedin:  { accessToken: '...' },
  tiktok:    { accessToken: '...' },
  youtube:   { accessToken: '...' },
  pinterest: { accessToken: '...' },
  telegram:  { botToken: '...' },
  zalo:      { accessToken: '...' },
})

// Đăng lên nhiều nền tảng cùng lúc
await Promise.all([
  client.facebook?.postText({ message: 'Xin chào!' }),
  client.instagram?.postImage({ imageUrl: 'https://...', caption: 'Xin chào!' }),
  client.threads?.postText({ text: 'Xin chào!' }),
  client.twitter?.postText({ text: 'Hello!' }),
  client.telegram?.sendMessage({ chatId: '@kenh', text: 'Xin chào!' }),
])

Tất cả nền tảng đều là tuỳ chọn — chỉ cấu hình những nền tảng bạn cần.


Kết quả trả về (PostResult)

Mọi method đều trả về PostResult:

interface PostResult {
  id: string        // ID bài đăng do nền tảng cấp
  platform: string  // 'facebook' | 'instagram' | 'threads' | ...
  createdAt: string // ISO 8601
}

API từng nền tảng

Facebook

import { FacebookClient } from 'social-posts-sdk'

const fb = new FacebookClient({ pageId: 'PAGE_ID', accessToken: 'PAGE_TOKEN' })

await fb.postText({ message: 'Xin chào!', link?: 'https://...' })
await fb.postPhoto({ imageUrl: 'https://...', message?: '...' })
await fb.postAlbum({ imageUrls: ['https://...', 'https://...'], message?: '...' })
await fb.postVideo({ videoUrl: 'https://...', title?: '...', description?: '...' })

Token: Page Access Token với quyền pages_manage_posts.


Instagram

import { InstagramClient } from 'social-posts-sdk'

const ig = new InstagramClient({ igUserId: 'IG_USER_ID', accessToken: 'TOKEN' })

await ig.postImage({ imageUrl: 'https://...', caption?: '...', userTags?: [...] })
await ig.postVideo({ videoUrl: 'https://...', mediaType?: 'VIDEO' | 'REELS', caption?: '...' })
await ig.postCarousel({ items: [{ type: 'IMAGE', imageUrl: '...' }, ...], caption?: '...' })

Token: Page Access Token với instagram_basic, instagram_content_publish. Lưu ý: Tài khoản phải kết nối với Facebook Page và chuyển sang loại Business/Creator.


Threads

import { ThreadsClient } from 'social-posts-sdk'

const threads = new ThreadsClient({ userId: 'USER_ID', accessToken: 'TOKEN' })

await threads.postText({ text: 'Xin chào!', replyToId?: '...' })
await threads.postImage({ imageUrl: 'https://...', text?: '...' })
await threads.postVideo({ videoUrl: 'https://...', text?: '...' })
await threads.postCarousel({ items: [...], text?: '...' })  // tối đa 20 items

Token: User Access Token với threads_basic, threads_content_publish.


Twitter / X

import { TwitterClient } from 'social-posts-sdk'

const twitter = new TwitterClient({
  accessToken: 'OAUTH2_USER_TOKEN',
  // Bắt buộc khi dùng postImages / postVideo:
  oauth1: { consumerKey, consumerSecret, accessToken, accessTokenSecret },
})

await twitter.postText({ text: 'Hello!', replyToTweetId?: '...' })
await twitter.postImages({ imageUrls: ['https://...'], text?: '...' }) // tối đa 4 ảnh
await twitter.postVideo({ videoUrl: 'https://...', text?: '...' })

Token: OAuth 2.0 user access token với tweet.write. Upload media cần thêm OAuth 1.0a.


LinkedIn

import { LinkedInClient } from 'social-posts-sdk'

const li = new LinkedInClient({ accessToken: 'OAUTH2_TOKEN' })

// authorUrn: "urn:li:organization:12345" hoặc "urn:li:person:xxxx"
await li.postText({ text: '...', authorUrn: 'urn:li:organization:12345' })
await li.postImage({ imageUrl: 'https://...', text?: '...', authorUrn: '...' })
await li.postVideo({ videoUrl: 'https://...', text?: '...', authorUrn: '...' })

Token: OAuth 2.0 với w_member_social (cá nhân) hoặc w_organization_social (trang công ty).


TikTok

import { TikTokClient } from 'social-posts-sdk'

const tiktok = new TikTokClient({ accessToken: 'TOKEN' })

await tiktok.postVideo({
  videoUrl: 'https://...',
  title?: '...',
  description?: '...',
  privacyLevel?: 'PUBLIC_TO_EVERYONE' | 'SELF_ONLY', // mặc định: SELF_ONLY
})
await tiktok.postPhotos({ photoUrls: ['https://...', 'https://...'], title?: '...' })

Token: OAuth 2.0 với scope video.publish. Lưu ý: URL video/ảnh phải công khai (SDK dùng PULL_FROM_URL).


YouTube

import { YouTubeClient } from 'social-posts-sdk'

const yt = new YouTubeClient({ accessToken: 'OAUTH2_TOKEN' })

await yt.uploadVideo({
  videoUrl: 'https://...',   // SDK tải về và stream lên YouTube
  title: 'Tiêu đề video',
  description?: '...',
  tags?: ['tag1', 'tag2'],
  categoryId?: '22',          // 22 = People & Blogs
  privacyStatus?: 'public' | 'private' | 'unlisted',
  madeForKids?: false,
})

Token: OAuth 2.0 với scope https://www.googleapis.com/auth/youtube.upload.


Pinterest

import { PinterestClient } from 'social-posts-sdk'

const pinterest = new PinterestClient({ accessToken: 'TOKEN' })

await pinterest.createPin({
  boardId: 'BOARD_ID',
  imageUrl: 'https://...',
  title?: '...',
  description?: '...',
  link?: 'https://...',
  altText?: '...',
  boardSectionId?: '...',
})

Token: OAuth 2.0 với pins:write, boards:read.


Telegram

import { TelegramClient } from 'social-posts-sdk'

const tg = new TelegramClient({ botToken: 'BOT_TOKEN' })

await tg.sendMessage({ chatId: '@kenh', text: '<b>Xin chào!</b>', parseMode?: 'HTML' })
await tg.sendPhoto({ chatId: '@kenh', photoUrl: 'https://...', caption?: '...' })
await tg.sendVideo({ chatId: '@kenh', videoUrl: 'https://...', caption?: '...' })
await tg.sendAlbum({
  chatId: '@kenh',
  media: [
    { type: 'photo', photoUrl: 'https://...' },
    { type: 'video', videoUrl: 'https://...' },
  ],
})

Token: Bot Token từ @BotFather.


Zalo

import { ZaloClient } from 'social-posts-sdk'

const zalo = new ZaloClient({ accessToken: 'OA_ACCESS_TOKEN' })

await zalo.postFeed({ message: 'Xin chào!', photoUrls?: ['https://...'] })

Token: OA Access Token từ Zalo Developers.


Đọc bài đăng

import type { PostInfo } from 'social-posts-sdk'

const info: PostInfo = await client.facebook!.getPost('post_id')
// info.id, info.platform, info.content, info.url, info.createdAt, info.metrics, info.raw

const tweet: PostInfo = await client.twitter!.getTweet('tweet_id')
const video: PostInfo = await client.youtube!.getVideo('video_id')
const pin:   PostInfo = await client.pinterest!.getPin('pin_id')

Cấu trúc PostInfo:

interface PostInfo {
  id: string
  platform: string
  content: string | null      // nội dung / caption / tiêu đề
  url: string | null          // đường link trực tiếp
  createdAt: string | null    // ISO 8601
  metrics: {
    likes: number | null
    comments: number | null
    shares: number | null
    views: number | null
  }
  raw: unknown                // dữ liệu gốc từ API
}

Xoá & Cập nhật bài đăng

// Xoá
await client.facebook!.deletePost('post_id')
await client.instagram!.deletePost('media_id')
await client.threads!.deletePost('media_id')
await client.twitter!.deleteTweet('tweet_id')
await client.linkedin!.deletePost('urn:li:ugcPost:123')
await client.youtube!.deleteVideo('video_id')
await client.pinterest!.deletePin('pin_id')

// Cập nhật (các nền tảng hỗ trợ)
await client.facebook!.updatePost('post_id', { message: 'Nội dung mới' })
await client.youtube!.updateVideo('video_id', {
  title: 'Tiêu đề mới',
  description: 'Mô tả mới',
  tags: ['tag1'],
  categoryId: '22',
})

Retry & Exponential Backoff

Truyền cấu hình retry vào bất kỳ platform client nào để tự động thử lại khi gặp rate-limit hoặc lỗi 5xx:

import { FacebookClient } from 'social-posts-sdk'
import type { RetryConfig } from 'social-posts-sdk'

const retry: RetryConfig = {
  maxAttempts: 5,       // mặc định: 3
  initialDelayMs: 500,  // mặc định: 1000
  maxDelayMs: 30_000,   // mặc định: 30_000
  factor: 2,            // mặc định: 2 (tăng theo cấp số nhân)
}

const fb = new FacebookClient({
  pageId: 'PAGE_ID',
  accessToken: 'TOKEN',
  retry,
})

Quy tắc retry:

  • Có retry: RateLimitError, lỗi mạng, SocialSDKError 5xx
  • Không retry: AuthError, ValidationError, lỗi 4xx

Làm mới Token

import {
  refreshMetaToken,     // Facebook / Instagram / Threads
  refreshTwitterToken,
  refreshLinkedInToken,
  refreshGoogleToken,   // YouTube
  refreshTikTokToken,
  refreshPinterestToken,
} from 'social-posts-sdk'

// Đổi short-lived Meta token lấy long-lived token (60 ngày)
const { access_token } = await refreshMetaToken({
  clientId: 'APP_ID',
  clientSecret: 'APP_SECRET',
  shortLivedToken: 'SHORT_TOKEN',
})

// Làm mới Twitter OAuth 2.0 token
const tokens = await refreshTwitterToken({
  clientId: 'CLIENT_ID',
  clientSecret: 'CLIENT_SECRET',
  refreshToken: 'REFRESH_TOKEN',
})

OAuth Flow

Tạo link đăng nhập và đổi code lấy token:

import {
  getMetaAuthUrl, exchangeMetaCode,
  getTwitterAuthUrl, exchangeTwitterCode,
  getLinkedInAuthUrl, exchangeLinkedInCode,
  getGoogleAuthUrl, exchangeGoogleCode,
  getTikTokAuthUrl, exchangeTikTokCode,
  getPinterestAuthUrl, exchangePinterestCode,
  getZaloAuthUrl, exchangeZaloCode,
} from 'social-posts-sdk'

// Bước 1: Chuyển hướng user đến trang đăng nhập
const url = getMetaAuthUrl({
  clientId: 'APP_ID',
  redirectUri: 'https://yourapp.com/callback',
  scopes: ['pages_manage_posts', 'instagram_content_publish'],
  state: 'csrf_token',
})

// Bước 2: Nhận code từ callback, đổi lấy token
const { access_token } = await exchangeMetaCode({
  clientId: 'APP_ID',
  clientSecret: 'APP_SECRET',
  redirectUri: 'https://yourapp.com/callback',
  code: req.query.code,
})

// Twitter dùng PKCE — lưu codeVerifier giữa 2 bước
const { url: twUrl, codeVerifier } = await getTwitterAuthUrl({
  clientId: 'CLIENT_ID',
  redirectUri: 'https://yourapp.com/tw/callback',
  scopes: ['tweet.read', 'tweet.write', 'offline.access'],
  state: 'csrf_token',
})

const twTokens = await exchangeTwitterCode({
  clientId: 'CLIENT_ID',
  clientSecret: 'CLIENT_SECRET',
  redirectUri: 'https://yourapp.com/tw/callback',
  code: req.query.code,
  codeVerifier,   // từ bước 1
})

Xử lý lỗi

import { SocialSDKError, AuthError, RateLimitError, ValidationError } from 'social-posts-sdk'

try {
  await client.facebook?.postText({ message: 'Xin chào' })
} catch (err) {
  if (err instanceof ValidationError) {
    console.error('Dữ liệu không hợp lệ:', err.issues)
  } else if (err instanceof AuthError) {
    console.error('Token không hợp lệ hoặc đã hết hạn')
  } else if (err instanceof RateLimitError) {
    console.error('Vượt giới hạn — hãy thử lại sau')
  } else if (err instanceof SocialSDKError) {
    console.error(`[${err.platform}] lỗi ${err.code}:`, err.message)
  }
}

Cấu hình chi tiết

Facebook

| Thuộc tính | Bắt buộc | Mặc định | Mô tả | |------------|----------|----------|-------| | pageId | ✅ | — | ID Trang Facebook | | accessToken | ✅ | — | Page Access Token | | apiVersion | — | v22.0 | Phiên bản Graph API |

Instagram / Threads

| Thuộc tính | Bắt buộc | Mặc định | Mô tả | |------------|----------|----------|-------| | igUserId / userId | ✅ | — | User ID | | accessToken | ✅ | — | Access Token | | apiVersion | — | v22.0 | Phiên bản Graph API | | pollIntervalMs | — | 3000 | Thời gian chờ giữa các lần kiểm tra (ms) | | pollMaxAttempts | — | 20 | Số lần kiểm tra tối đa |

TikTok

| Thuộc tính | Bắt buộc | Mặc định | Mô tả | |------------|----------|----------|-------| | accessToken | ✅ | — | OAuth 2.0 Access Token | | pollIntervalMs | — | 5000 | Thời gian chờ (ms) | | pollMaxAttempts | — | 24 | Số lần kiểm tra tối đa |


Ví dụ mẫu

Xem thư mục examples/:

| File | Nền tảng | |------|---------| | examples/facebook.ts | Facebook | | examples/instagram.ts | Instagram | | examples/threads.ts | Threads | | examples/twitter.ts | Twitter / X | | examples/linkedin.ts | LinkedIn | | examples/tiktok.ts | TikTok | | examples/youtube.ts | YouTube | | examples/pinterest.ts | Pinterest | | examples/telegram.ts | Telegram | | examples/zalo.ts | Zalo | | examples/combined.ts | Facebook + Instagram đồng thời |

Chạy ví dụ:

FB_PAGE_ID=xxx FB_ACCESS_TOKEN=yyy npx tsx examples/facebook.ts
TELEGRAM_BOT_TOKEN=xxx TELEGRAM_CHAT_ID=@kenh npx tsx examples/telegram.ts

Giấy phép

MIT