SDKNode.js SDK

SDK

Node.js SDK

@sofia-post/node で Node.js から Sofia API を呼び出し、投稿の公開・予約やメディアのアップロードを型付きで行えます。

公式の Node.js SDK は Sofia API v1 を Sofia という 1 つのクラスにまとめたものです。ルートごとに 1 つのメソッド、型付きのリクエストとレスポンス、そしてすべての失敗に共通の 1 つのエラー型を備えています。依存パッケージはなく、Node.js 20 以降で動作します。

インストール

SDK は npm に @sofia-post/node パッケージとして公開されています。import でも require でも使えます。

npm install @sofia-post/node

クイックスタート

キーを指定してクライアントを作成し、投稿先の店舗を見つけて、Instagram への投稿を予約します。

import { Sofia } from '@sofia-post/node';

const sofia = new Sofia(process.env.SOFIA_API_KEY);

const [establishment] = await sofia.establishments();

const post = await sofia.post({
  establishmentId: establishment.id,
  targets: [{ platform: 'instagram', text: 'Tarte tatin du jour 🍎' }],
  scheduledAt: new Date('2026-12-01T09:00:00Z'),
});

console.log(post.id, post.status);

認証

コンストラクタには、設定 › API の個人アクセスタブで作成した個人キーを渡します。アプリケーションが他の Sofia ユーザーの代わりに動作する場合は、OAuth アクセストークンを渡します(OAuth2)。SDK はリクエストのたびに Authorization: Bearer … として送信します。

クライアントは既定で https://api.sofia-post.com に接続します。2 番目の引数で、ベース URL やリクエスト送信に使う fetch を変更できます。

const sofia = new Sofia(apiKey, { baseUrl: 'http://localhost:3008' });

メソッド

メソッド内容
me()キーが誰の代わりに動作するか、そのスコープ、テストキーかどうか
platforms()各ネットワークのルール:文字数、メディア、フォーマット
establishments()キーが扱える店舗
accounts(establishmentId)店舗に接続されているソーシャルアカウント
connectionLink(establishmentId, input)Sofia がホストするページで、ネットワークを接続できます
insights(establishmentId, period?)リーチ、エンゲージメント、フォロワーをネットワークごとに取得
post(input, options?)今すぐ公開、scheduledAt で予約、または下書きとして保存
postList(filters?)店舗、ステータス、日付で絞り込んだ投稿の 1 ページ
getPost(id) · updatePost(id, input) · deletePost(id)投稿を 1 件取得、変更、または取り下げ
upload(input) · uploadFromUrl(input)ファイルまたは URL を店舗のメディアライブラリに追加
mediaList(filters) · getMedia(id) · deleteMedia(id)メディアライブラリの閲覧と整理
createWebhook(input) · webhooks() · deleteWebhook(id) · testWebhook(id)投稿が公開されたとき、または失敗したときに通知を受け取る

投稿

投稿にはネットワークごとに 1 つのターゲットがあり、それぞれに専用のテキスト、メディア、フォーマットがあります。まず dryRun で確認してください。何も書き込まれず、拒否された場合は違反しているルールがすべて一覧で返ります。idempotencyKey を渡すと、リクエストを再送しても二重に公開されません。scheduledAt には Date または ISO 8601 形式の文字列を渡せます。

import type { PublishPostInput } from '@sofia-post/node';

const input: PublishPostInput = {
  establishmentId,
  targets: [
    { platform: 'instagram', text: 'Menu du jour', media: [{ id: media.id }] },
    { platform: 'facebook', text: 'Menu du jour : tarte tatin et café' },
  ],
};

await sofia.post(input, { dryRun: true });
await sofia.post(input, { idempotencyKey: crypto.randomUUID() });

メディア

ファイルを 1 回アップロードし、その id を投稿の media に指定します。upload は Buffer、Uint8Array、Blob を受け取り、contentType を指定しない場合はファイル名からコンテンツタイプを判定します。uploadFromUrl では Sofia がファイルを自分でダウンロードします。

import { readFile } from 'node:fs/promises';

const media = await sofia.upload({
  establishmentId,
  file: await readFile('tarte-tatin.jpg'),
  fileName: 'tarte-tatin.jpg',
});

const imported = await sofia.uploadFromUrl({ establishmentId, url: 'https://example.com/menu.png' });

ページネーション

postList と mediaList は 1 ページずつ返します。ページの nextCursor を次の呼び出しの cursor に渡してください。最後のページにはありません。

let cursor: string | undefined;
do {
  const page = await sofia.postList({ establishmentId, status: 'published', limit: 100, cursor });
  page.data.forEach((post) => console.log(post.id));
  cursor = page.nextCursor;
} while (cursor);

エラー

API が呼び出しを拒否すると、各メソッドは SofiaApiError をスローします。HTTP の status、エラーエンベロープの安定した code、details(拒否された投稿では、違反しているネットワークのルールすべて)、サポートに伝える requestId、そして 429 の場合は retryAfterSeconds が含まれます。

import { SofiaApiError } from '@sofia-post/node';

try {
  await sofia.post(input);
} catch (error) {
  if (!(error instanceof SofiaApiError)) throw error;
  if (error.code === 'post_refused') console.log(error.details);
  if (error.status === 429) await wait(error.retryAfterSeconds);
}

API にまったく接続できない場合、エラーのコードは network_error、ステータスは 0 になります。SDK は自動で再試行しません。429 では retryAfterSeconds だけ待ち、5xx では間隔を空けて再試行してください。

TypeScript

パッケージには型定義が含まれています。PublishPostInput、Post、Media、SocialAccount、EstablishmentInsights などが Sofia と並んでエクスポートされるので、エディターがすべてのフィールドと列挙値を補完します。

次は:API リファレンスで SDK が呼び出すすべてのルートを確認できます。同じ API をターミナルから操作するのが CLI です。

このページは役に立ちましたか?