Skip to content
このページは AI の支援により作成・翻訳されました。誤りがあれば、改善にご協力ください。 GitHub で編集

IMAP設定

PRX-Emailはrustlsライブラリを使用してTLS経由でIMAPサーバーに接続します。パスワード認証とGmailおよびOutlook用のXOAUTH2をサポートします。受信トレイ同期はUIDベースで増分的に行われ、カーソルはSQLiteデータベースに永続化されます。

基本的なIMAP設定

rust
use prx_email::plugin::{ImapConfig, AuthConfig};

let imap = ImapConfig {
    host: "imap.example.com".to_string(),
    port: 993,
    user: "[email protected]".to_string(),
    auth: AuthConfig {
        password: Some("your-app-password".to_string()),
        oauth_token: None,
    },
};

設定フィールド

フィールドタイプ必須説明
hostStringはいIMAPサーバーホスト名(空であってはならない)
portu16はいIMAPサーバーポート(TLSは通常993)
userStringはいIMAPユーザー名(通常はメールアドレス)
auth.passwordOption<String>いずれかIMAP LOGINのアプリパスワード
auth.oauth_tokenOption<String>いずれかXOAUTH2のOAuthアクセストークン

認証

passwordまたはoauth_tokenのいずれか一方のみを設定する必要があります。両方または両方なしの場合は検証エラーになります。

一般的なプロバイダ設定

プロバイダホストポート認証方式
Gmailimap.gmail.com993アプリパスワードまたはXOAUTH2
Outlook / Office 365outlook.office365.com993XOAUTH2(推奨)
Yahooimap.mail.yahoo.com993アプリパスワード
Fastmailimap.fastmail.com993アプリパスワード
ProtonMail Bridge127.0.0.11143Bridgeパスワード

受信トレイの同期

syncメソッドはIMAPサーバーに接続し、フォルダを選択し、UIDで新しいメッセージを取得し、SQLiteに保存します:

rust
use prx_email::plugin::SyncRequest;

plugin.sync(SyncRequest {
    account_id: 1,
    folder: Some("INBOX".to_string()),
    cursor: None,        // Resume from last saved cursor
    now_ts: now,
    max_messages: 100,   // Fetch at most 100 messages per sync
})?;

同期フロー

mermaid
sequenceDiagram
    participant Plugin as EmailPlugin
    participant DB as SQLite
    participant IMAP as IMAP Server

    Plugin->>DB: Load sync cursor for account/folder
    Plugin->>IMAP: TLS Connect + Login/XOAUTH2
    Plugin->>IMAP: SELECT folder
    Plugin->>IMAP: UID SEARCH (from cursor+1)
    IMAP-->>Plugin: UID list
    loop Each UID
        Plugin->>IMAP: UID FETCH (RFC822)
        IMAP-->>Plugin: Raw message
        Plugin->>Plugin: Parse MIME (headers, body, attachments)
        Plugin->>DB: UPSERT message
    end
    Plugin->>DB: Update sync cursor
    Plugin->>IMAP: LOGOUT

増分同期

PRX-EmailはUIDベースのカーソルを使用してメッセージの再取得を防ぎます。各同期後:

  1. 見た最高のUIDがカーソルとして保存されます
  2. 次の同期はcursor + 1から始まります
  3. 既存の(account_id, message_id)ペアを持つメッセージは更新されます(UPSERT)

カーソルは複合キー(account_id, folder_id)を持つsync_stateテーブルに保存されます。

マルチフォルダ同期

同じアカウントの複数のフォルダを同期します:

rust
for folder in &["INBOX", "Sent", "Drafts", "Archive"] {
    plugin.sync(SyncRequest {
        account_id,
        folder: Some(folder.to_string()),
        cursor: None,
        now_ts: now,
        max_messages: 100,
    })?;
}

同期スケジューラ

定期的な同期には組み込みの同期ランナーを使用します:

rust
use prx_email::plugin::{SyncJob, SyncRunnerConfig};

let jobs = vec![
    SyncJob { account_id: 1, folder: "INBOX".into(), max_messages: 100 },
    SyncJob { account_id: 1, folder: "Sent".into(), max_messages: 50 },
    SyncJob { account_id: 2, folder: "INBOX".into(), max_messages: 100 },
];

let config = SyncRunnerConfig {
    max_concurrency: 4,         // Max jobs per runner tick
    base_backoff_seconds: 10,   // Initial backoff on failure
    max_backoff_seconds: 300,   // Maximum backoff (5 minutes)
};

let report = plugin.run_sync_runner(&jobs, now, &config);
println!(
    "Run {}: attempted={}, succeeded={}, failed={}",
    report.run_id, report.attempted, report.succeeded, report.failed
);

スケジューラの動作

  • 並行性キャップ: ティックごとに最大max_concurrencyジョブが実行される
  • 失敗バックオフ: base * 2^failuresの計算式で指数バックオフ、max_backoff_secondsでキャップ
  • 期限確認: バックオフウィンドウが経過していない場合はジョブがスキップされる
  • 状態追跡: account::folderキーごとに(next_allowed_at, failure_count)を追跡

メッセージパース

受信メッセージはmail-parserクレートを使用して以下の抽出を行います:

フィールドソース備考
message_idMessage-IDヘッダー生バイトのSHA-256にフォールバック
subjectSubjectヘッダー
senderFromヘッダーの最初のアドレス
recipientsToヘッダーのすべてのアドレスカンマ区切り
body_text最初のtext/plainパート
body_html最初のtext/htmlパートフォールバック: 生セクション抽出
snippetbody_textまたはbody_htmlの最初の120文字
references_headerReferencesヘッダースレッドのため
attachmentsMIME添付ファイルパートJSONシリアライズされたメタデータ

TLS

すべてのIMAP接続はwebpki-roots証明書バンドルを持つrustls経由でTLSを使用します。TLSを無効にするオプションやSTARTTLSを使用するオプションはありません。接続は常に最初から暗号化されます。

次のステップ

Released under the Apache-2.0 License.