mcpField
P
pinme-email

pinme-email

github.com/glitternetwork開発3.8k501 回インストール15 週間前に更新
リポジトリ

pinme-email について

PinMe Worker から PinMe のメール API を呼び出す TypeScript ガイドです。自動注入される認証情報、リクエスト形式、エラー処理を説明します。

主な機能

  1. 01PinMe API 経由のメール送信
  2. 02自動注入される API 認証情報の利用
  3. 03任意の API ベース URL の設定
  4. 04API エラーの一元処理

活用シーン

  1. 01Worker から確認コードをメール送信
  2. 02Worker のルートでメール送信エラーを返却

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/glitternetwork/pinme --skill pinme-email

インストール後、Claude Code で/pinme-emailを入力して読み込まれたか確認します。

詳細

PinMe Worker のメール API 統合

PinMe Worker(TypeScript)から PinMe プラットフォームのメール送信 API を呼び出す方法を説明します。

環境変数

Worker の作成時に、以下の環境変数が自動的に注入されます。手動で設定する必要はありません。

// backend/src/worker.ts
export interface Env {
  DB: D1Database;
  API_KEY: string;      // Project API Key — used for send_email authentication
  BASE_URL?: string;    // Optional override for PinMe API base URL, defaults to https://pinme.cloud
}

API_KEY は、Worker が PinMe プラットフォーム API を呼び出すための唯一の認証情報です。BASE_URL が設定されていない場合は、https://pinme.cloud が既定値として使用されます。


メール送信 API

エンドポイント: POST {BASE_URL}/api/v4/send_email 認証: X-API-Key ヘッダー(env.API_KEY を使用) 送信者: 自動的に {project_name}@pinme.cloud に設定されます

リクエスト形式
{
  "to": "[email protected]",
  "subject": "Your verification code",
  "html": "<p>Your code is <strong>123456</strong></p>"
}
フィールド型必須説明
tostringはい受信者のメールアドレス
subjectstringはいメールの件名
htmlstringはいHTML 本文
レスポンス形式

成功(200):

{ "code": 200, "msg": "ok", "data": { "ok": true } }

エラー:

HTTP ステータス意味data.error の例
401API キーがない、または無効です"X-API-Key header is required" / "Invalid API key"
400パラメーターの検証に失敗しました"Invalid email address" / "Subject is required"
500メールサービスのエラー"Failed to send email"
Worker のコード例
async function sendEmail(env: Env, to: string, subject: string, html: string): Promise<{ ok: boolean; error?: string }> {
  const baseUrl = env.BASE_URL ?? 'https://pinme.cloud';
  const resp = await fetch(`${baseUrl}/api/v4/send_email`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': env.API_KEY,
    },
    body: JSON.stringify({ to, subject, html }),
  });

  const result = await resp.json() as { code: number; msg: string; data?: { ok?: boolean; error?: string } };

  if (resp.status !== 200 || result.code !== 200) {
    return { ok: false, error: result.data?.error || result.msg || 'Unknown error' };
  }
  return { ok: true };
}

// Usage in routes
async function handleSendVerification(request: Request, env: Env): Promise<Response> {
  const { email } = await request.json() as { email: string };
  const code = Math.random().toString().slice(2, 8);

  const result = await sendEmail(env, email, 'Verification Code',
    `<p>Your code is <strong>${code}</strong></p>`);

  if (!result.ok) {
    return json({ error: result.error }, 500);
  }
  return json({ ok: true });
}

エラー処理パターン

PinMe プラットフォーム API の統一レスポンス形式:

interface PinmeResponse<T = unknown> {
  code: number;   // 200=success, other=failure
  msg: string;    // "ok" | "error" | "invalid params"
  data?: T;       // Business data on success, may contain { error: string } on failure
}
推奨される統一エラーハンドラー
async function callPinmeAPI<T>(url: string, apiKey: string, body: unknown): Promise<{ data?: T; error?: string }> {
  let resp: Response;
  try {
    resp = await fetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'X-API-Key': apiKey },
      body: JSON.stringify(body),
    });
  } catch {
    return { error: 'Network error' };
  }

  if (!resp.ok) {
    try {
      const err = await resp.json() as PinmeResponse;
      return { error: err.data && typeof err.data === 'object' && 'error' in err.data
        ? (err.data as { error: string }).error
        : err.msg || `HTTP ${resp.status}` };
    } catch {
      return { error: `HTTP ${resp.status}` };
    }
  }

  const result = await resp.json() as PinmeResponse<T>;
  if (result.code !== 200) {
    return { error: result.data && typeof result.data === 'object' && 'error' in result.data
      ? (result.data as { error: string }).error
      : result.msg };
  }
  return { data: result.data as T };
}
使用例
const baseUrl = env.BASE_URL ?? 'https://pinme.cloud';

// Send email
const emailResult = await callPinmeAPI<{ ok: boolean }>(
  `${baseUrl}/api/v4/send_email`, env.API_KEY,
  { to: '[email protected]', subject: 'Hello', html: '<p>Hi</p>' },
);
if (emailResult.error) return json({ error: emailResult.error }, 500);

コメント