Gmail X-GM-MSGID

0 votes
asked Sep 21, 2011 by kleinux (180 points)
edited Sep 21, 2011

Can someone shed some light on how I would go about issuing this command with the secure imap library?

http://code.google.com/apis/gmail/imap/#x-gm-msgid

This code snippet seems to succeed, but now I'm not sure how to get the e-mail;

long v;
bool passed = long.TryParse(param, System.Globalization.NumberStyles.HexNumber, null, out v);
_imap.SendCommand(string.Format("FETCH 1 (X-GM-MSGID)", v));
var p= _imap.ReadResponse();
Console.WriteLine("{0}: {1}", p.Code, p.Description);

"Ok: Success" is printed to the console.

Applies to: Rebex Secure Mail

1 Answer

0 votes
answered Sep 21, 2011 by Lukas Matyska (54,470 points)
edited Sep 21, 2011

The response data is stored within ImapResponseLine field which can be accessed by calling the response.GetLines() method.

Following code tries to solve the problem described at your previous question, but unfortunately Gmail changes the X-GM-MSGID value after sending the message from web interface.

{
    // ...

    // prepare a message
    MailMessage mail = new MailMessage();
    mail.To = "some@domain";
    mail.Subject = "Test X-GM-MSGID";
    mail.BodyText = "This is a X-GM-MSGID test.";

    // store message and receive its UniqueId
    string uid = imap.StoreMessage("[Gmail]/Drafts", mail);

    // select Draft folder and receive X-GM-MSGID
    imap.SelectFolder("[Gmail]/Drafts", true);
    string msgid = GetGmailMsgId(imap, uid);

    // select Sent Mails folder and get message info using X-GM-MSGID
    imap.SelectFolder("[Gmail]/Sent Mail", true);
    ImapMessageInfo mailInfo = GetMessageInfo(imap, msgid, ImapListFields.Envelope);
}

private static readonly Regex GmailMsgIdRegex = new Regex("X-GM-MSGID (?<msgid>[0-9]+)");

private static string GetGmailMsgId(Imap imap, string uniqueId)
{
    // parse Rebex style UniqueId to IMAP style UniqueId
    long validity, uid;
    if (!ImapMessageSet.ParseUniqueId(uniqueId, out validity, out uid))
        throw new ImapException(string.Format("Invalid unique Id ('{0}').", uniqueId));

    // send UID FETCH X-GM-MSGID command
    imap.SendCommand("UID FETCH", uid.ToString(), "(X-GM-MSGID)");

    // read response
    ImapResponse response = imap.ReadResponse();
    if (response.Code != ImapResponseCode.Ok)
        throw new ImapException(response);

    // expected result is:
    // * 1 FETCH (X-GM-MSGID 1278455344230334865 UID 11)
    // OK FETCH (Success)
    ImapResponseLine[] lines = response.GetLines();
    if (lines == null || lines.Length == 0)
        throw new ImapException(string.Format("Message not found ('{0}').", uniqueId));
    if (lines.Length != 1)
        throw new ImapException(string.Format("Invalid response for UID FETCH X-GM-MSGID ('{0}').", uniqueId));

    Match match = GmailMsgIdRegex.Match(lines[0].Parameters);
    if (!match.Success)
        throw new ImapException(string.Format("Invalid response for UID FETCH X-GM-MSGID ('{0}').", uniqueId));

    return match.Groups["msgid"].Value;
}

private static ImapMessageInfo GetMessageInfo(Imap imap, string msgid, ImapListFields fields)
{
    // send UID SEARCH X-GM-MSGID command 
    imap.SendCommand("UID SEARCH", "X-GM-MSGID", msgid);

    // read response
    ImapResponse response = imap.ReadResponse();
    if (response.Code != ImapResponseCode.Ok)
        throw new ImapException(response);

    // expected result is:
    // * SEARCH 1
    // OK SEARCH (Success)
    ImapResponseLine[] lines = response.GetLines();
    if (lines == null || lines.Length == 0 || lines[0].Parameters.Length == 0)
        throw new ImapException(string.Format("Message not found ('{0}').", msgid));
    if (lines.Length != 1)
        throw new ImapException(string.Format("Invalid response for UID SEARCH X-GM-MSGID ('{0}').", msgid));

    // try to parse response, we expect one UID
    long uid;
    if (!long.TryParse(lines[0].Parameters, out uid))
        throw new ImapException(string.Format("Invalid response for UID SEARCH X-GM-MSGID ('{0}').", msgid));

    // convert IMAP style UniqueId to Rebex style UniqueId for further use
    string uniqueId = ImapMessageSet.BuildUniqueId(imap.CurrentFolder.ValidityId, uid);

    // return message info with specified fields
    return imap.GetMessageInfo(uniqueId, fields);
}
...