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,
    },
};

설정 필드

필드타입필수설명
hostStringIMAP 서버 호스트명 (빈 값 불가)
portu16IMAP 서버 포트 (TLS의 경우 일반적으로 993)
userStringIMAP 사용자 이름 (보통 이메일 주소)
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.11143브릿지 비밀번호

받은 편지함 동기화

sync 메서드는 IMAP 서버에 연결하고, 폴더를 선택하고, UID로 새 메시지를 페칭하고, SQLite에 저장합니다:

rust
use prx_email::plugin::SyncRequest;

plugin.sync(SyncRequest {
    account_id: 1,
    folder: Some("INBOX".to_string()),
    cursor: None,        // 마지막 저장된 커서에서 재개
    now_ts: now,
    max_messages: 100,   // 동기화당 최대 100개 메시지 페칭
})?;

동기화 흐름

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,         // 러너 틱당 최대 작업 수
    base_backoff_seconds: 10,   // 실패 시 초기 백오프
    max_backoff_seconds: 300,   // 최대 백오프 (5분)
};

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.