Mathematica has a function for sending mail (SendMail) and can import the MBOX format. But what I'd like to do is programmatically retrieve mail from a Gmail account, from within Mathematica on a Windows system. Is this possible?

Use case: I use MarineTraffic.com's e-mail notifications about ship arrivals to watch interesting ships as they pass by. I'd like to filter incoming messages from them and use data from previous notifications to filter 'seen' ships. I may want to do some automated lookup on ship names too to find those that are more likely to be interesting. A perfect task for Mathematica — if only I could periodically get the new mails and process them!

  • $\begingroup$ What ship is that in the photo? $\endgroup$ – acl Jun 26 '12 at 21:37
  • $\begingroup$ Do you mean a Vowelfail ship, for example? $\endgroup$ – Dr. belisarius Jun 27 '12 at 0:01
  • $\begingroup$ @acl It's the MPI Discovery. It's built for installing offshore wind turbines. Some time ago I saw it sail into the harbour while taking a walk in Valletta, it was quite surprising (and this is what motivated me to try to find 'interesting' ships). $\endgroup$ – Szabolcs Jun 27 '12 at 10:19
  • $\begingroup$ Since Mathematica 10.2 there is a new function called MailReceiverFunction which can be deployed to Wolfram Cloud and be used to effectively solve this problem. (Not gmail, but the analysis of email notifications.) $\endgroup$ – C. E. Aug 21 '16 at 8:59

I've implemented a java program using the JavaMail API to only fetch unread emails from a particular user (and mark it as read). This will allow you to periodically get emails from your ship traffic service. This is inspired by this blog post on Stephen Wolfram's email analytics.

1. Java code to fetch unread email from a sender

Below is the java code, which is saved in the file FetchMail.java.

import java.io.IOException                 ;
import java.util.Properties                ;
import javax.mail.*                        ;
import javax.mail.search.FlagTerm          ;
import javax.mail.internet.InternetAddress ;

public class FetchMail {
    public static String[] UnreadMail(
            String server   ,
            String folder   ,
            String from     ,
            String username ,
            String password
            ) {
        Properties props = System.getProperties()                                     ;
        props.setProperty("mail.store.protocol", "imaps")                             ;
        try {
            Session session  = Session.getDefaultInstance(props, null)                ;
            Store store      = session.getStore("imaps")                              ;
            store.connect(server, username, password)                                 ;
            Folder inbox     = store.getFolder(folder)                                ;
            inbox.open(Folder.READ_WRITE)                                             ;
            FlagTerm ft      = new FlagTerm(new Flags(Flags.Flag.SEEN), false)        ;
            Message msgs[]   = inbox.search(ft)                                       ;

            String[] emails  = new String[msgs.length]                                ;
            String[] content = new String[msgs.length]                                ;

            if (msgs.length > 0)
                for (int i = 0; i < msgs.length ; i++)
                    emails[i] = ((InternetAddress) msgs[i].getFrom()[0]).getAddress() ;
                    if (emails[i].equals(from))
                        content[i] = msgs[i].getContent().toString()                  ;
            store.close()                                                             ;
            return content                                                            ;
        catch (NoSuchProviderException e) {
            return null                                                               ;
        catch (MessagingException e) {
            return null                                                               ;
        catch (IOException e) {
            return null                                                               ;

Next, compile the above file. You will need the mail.jar file from the above API download. Drop it in the same folder and execute

javac -classpath ./mail.jar FetchMail.java

2. Calling it from Mathematica

After compiling, include the FetchMail.class file in the same directory as your Mathematica notebook. Here's a convenient function that uses this class file to fetch unread mail from the Gmail server from a particular sender

unreadMail[server_String, email_String, pass_String, folder_String, from_String] :=         
    DynamicModule[{messages, monthname2num, datelists, parsedate},
        messages = FetchMail`UnreadMail[server, folder, from, email, pass];
        DeleteCases[messages, Null]

3. Usage and caveats

Usage is fairly straightforward from the arguments. As a sample demonstration, I just marked the last email from you as unread and ran this function and voila!

unreadMail["imap.gmail.com", "myEmail@gmail.com", "hunter2", "Inbox", "szabolcsEmail"]

enter image description here

However, do note that

  • If you're running this as a ScheduledTask, you will have to enter your password as a string argument. Not necessarily a wise idea to do with your primary email ID, but you could always create a throwaway for this specific purpose and use that instead.
  • Unread mail from this sender is automatically marked as read when you fetch it. This is necessary so that you don't keep retrieving the same mail again and again. However if you're automating it, be aware that there might be some emails that you haven't read and might have missed.
  • $\begingroup$ If it let's me retrieve new mail only, this is a clear accept. Thank! $\endgroup$ – Szabolcs Jun 26 '12 at 20:58
  • $\begingroup$ @Szabolcs See my edit. $\endgroup$ – rm -rf Jun 27 '12 at 8:35
  • $\begingroup$ Wow, that is really great! I am going to set up a separate email account for this---the volume of notifications is just too great! $\endgroup$ – Szabolcs Jun 27 '12 at 9:51
  • $\begingroup$ While this is amazing, I think the JavaMail API must have changed since you posted this code, because getContent seems to return a MIME MultiPart now, instead of something that can be converted to a String. In particular, your Mathematica code doesn't seem to work (at least on my machine). $\endgroup$ – Steve D Dec 19 '12 at 4:30
  • 1
    $\begingroup$ @posting in 2016 — does anybody have a working version of this? I'd love to be able to check e-mail from within Mathematica without resorting to MailReceiverFunction and the cloud. $\endgroup$ – Michael Stern Apr 23 '16 at 0:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.