2009-07-05 7 views
18

Je suis en train d'écrire une application cliente qui récupère des courriels d'un serveur IMAP, puis les stocke dans une base de données. Le problème est qu'une fois que j'ai vérifié le courrier, la prochaine fois que je veux seulement télécharger le courrier qui est arrivé depuis. Donc, si j'avais vérifié le serveur il y a deux heures, je veux seulement recevoir le courrier qui est arrivé dans les deux dernières heures.Récupération de nouveaux messages à partir d'un serveur IMAP

Je pourrais utiliser SEARCH avec SINCE DATE, mais il n'y a pas de support pour le temps + date pourrait être facilement usurpée.

J'ai également essayé le drapeau RECENT, mais cela ne semble pas fonctionner avec gmail (en ruby ​​il montre nil à chaque fois).

Répondre

40

Vous souhaitez utiliser l'ID unique (UID) pour les messages. C'est spécifiquement pourquoi il a été créé. Vous voudrez garder une trace du dernier UID demandé, puis, pour demander tous les nouveaux messages, utilisez le message "[UID]: *", où [UID] est la valeur UID réelle. Par exemple, disons que le dernier message feteched avait un identifiant unique de "123456". Vous chercher

123456: *

Ensuite, jeter le premier message retourné.

Les UID sont supposés être stables d'une session à l'autre et ne changent jamais et leur valeur augmente toujours. Le catch pour vérifier ceci, est de vérifier la UIDValidity lorsque vous sélectionnez le dossier. Si le numéro UIDValidity n'a pas changé, les UID doivent toujours être valides entre les sessions.

Voici les parties pertinentes de la RFC:

2.3.1.1. L'identificateur unique (UID) Message Attribut

Une valeur de 32 bits attribué à chaque message, qui, lorsqu'il est utilisé avec le identificateur valeur de validité uniques (voir ci-dessous) forme une valeur de 64 bits qui doit pas faire référence à tout autre message dans la boîte aux lettres ou toute boîte aux lettres ultérieure avec le même nom pour toujours. Les identificateurs uniques sont attribués de manière strictement ascendante dans la boîte aux lettres; à chaque fois qu'un message est ajouté à la boîte aux lettres, un UID supérieur est affecté au message qui a été ajouté précédemment. Contrairement aux numéros de séquence , les identificateurs uniques ne sont pas nécessairement contigus.

L'identificateur unique d'un message NE DOIT PAS changer au cours de la session , et NE DEVRAIT PAS changer entre les sessions. Toute modification de identificateurs uniques entre les sessions DOIT être détectable à l'aide du mécanisme UIDVALIDITY décrit ci-dessous.Les identificateurs uniques persistants sont requis pour qu'un client resynchronise son état d'une précédente session avec le serveur (par exemple, clients déconnectés ou hors connexion ); ceci est discuté plus en détail dans [IMAP-DISC].

Note: La prochaine valeur d'identifiant unique est destiné à fournir un moyen pour un client afin de déterminer si des messages ont été livrés à la boîte aux lettres depuis le temps précédent le vérifier cette valeur.

Voici le lien avec plus d'informations:

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

Ce que je ferais, est aussi garder une trace du INTERNALDATE des messages téléchargés. De cette façon, si vous perdez jamais la synchronisation d'UID, vous pouvez au moins parcourir les messages et trouver le dernier que vous avez téléchargé, basé sur le InternalDate du message.

+0

oui c'est parfait! soyez sûr que vous exécutez la commande "UID 123: *" au lieu de simplement "123: *" qui renvoie des résultats inattendus - par exemple. client.Folders.Inbox.Search ("UID 123: *") –

4

Il y a un drapeau imap appelé "vu". La plupart des clients marqueraient un message vu lors de l'affichage du message, de sorte que vous souhaitiez parcourir les messages sur le serveur qui ne possèdent pas cet indicateur.

Voici un extrait de code qui devrait vous donner la bonne idée. Le bit opératoire est bien sûr

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

merci, mais mon application n'est pas la seule qui a accès à ce compte de messagerie. Par exemple, un message particulier aurait pu être lu dans Outlook, et ainsi marqué comme "vu". L'utilisation de "vu" ferait que ma demande me manque. –

+0

Dans ce cas, vous pouvez simplement parcourir les en-têtes Message-Id du courrier sur le serveur et comparer avec ce que vous avez dans la base de données. http://www.freesoft.org/CIE/RFC/850/10.htm – JosefAssad

0

Si vous êtes-vous capable de filtrer le courrier entrant dans un dossier IMAP spécifique sur le côté serveur, votre application peut lire les nouveaux messages dans ce dossier, puis les déplacer dans la norme INBOX dossier après c'est fait.

Questions connexes