Thursday, August 29, 2013

Check Gmail inbox via Windows 7 PowerShell Part 2: message body

Here i wrote about how to quickly check gmail inbox messages using gmail rss feed and powershell. But what about getting the email body or applying some sort of filtering? Luckily, powershell allows us to execute c# code :)

We need something bigger, that rss, to get more information about our inbox message. And it is possible only if we connect to the mailbox via pop or imap (don't forget to enable pop/imap in the gmail mail box settings). The problem here is that we either have to implement the protocol or to find good 3rd party library for it. And why in the world you want to use powershell for it? :) But anyway, lets begin.

First of all we need some code in order to connect to our mail box and read the response. And i got some directly below (WARNING: quick and dirty 10-minutes-code. No exception handling, no taste and style. Just an example:) ):

$Source = @"

using System; 
using System.Text;

public class Program
{
    private const string Mailbox = "MAIL@GMAIL.COM";
    private const string Password = "PASSWORD";

    private static System.Net.Sockets.TcpClient _tcpClient;
    private static System.Net.Security.SslStream _sslStream;
    private static  StringBuilder _sb = new StringBuilder();
    private static byte[] _responseBuffer;
    private static byte[] _buf;
    private static int _bytes = -1;

    public static void Main()
    {
        _tcpClient = new System.Net.Sockets.TcpClient("imap.gmail.com", 993);
        _sslStream = new System.Net.Security.SslStream(_tcpClient.GetStream());
        _sslStream.AuthenticateAsClient("imap.gmail.com");
        ReadResponse("");
        ReadResponse("$ LOGIN "+Mailbox + " " + Password + "  \r\n");
        ReadResponse("$ LIST " + "\"\"" + " \"*\"" + "\r\n");
        ReadResponse("$ SELECT INBOX\r\n");
        ReadResponse("$ STATUS INBOX (MESSAGES)\r\n");
        ReadResponse("$ FETCH 1 BODY[TEXT]\r\n");
        ReadResponse("$ LOGOUT\r\n");
    }

    private static void ReadResponse(string command)
    {
        if (command != "")
        {
            if (_tcpClient.Connected)
            {
                _buf = Encoding.ASCII.GetBytes(command);
                _sslStream.Write(_buf, 0, _buf.Length);
            }
        }
        _sslStream.Flush();
        _responseBuffer = new byte[2048];
        _bytes = _sslStream.Read(_responseBuffer, 0, 2048);
        _sb.Append(Encoding.ASCII.GetString(_responseBuffer));
        Console.WriteLine(_sb.ToString());
        _sb = new StringBuilder();
    }

}
"@

Add-Type -TypeDefinition $Source 

[Program]::Main()

Add-Type -TypeDefinition $Source this line adds our class to current powershell session and this [Program]::Main() is how we access implemented methods of our class.

This is the code for powershell, which allow us to get one unread message from inbox. Paste it in powershell console (don't forget to change email and password in script). Wow, a lot of information suddenly appears. And somewhere in this mess there is our tiny little message body:

But what about all messages, about parsing and filtering? Well, that is up to you :) For example, to get all the messages you have to parse the response for STATUS command, and the response looks something like this

{* STATUS "INBOX" (MESSAGES 1)
$ OK Success
}

So the amount of messages is there, it's just waiting to be parsed. Same is for headers and all the other information: you can get anything, but first you need to implement necessery commands. :) And this is just an example how to use c# and powershell to get 1 tiny little email body from your mail box. That's all.

If you really need all the strength of imap protocol better idea will be to use existing protocol implementations. On the other side, reinventing the bicycle is the good way to learn.

3 comments :

  1. Hi
    Can you help a little bit on how to parse and get information from two or more new emails?
    Regards

    ReplyDelete
  2. This blog is very interesting and informative... i like this post and i feel very happy to read this article... Keep it up!!!
    thanks for sharing...
    More info:- Gmail Technical Support

    ReplyDelete
  3. This is amazing! I had to setup two-factor auth and generate an app password, but it is working beautifully now!

    ReplyDelete