✉️

Upyo 0.4.0 リリース:モダンなプロトコルへの対応とメール認証機能の強化

に公開

Upyoは、Node.js、Deno、Bun、エッジファンクションなど、あらゆるJavaScriptランタイムで動作するモダンなメール送信ライブラリです。SMTP、Mailgun、SendGrid、Amazon SESなど主要なトランスポートを網羅し、共通のAPIでシームレスなメール送信を実現します。

Upyo 0.4.0では、待望のJMAPトランスポートの追加、SMTPでのDKIM署名への対応、そして冪等性キーのハンドリング改善を行いました。今回のアップデートにより、最新プロトコルへの対応とメールの信頼性がさらに向上しています。

JMAPトランスポートの導入

新しい@upyo/jmapパッケージにより、次世代のメールプロトコルJMAP(JSON Meta Application Protocol)に対応しました。JMAPはRFC 8620およびRFC 8621で標準化されており、従来のSMTPとは異なり、標準的なHTTPリクエストとJSONペイロードを利用します。ステートレスな特性を持つため、サーバーレス環境やエッジコンピューティングでの利用に最適です。

import { JmapTransport } from "@upyo/jmap";

const transport = new JmapTransport({
  sessionUrl: "https://mail.example.com/.well-known/jmap",
  bearerToken: "your-bearer-token",
});

const receipt = await transport.send(message);

トランスポート層でセッションディスカバリとキャッシュを自動的に処理するため、不要なラウンドトリップを最小限に抑えます。送信者のアイデンティティはFromアドレスから自動解決され、Bearerトークン認証とBasic認証の両方に対応しています。

また、JMAPの強力な機能であるリクエストのバッチ処理もサポートしています。sendMany()メソッドを使用することで、複数のメールを単一のHTTPリクエストにまとめて効率的に一括送信できます。テキスト・HTMLコンテンツ、添付ファイル(インラインおよび通常)、CC/BCC、カスタムヘッダー、優先度設定など、Upyoの標準的なメッセージ機能をすべてサポートしています。

詳細はJMAPトランスポートのドキュメントをご覧ください。

インストール

npm  add     @upyo/jmap
pnpm add     @upyo/jmap
yarn add     @upyo/jmap
deno add jsr:@upyo/jmap
bun  add     @upyo/jmap

SMTPトランスポートのDKIM署名対応

SMTPトランスポートにおいて、送信ドメイン認証の標準であるDKIM(DomainKeys Identified Mail)署名がネイティブでサポートされました。外部ツールに頼ることなく、ライブラリ内で直接署名を付与できるようになります。これによりメールの到達率が向上し、迷惑メールとして扱われる可能性を低減できます。

import { SmtpTransport } from "@upyo/smtp";
import { readFileSync } from "node:fs";

const transport = new SmtpTransport({
  host: "smtp.example.com",
  port: 587,
  secure: false,
  auth: { user: "user@example.com", pass: "password" },
  dkim: {
    signatures: [{
      signingDomain: "example.com",
      selector: "mail",
      privateKey: readFileSync("./dkim-private.pem", "utf8"),
    }],
  },
});

本機能はWeb Crypto APIを用いて実装されており、各種ランタイム間での完全な互換性を確保しています。署名アルゴリズムはrsa-sha256(RFC 6376)とed25519-sha256(RFC 8463)の両方に対応し、1通のメールに対するマルチ署名も可能です。署名失敗時の動作も設定可能で、エラーをスローするか、署名なしで送信するかを選択できます。

秘密鍵はPEM形式の文字列に加え、Web Crypto APIのCryptoKeyオブジェクトとしても指定できます。詳細な設定についてはSMTPトランスポートのドキュメントを参照してください。

メッセージレベルの冪等性キー

Messageインターフェースに、オプションのidempotencyKeyプロパティを追加しました。これにより、アプリケーション側でリトライ処理を行う際の重複送信を確実に防ぐことができるようになります。

従来は送信を試行するたびに内部で新しいキーが生成されていたため、リトライ時に同一のメッセージとして認識されない課題がありました。メッセージ自体にキーを含めることで、リトライ時も一貫して同じキーが使用されます。

import { createMessage } from "@upyo/core";

const message = createMessage({
  from: "sender@example.com",
  to: "recipient@example.com",
  subject: "重要なお知らせ",
  content: { text: "..." },
  idempotencyKey: "unique-key-for-this-message",
});

// 同じメッセージオブジェクトでリトライしても、同一の冪等性キーが維持されます
await transport.send(message);

Resendトランスポートでは、このキーが提供されている場合に優先的に使用し、提供されない場合は自動生成にフォールバックします。また、本アップデートに伴い、冪等性キーがHTTPリクエストヘッダーではなくメールのカスタムヘッダーに誤って配置されていたバグも修正しています。


詳細な変更点についてはCHANGES.mdを参照してください。

ご質問やフィードバックはGitHubリポジトリまでお願いします。

Discussion