Node.jsアプリケーションに荷物追跡を追加するのは複雑である必要はありません。このチュートリアルでは、WhereParcel SDKを使って、インストールからリアルタイムWebhook通知まで実装します。

前提条件

  • Node.js 18+(SDKはネイティブfetchを使用)
  • WhereParcel APIキー(無料取得

ステップ1:SDKインストール

npm install whereparcel

ゼロ依存 — Node.js組み込みAPIのみを使用します。

ステップ2:クライアント初期化

import { WhereParcel } from 'whereparcel';

const wp = new WhereParcel(
  process.env.WHEREPARCEL_API_KEY!,
  process.env.WHEREPARCEL_SECRET_KEY!
);

APIキーは環境変数に保存してください。ソースコードにハードコードしないでください。

ステップ3:荷物を追跡

最も基本的な使い方 — 配送業者コードと追跡番号で単件追跡:

const response = await wp.track([
  { carrier: 'us.usps', trackingNumber: '9400111899562537866361' },
]);

console.log(response.summary);
// { total: 1, success: 1, failed: 0, usageIncremented: 1 }

for (const result of response.results) {
  if (result.status === 'success') {
    console.log(`ステータス: ${result.data.deliveryStatus}`);
    // ステータス: in_transit
  }
}

配送ステータス一覧

WhereParcelはすべての配送業者のステータスを以下の値に統一します:

ステータス説明
pendingラベル作成済み、まだ集荷されていない
in_transit配送中
out_for_delivery配達に出発
delivered配達完了
failed配達失敗
returned返送
cancelled配送キャンセル
unknownステータス確認不可

ステップ4:一括追跡

ECサイトのように大量の注文を追跡する場合はバルクAPIを使用(リクエストあたり最大5件):

const response = await wp.track([
  { carrier: 'us.usps', trackingNumber: '9400111899562537866361' },
  { carrier: 'us.fedex', trackingNumber: '123456789012' },
  { carrier: 'us.ups', trackingNumber: '1Z999AA10123456784' },
]);

console.log(response.summary);
// { total: 3, success: 3, failed: 0, usageIncremented: 3 }

for (const result of response.results) {
  if (result.status === 'success') {
    console.log(`${result.carrier}: ${result.data.deliveryStatus}`);
  }
}

ステップ5:配送業者コードを確認

どの配送業者コードを使えばいいかわからない場合:

// 全500+配送業者
const allCarriers = await wp.getCarriers();

// 米国の配送業者のみ
const usCarriers = await wp.getCarriersByCountry('us');
// ['us.fedex', 'us.ups', 'us.usps', ...]

// サポート国一覧
const countries = await wp.getCountries();
// ['kr', 'us', 'jp', 'cn', 'de', ...]

配送業者コードの形式:{国}.{業者} — 例:us.fedexkr.cjjp.yamato

ステップ6:Webhookを設定

ポーリングの代わりに、WhereParcelがステータス変更時に通知するよう設定:

6a. Webhookエンドポイント作成

const endpoint = await wp.createWebhookEndpoint({
  name: 'My App - Production',
  url: 'https://myapp.com/api/webhooks/tracking',
});

console.log(endpoint.endpointId); // 'endpoint_abc123'
console.log(endpoint.secret);     // 'whsec_...'

6b. モニタリング登録

await wp.registerWebhook({
  trackingItems: [
    { carrier: 'us.usps', trackingNumber: '9400111899562537866361' },
    { carrier: 'us.fedex', trackingNumber: '123456789012' },
  ],
  recurring: true,
  webhookEndpointId: endpoint.endpointId,
});

recurring: trueを設定すると、配達完了までステータス変更のたびに通知を受け取ります。

6c. Webhookイベントを処理

Express/Fastify/Next.jsアプリにWebhookハンドラーを追加:

app.post('/api/webhooks/tracking', (req, res) => {
  const { carrier, trackingNumber, deliveryStatus, events } = req.body;

  console.log(`${carrier} ${trackingNumber}: ${deliveryStatus}`);

  // DB更新、顧客通知など

  res.status(200).json({ received: true });
});

エラーハンドリングのベストプラクティス

常にエラーを適切に処理してください:

import {
  WhereParcel,
  AuthenticationError,
  RateLimitError,
  NotFoundError,
} from 'whereparcel';

try {
  const result = await wp.track([{ carrier: 'us.usps', trackingNumber: '...' }]);
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('認証失敗 — APIキーを確認してください');
  } else if (error instanceof RateLimitError) {
    const retryAfter = error.retryAfter ?? 60;
    console.error(`レート制限。${retryAfter}秒後にリトライ`);
  } else if (error instanceof NotFoundError) {
    console.error('配送業者またはエンドポイントが見つかりません');
  }
}

完全な例:Express追跡サーバー

WhereParcelをラップしたシンプルなExpressサーバー:

import express from 'express';
import { WhereParcel } from 'whereparcel';

const app = express();
const wp = new WhereParcel(
  process.env.WHEREPARCEL_API_KEY!,
  process.env.WHEREPARCEL_SECRET_KEY!
);

app.get('/track/:carrier/:trackingNumber', async (req, res) => {
  const { carrier, trackingNumber } = req.params;
  const result = await wp.track([{ carrier, trackingNumber }]);
  res.json(result);
});

app.listen(3000, () => console.log('追跡サーバー起動中 :3000'));

テスト:

curl http://localhost:3000/track/us.usps/9400111899562537866361

次のステップ