2009-07-05 38 views
18

Tôi đang viết ứng dụng khách tìm nạp email từ máy chủ IMAP và sau đó lưu trữ chúng trong cơ sở dữ liệu. Vấn đề là khi tôi đã kiểm tra thư, lần sau tôi chỉ muốn tải xuống thư đã đến từ đó. Vì vậy, nếu tôi đã kiểm tra máy chủ cho thư hai giờ trước, tôi chỉ muốn nhận được thư đã đến trong hai giờ qua.Chỉ nhận thư mới từ máy chủ IMAP

Tôi có thể sử dụng TÌM KIẾM với NGÀY SINCE, nhưng không có hỗ trợ cho ngày + thời gian có thể dễ dàng bị giả mạo.

Tôi cũng đã thử cờ RECENT, nhưng điều đó dường như không hoạt động với gmail (trong ruby ​​nó hiển thị nil mọi lúc).

Trả lời

40

Bạn muốn sử dụng UniqueId (UID) cho thư. Đây là lý do tại sao nó được tạo ra.

Bạn sẽ muốn theo dõi UID cuối cùng được yêu cầu, và sau đó, để yêu cầu tất cả thư mới bạn sử dụng bộ thông báo "[UID]: *", trong đó [UID] là giá trị UID thực tế. Ví dụ:

Ví dụ: cho phép thông báo cuối cùng được kích hoạt có id duy nhất là "123456". Bạn sẽ tìm nạp

123456: *

Sau đó, hãy hủy thư trả về đầu tiên.

UID được 'cho là' ổn định qua các phiên và không bao giờ thay đổi và luôn tăng giá trị. Việc nắm bắt để xác minh điều này, là kiểm tra UIDValidity khi bạn chọn thư mục. Nếu số UIDValidity không thay đổi, thì UID sẽ vẫn hợp lệ trong các phiên.

Dưới đây là các phần liên quan từ RFC:

2.3.1.1. Mã định danh duy nhất (UID) Thuộc tính

Giá trị 32 bit được gán cho mỗi thư, được sử dụng với giá trị giá trị 64 bit giá trị 64 bit KHÔNG PHẢI tham chiếu đến bất kỳ thư nào khác trong hộp thư hoặc bất kỳ hộp thư tiếp theo nào có cùng tên mãi mãi. Số nhận dạng duy nhất được gán theo kiểu tăng dần trong hộp thư; vì mỗi thông báo được thêm vào hộp thư, nó được gán UID cao hơn các thông báo đã được thêm trước đó. Không giống như chuỗi thông báo số, số nhận dạng duy nhất không nhất thiết phải tiếp giáp.

Mã định danh duy nhất của tin nhắn KHÔNG PHẢI thay đổi trong phiên và KHÔNG được thay đổi giữa các phiên. Bất kỳ thay đổi nào của số nhận dạng duy nhất giữa các phiên PHẢI được phát hiện bằng cách sử dụng cơ chế UIDVALIDITY được thảo luận bên dưới.Số nhận dạng duy nhất liên tục được yêu cầu để khách hàng đồng bộ hóa trạng thái của nó từ phiên trước với máy chủ (ví dụ: ngắt kết nối hoặc truy cập ngoại tuyến khách hàng); điều này được thảo luận thêm trong [IMAP-DISC].

Lưu ý: Giá trị định danh duy nhất tiếp theo là nhằm cung cấp một phương tiện cho một khách hàng để xác định xem bất kỳ thông điệp đã được gửi đến hộp thư kể từ lần trước nó kiểm tra giá trị này.

Dưới đây là liên kết với biết thêm:

http://www.faqs.org/rfcs/rfc3501.html

Những gì tôi sẽ làm gì, cũng được theo dõi các InternalDate của các tin nhắn tải về. Bằng cách này, nếu bạn bị mất đồng bộ hóa UID, bạn ít nhất có thể lặp lại thông qua các thư và tìm thư cuối cùng bạn đã tải xuống, dựa trên InternalDate của thư.

+0

có điều này là hoàn hảo! hãy chắc chắn rằng bạn chạy lệnh "UID 123: *" thay vì chỉ "123: *" trả về kết quả không mong muốn - ví dụ: client.Folders.Inbox.Search ("UID 123: *") –

4

Có một cờ imap có tên "đã xem". Hầu hết các khách hàng sẽ đánh dấu một thông báo được nhìn thấy khi xem tin nhắn, vì vậy bạn muốn lặp lại các tin nhắn trên máy chủ không có bộ cờ đó.

Đây là đoạn mã sẽ cung cấp cho bạn ý tưởng đúng. Bit phẫu dĩ nhiên là

imap.search(["NOT", "SEEN"]).each do bla.bla.bla 
+0

cảm ơn, nhưng đơn đăng ký của tôi không phải là người duy nhất có quyền truy cập vào tài khoản email đó. Ví dụ, một thông điệp cụ thể có thể đã được đọc trong triển vọng, và do đó được đánh dấu là "nhìn thấy". Sử dụng "nhìn thấy" sẽ làm cho ứng dụng của tôi bỏ lỡ nó. –

+0

Trong trường hợp đó, bạn có thể chỉ muốn lặp lại các tiêu đề Message-Id trong thư trên máy chủ và so sánh với những gì bạn có trong cơ sở dữ liệu. http://www.freesoft.org/CIE/RFC/850/10.htm – JosefAssad

0

Nếu bạn là bạn có thể lọc thư đến vào một thư mục IMAP cụ thể về phía máy chủ, ứng dụng của bạn có thể đọc tin nhắn mới trong thư mục đó và sau đó di chuyển chúng vào INBOX tiêu chuẩn sau khi hoàn tất.

Các vấn đề liên quan