Thursday, November 24, 2016

Php read email & attachments from google using oauth

You can get access token & other details to perform this action:
http://pritomkumar.blogspot.com/2016/11/using-oauth-20-for-google-client-side.html

Code snippet to read email & attachments from google using oauth

<?php
session_start();
init();
if(isset($_GET["email_id"])) {
    email_details();
}
else if(isset($_GET["email_attachment"])) {
    email_attachment();
}
else {
    list_email();
}

function init() {
    $_SESSION["google_user_id"] = "11822454346345607576118";
    $_SESSION["access_token"] = "ya29.CjCgA8bf_BCrsdfsdfsdfsdf5orH3cvbMMzQY0RX8NUrbgpNhm9oXHyAAZ0WF3Jid4WwQ";

    /* Permissions to read email */
    $_SESSION["scope"] = "https://www.googleapis.com/auth/userinfo.profile"; /* User profile */
    $_SESSION["scope"] .= " https://www.googleapis.com/auth/gmail.readonly"; /* Read mail */
}

function email_attachment() {
    $id = $_GET["email_attachment"];
    $name = $_GET["name"];
    if (!file_exists("attachments")) {
        mkdir("attachments");
    }

    $apiUrl = "https://www.googleapis.com/gmail/v1/users/".$_SESSION["google_user_id"];
    $apiUrl .= "/messages/$id/attachments/".$id;
    $apiUrl .= "?access_token=".$_SESSION["access_token"];
    $remoteFile = decode_content(json_decode(make_request($apiUrl))->data);
    $file = "attachments/".md5(time()).$name;
    file_put_contents($file, $remoteFile);
    header("Location: $file");
    exit;
}

function email_details() {
    $id = $_GET["email_id"];
    $raw = "";// "format=raw&";
    $fields = "";// "fields=raw&";
    $apiUrl = "https://www.googleapis.com/gmail/v1/users/";
    $apiUrl .= $_SESSION["google_user_id"]."/messages/$id?$raw$fields";
    $apiUrl .= "access_token=".$_SESSION["access_token"];
    //echo $apiUrl; die();
    $result = json_decode(make_request($apiUrl));
    //file_put_contents("raw-email.txt", $result->raw); die();
    //echo "<pre>"; print_r($result); echo "</pre>"; die();

    $message = parse_email($result->payload->parts);
    $link = ""; $html = "";
    foreach($message as $msg) {
        if($msg["type"] == "html") {
            $html = $msg["body"];
        }
        else if($msg["type"] == "text") {
            //you can do anything with text part of email
        }
        else {
            $link .= "<a href='?email_attachment=".$msg["body"]."&name=".$msg["name"]."' target='_blank'>".$msg["name"]."</a><br/>";
        }
    }
    echo "<h3><i>Email Attachments:</i></h3>".$link."<h3><i>Email Body:</i></h3>".trim($html);
}

function parse_email($email) {
    $result = array();
    for($i = 0; $i < count($email); $i++) {
        $part = $email[$i];
        $mime = $part->mimeType;
        $name = $part->filename;
        if(strlen($name) > 0) {
            $file = array();
            $file["type"] = $mime;
            $file["name"] = $name;
            $file["body"] = $part->body->attachmentId;
            array_push($result, $file);
        }
        else if($mime === "text/plain") {
            $file = array();
            $file["type"] = "text";
            $file["name"] = "email_body_plain.html";
            $file["body"] = decode_content($part->body->data);
            array_push($result, $file);
        }
        else if($mime === "text/html") {
            $file = array();
            $file["type"] = "html";
            $file["name"] = "email_body_html.html";
            $file["body"] = decode_content($part->body->data);
            array_push($result, $file);
        }
        else if(substr($mime, 0, 9) === "multipart") {
            foreach(parse_email($part->parts) as $file) {
                array_push($result, $file);
            }
        }
    }
    return $result;
}

function decode_content($content) {
    return base64_decode(str_replace("-", "+", str_replace("_", "/", $content)));
}

function list_email() {
    //gmail api ref page: https://developers.google.com/gmail/api/v1/reference/
    //https://developers.google.com/gmail/api/v1/reference/users/messages/list
    //Searching filtering gmail over oauth2 api using php
    //https://developers.google.com/gmail/api/guides/filtering
    //https://support.google.com/mail/answer/7190?hl=en

    $search = "from:pritom@xxx.com OR from:pritomkucse@gmail.com"; //Search by from address
    $search = "subject:Fwd:"; //Words in the subject line
    $search = "label:sent OR label:starred"; //With certain labels
    $search = "has:attachment"; //Any email with attachments
    $search = "is:important"; //Important mails only
    $search = "is:read"; //For mails those are read already
    $search = "is:unread"; //For mails those are not read yet
    $search = "cc:pritomkucse@gmail.com"; //Emails has specific cc, bcc not allowed
    $search = "after:2016/11/19 AND label:inbox"; //Emails reached inbox after specific date
    $search = "before:2016/04/19 AND label:inbox"; //Emails reached inbox before specific date
    $search = "has:nouserlabels"; //Emails with no labels
    $search = "deliveredto:pritom@xxx.com"; //Emails delivered to some address
    $search = "size:10000"; //Email larger than bytes
    $search = "larger:15M"; //Emails larger than megabytes
    $search = "smaller:1M"; //Emails smaller than megabytes
    $search = "newer_than:1d"; //Emails newer than 1 day (d/m/y)
    $search = "older_than:20d"; //Emails older than 1 day (d/m/y)
    $search = "category:updates"; //Emails in specific category
    $search = "rfc822msgid:2021140448.450273.1479617087520.JavaMail.zimbra@bitmascot.com"; //Specific message by Message-ID
    $search = "!from:@gmail.com"; //Search by not from domain
    $search = "!from:pritomkucse@google.com"; //Search by not from address
    $search = ""; //No filtering

    $maxResults = 10;
    $apiUrl = "https://www.googleapis.com/gmail/v1/users/".$_SESSION["google_user_id"]."/messages?";
    $apiUrl .= "access_token=".$_SESSION["access_token"];
    $apiUrl .= "&maxResults=".$maxResults;
    if(strlen($search) > 0) {
        $apiUrl .= "&q=" . urlencode($search);
    }
    if(isset($_GET["next_page"]) && strlen($_GET["next_page"]) > 0) {
        $apiUrl .= "&pageToken=". $_GET["next_page"];
    }
    $result = json_decode(make_request($apiUrl));
    //echo "<pre>";print_r($result);echo "</pre>";die();

    if(isset($result->messages)) {
        foreach($result->messages as $m) {
            $link = "<a target='_blank' href='?email_id=".$m->id."'>View Message [[".$m->id . "]]</a><br/>";
            echo $link;
        }
    }
    else {
        echo "<pre>"; print_r($result); echo "</pre>"; die();
    }
    if(isset($result->nextPageToken)) {
        echo "<a href='?email=true&next_page=".$result->nextPageToken."'>Next_Page</a>";
    }
}

function make_request($url, $post = null, $headers = null, $returnArray = false) {
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_POST, $post == null ? 0 : 1);
    if($post != null) {
        curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
    }
    curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSLVERSION, 1);
    if($headers != null) {
        curl_setopt($curl, CURLOPT_HEADER, true);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    }
    $response = curl_exec($curl);
    $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    curl_close($curl);
    if($http_code >= 400) {
        echo "Error executing request to Office365 api with error code=$http_code<br/><br/>\n\n";
        echo "<pre>"; print_r($response); echo "</pre>";
        die();
    }
    if($returnArray) {
        return array(
            "response" => $response,
            "header_size" => $header_size
        );
    }
    return $response;
}
?>

Tuesday, November 22, 2016

Write a PHP app to get/read Outlook Office 365 mail using oauth connection

1. Go to https://apps.dev.microsoft.com/#/appList
2. Click on "Add an app"
3. Put a name on "New Application Registration" form such "My App"
4. And click "Create application" button
5. It will redirect to you your application page:
https://apps.dev.microsoft.com/#/application/da8a54d8-86b5-4196-981e-XXXXXXXXXX
6. Find the button "Generate New Password" and click
7. Copy the password: "pYJAiGeYTXXXXXXXvzhfp"
8. Find "Platforms" button and click "Add platform" and select "Web"
9. Enter your application url in the field "Redirect URIs" 
http://localhost/tappi/office.php (Your uri would be different)
10. And click on "Save" button
11. Done from this end.

Api reference: https://dev.outlook.com/restapi/reference




Now follow the php code snippet (full example to get user profile, read email & send email):


<?php
session_start();
init();

if(token()) {
    echo "<a href='".$_SESSION["redirect_uri"]."''>Home</a>";
    echo " || <a href='".$_SESSION["redirect_uri"]."?refresh_token=true'>Refresh token</a>";
    echo " || <a href='".$_SESSION["redirect_uri"]."?profile=true'>Profile</a>";
    echo " || <a href='".$_SESSION["redirect_uri"]."?list_email=true'>List Email</a>";
    echo " || <a href='".$_SESSION["redirect_uri"]."?logout=true'>Logout</a><br/><br/>\n\n";
}

if(isset($_GET["logout"])) {
    flush_token();
    echo "Logged out<br/>";
    echo "<a href='".$_SESSION["redirect_uri"]."'>Start new session</a>";
    die();
}
else if(isset($_GET["profile"])) {
    view_profile();
}
else if(isset($_GET["refresh_token"])) {
    refresh_token();
}
else if(isset($_GET["list_email"])) {
    list_email();
}
else if(isset($_GET["view_email"])) {
    view_email();
}
else if(isset($_GET["view_attachments"])) {
    view_attachments();
}
else if(token()) {
    echo "<pre>"; print_r(token()); echo "</pre>";
}
elseif (isset($_GET["code"])) {
    echo "<pre>";print_r($_GET);echo "</pre>";
    $token_request_data = array (
        "grant_type" => "authorization_code",
        "code" => $_GET["code"],
        "redirect_uri" => $_SESSION["redirect_uri"],
        "scope" => implode(" ", $_SESSION["scopes"]),
        "client_id" => $_SESSION["client_id"],
        "client_secret" => $_SESSION["client_secret"]
    );
    $body = http_build_query($token_request_data);
    $response = runCurl($_SESSION["authority"].$_SESSION["token_url"], $body);
    $response = json_decode($response);

    store_token($response);
    file_put_contents("office_active_user_id.txt", get_user_id());
    file_put_contents("office_access_token.txt", $response->access_token);
    header("Location: " . $_SESSION["redirect_uri"]);
}
else {
    $accessUrl = $_SESSION["authority"].$_SESSION["auth_url"];
    echo "<a href='$accessUrl'>Login with Office 365</a>";
}

function view_email() {
    $mailID = $_GET["view_email"];
    $userID = get_user_id();
    $headers = array(
        "User-Agent: php-tutorial/1.0",
        "Authorization: Bearer ".token()->access_token,
        "Accept: application/json",
        "client-request-id: ".makeGuid(),
        "return-client-request-id: true",
        "X-AnchorMailbox: ". get_user_email()
    );
    $outlookApiUrl = $_SESSION["api_url"] . "/Users('$userID')/Messages('$mailID')";
    $response = runCurl($outlookApiUrl, null, $headers);
    $response = explode("\n", trim($response));
    $response = $response[count($response) - 1];
    $response = json_decode($response, true);
    echo "<pre>"; print_r($response); echo "</pre>";
}

function view_attachments() {
    $mailID = $_GET["view_attachments"];
    $folder = "Office-" . md5($mailID);
    if(!file_exists($folder)) {
        mkdir($folder);
    }
    $userID = get_user_id();
    $headers = array(
        "User-Agent: php-tutorial/1.0",
        "Authorization: Bearer ".token()->access_token,
        "Accept: application/json",
        "client-request-id: ".makeGuid(),
        "return-client-request-id: true",
        "X-AnchorMailbox: ". get_user_email()
    );
    $outlookApiUrl = $_SESSION["api_url"] . "/Users('$userID')/Messages('$mailID')/Attachments";
    $response = runCurl($outlookApiUrl, null, $headers);
    $response = explode("\n", trim($response));
    $response = $response[count($response) - 1];
    $response = json_decode($response, true);
    $file_links = "";
    foreach ($response["value"] as $attachment) {
        $to_file = $folder . "/" . md5($attachment["ContentId"]) . "-" . $attachment["Name"];
        file_put_contents($to_file, base64_decode($attachment["ContentBytes"]));
        if($file_links != "") {
            $file_links = $file_links . " ||| ";
        }
        $file_links .= "<a href='$to_file' target='_blank'>" . $attachment["Name"] . "</a>";
    }
    echo $file_links . "<br/><br/>";
    echo "<pre>"; print_r($response); echo "</pre>";
}

function list_email() {
    $headers = array(
        "User-Agent: php-tutorial/1.0",
        "Authorization: Bearer ".token()->access_token,
        "Accept: application/json",
        "client-request-id: ".makeGuid(),
        "return-client-request-id: true",
        "X-AnchorMailbox: ". get_user_email()
    );
    $top = 2;
    $skip = isset($_GET["skip"]) ? intval($_GET["skip"]) : 0;
    $search = array (
        // Only return selected fields
        "\$select" => "Subject,ReceivedDateTime,Sender,From,ToRecipients,HasAttachments,BodyPreview",
        // Sort by ReceivedDateTime, newest first
        "\$orderby" => "ReceivedDateTime DESC",
        // Return at most n results
        "\$top" => $top, "\$skip" => $skip
    );
    $outlookApiUrl = $_SESSION["api_url"] . "/Me/MailFolders/Inbox/Messages?" . http_build_query($search);
    $response = runCurl($outlookApiUrl, null, $headers);
    $response = explode("\n", trim($response));
    $response = $response[count($response) - 1];
    $response = json_decode($response, true);
    //echo "<pre>"; print_r($response); echo "</pre>";
    if(isset($response["value"]) && count($response["value"]) > 0) {
        echo "<style type='text/css'>td{border: 2px solid #cccccc;padding: 30px;text-align: center;vertical-align: top;}</style>";
        echo "<table style='width: 100%;'><tr><th>From</th><th>Subject</th><th>Preview</th></tr>";
        foreach ($response["value"] as $mail) {
            $BodyPreview = str_replace("\n", "<br/>", $mail["BodyPreview"]);
            echo "<tr>";
            echo "<td>".$mail["From"]["EmailAddress"]["Address"].
                "<br/><a target='_blank' href='?view_email=".$mail["Id"]."'>View Email</a>";
            if($mail["HasAttachments"] == 1) {
                echo "<br/><a target='_blank' href='?view_attachments=".$mail["Id"]."'>View Attachments</a>";
            }
            echo "</td><td>".$mail["Subject"]."</td>";
            echo "<td>".$BodyPreview."</td>";
            echo "</tr>";
        }
        echo "</table>";
    }
    else {
        echo "<div><h3><i>No email found</i></h3></div>";
    }
    $prevLink = "";
    if($skip > 0) {
        $prev = $skip - $top;
        $prevLink = "<a href='?list_email=true&skip=".$prev."'>Previous Page</a>";
    }
    if(isset($response["@odata.nextLink"])) {
        if($prevLink != "") {
            $prevLink .= " ||| ";
        }
        echo "<br/>".$prevLink."<a href='?list_email=true&skip=".($skip + $top)."'>Next Page</a>";
    }
    else {
        echo "<br/>" . $prevLink;
    }
}

function refresh_token() {
    $token_request_data = array (
        "grant_type" => "refresh_token",
        "refresh_token" => token()->refresh_token,
        "redirect_uri" => $_SESSION["redirect_uri"],
        "scope" => implode(" ", $_SESSION["scopes"]),
        "client_id" => $_SESSION["client_id"],
        "client_secret" => $_SESSION["client_secret"]
    );
    $body = http_build_query($token_request_data);
    $response = runCurl($_SESSION["authority"].$_SESSION["token_url"], $body);
    $response = json_decode($response);
    store_token($response);
    file_put_contents("office_access_token.txt", $response->access_token);
    header("Location: " . $_SESSION["redirect_uri"]);
}

function get_user_id() {
    if(isset($_SESSION["user_id"]) && strlen($_SESSION["user_id"]) > 0) {
        return $_SESSION["user_id"];
    }
    view_profile(true);
    $response = json_decode(file_get_contents("office_user_data.txt"));
    $_SESSION["user_id"] = $response->Id;
    return $response->Id;
}

function get_user_email() {
    if(isset($_SESSION["user_email"]) && strlen($_SESSION["user_email"]) > 0) {
        return $_SESSION["user_email"];
    }
    view_profile(true);
    $response = json_decode(file_get_contents("office_user_data.txt"));
    $_SESSION["user_email"] = $response->EmailAddress;
    return $response->EmailAddress;
}

function view_profile($skipPrint = false) {
    $headers = array(
        "User-Agent: php-tutorial/1.0",
        "Authorization: Bearer ".token()->access_token,
        "Accept: application/json",
        "client-request-id: ".makeGuid(),
        "return-client-request-id: true"
    );
    $outlookApiUrl = $_SESSION["api_url"] . "/Me";
    $response = runCurl($outlookApiUrl, null, $headers);
    $response = explode("\n", trim($response));
    $response = $response[count($response) - 1];
    file_put_contents("office_user_data.txt", $response);
    $response = json_decode($response);
    $_SESSION["user_id"] = $response->Id;
    $_SESSION["mail_id"] = $response->MailboxGuid;
    $_SESSION["user_email"] = $response->EmailAddress;
    if(!$skipPrint) {
        echo "<pre>"; print_r($response); echo "</pre>";
    }
}

function makeGuid(){
    if (function_exists('com_create_guid')) {
        error_log("Using 'com_create_guid'.");
        return strtolower(trim(com_create_guid(), '{}'));
    }
    else {
        $charid = strtolower(md5(uniqid(rand(), true)));
        $hyphen = chr(45);
        $uuid = substr($charid, 0, 8).$hyphen
            .substr($charid, 8, 4).$hyphen
            .substr($charid, 12, 4).$hyphen
            .substr($charid, 16, 4).$hyphen
            .substr($charid, 20, 12);
        return $uuid;
    }
}

function flush_token() {
    file_put_contents("office_auth_config.txt", "");
    $_SESSION["user_id"] = "";
    $_SESSION["mail_id"] = "";
}

function store_token($o) {
    file_put_contents("office_auth_config.txt", json_encode($o));
}

function token() {
    $text = file_exists("office_auth_config.txt") ? file_get_contents("office_auth_config.txt") : null;
    if($text != null && strlen($text) > 0) {
        return json_decode($text);
    }
    return null;
}

function init() {
    $_SESSION["client_id"] = "da8a54d8-86b5-xxxx-xxxx-e31efa3f3d59";
    $_SESSION["client_secret"] = "pYJAxxxxxxxxxxxxxxxX3vzhfp";
    $_SESSION["redirect_uri"] = "http://localhost/tappi/office.php";
    $_SESSION["authority"] = "https://login.microsoftonline.com";
    $_SESSION["scopes"] = array("offline_access", "openid");
    /* If you need to read email, then need to add following scope */
    if(true) {
        array_push($_SESSION["scopes"], "https://outlook.office.com/mail.read");
    }
    /* If you need to send email, then need to add following scope */
    if(true) {
        array_push($_SESSION["scopes"], "https://outlook.office.com/mail.send");
    }

    $_SESSION["auth_url"] = "/common/oauth2/v2.0/authorize";
    $_SESSION["auth_url"] .= "?client_id=".$_SESSION["client_id"];
    $_SESSION["auth_url"] .= "&redirect_uri=".$_SESSION["redirect_uri"];
    $_SESSION["auth_url"] .= "&response_type=code&scope=".implode(" ", $_SESSION["scopes"]);

    $_SESSION["token_url"] = "/common/oauth2/v2.0/token";

    $_SESSION["api_url"] = "https://outlook.office.com/api/v2.0";
}

function runCurl($url, $post = null, $headers = null) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, $post == null ? 0 : 1);
    if($post != null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
    }
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    if($headers != null) {
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    }
    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    if($http_code >= 400) {
        echo "Error executing request to Office365 api with error code=$http_code<br/><br/>\n\n";
        echo "<pre>"; print_r($response); echo "</pre>";
        die();
    }
    return $response;
}
?>

Monday, November 21, 2016

Java read email from google using oauth2 and parse email

Read Email From Google Account


package com.google_api;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by pritom on 21/11/2016.
 */
public class JavaReadEmail extends JavaRawEmailParser {
    public static void main(String[] args) throws Exception {
        String accessToken = getAccessToken();
        String userID = "118224582562607576118"; /* From google profile */
        String messageID = "158855e85a035ed1";
        String url = "https://www.googleapis.com/gmail/v1/users/";
        url += userID + "/messages/" + messageID + "?format=raw";
        url += "&access_token=" + accessToken;

        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        connection.setRequestMethod("GET");
        connection.setRequestProperty("Content-Type", "application/json");

        int httpCode = connection.getResponseCode();
        String responseMessage = connection.getResponseMessage(), httpResponse = "";
        InputStream is = null;
        if (httpCode >= 200 && httpCode <= 299) {
            is = connection.getInputStream();
        }
        else {
            is = connection.getErrorStream();
        }

        Writer writer5 = new StringWriter();
        char[] buffer = new char[1024];
        Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        int n;
        while ((n = reader.read(buffer)) != -1) {
            writer5.write(buffer, 0, n);
        }
        httpResponse = writer5.toString();
        println(httpResponse);

        String snippet = httpResponse.substring(httpResponse.indexOf("\"snippet\":") + 12);
        snippet = snippet.substring(0, snippet.indexOf("\n") - 2).trim();
        println("Snippet=" + snippet);

        String raw = httpResponse.substring(httpResponse.indexOf("\"raw\":") + 8);
        raw = raw.substring(0, raw.indexOf("\n") - 2).trim();

        parse(raw);
    }

    private static String getAccessToken() throws Exception {
        return "return access token from google";
    }
}

Parse Email Received From Google Account


package com.google_api;

import javax.mail.*;
import javax.mail.internet.MimeMessage;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.util.*;

/**
 * Created by pritom on 20/11/2016.
 */
public class JavaRawEmailParser {
    private static final String ENCODING = "UTF-8";

    public static void parse(String rawEmail) throws Exception {
        rawEmail = Base64Decoder.decodeBase64(rawEmail);
        Session s = Session.getDefaultInstance(new Properties());
        InputStream is = new ByteArrayInputStream(rawEmail.getBytes(ENCODING));
        MimeMessage mimeMessage = new MimeMessage(s, is);
        Enumeration enumeration = mimeMessage.getAllHeaders();
        while (enumeration.hasMoreElements()) {
            Header header = (Header) enumeration.nextElement();
            if (!header.getName().contains("Received")) {
                println(header.getName() + " == " + toSingleLine(header.getValue()));
            }
        }
        Map output = processMultipart((Multipart) mimeMessage.getContent());
        for (Object key : output.keySet().toArray()) {
            println("Key=<<" + key + ">> == " + output.get(key));
        }
    }

    private static Map processMultipart(Multipart multipart) throws Exception {
        Map output = new HashMap();
        output.put("html", "");
        output.put("text", "");
        List attachments = new ArrayList();

        for(int i = 0; i < multipart.getCount(); i++) {
            Map result = processBodyPart(multipart.getBodyPart(i));
            if (result != null) {
                if (result.containsKey("type")) {
                    if (result.get("type").toString().equalsIgnoreCase("html")) {
                        output.put("html", result.get("content").toString());
                    }
                    else if (result.get("type").toString().equalsIgnoreCase("text")) {
                        output.put("text", result.get("content").toString());
                    }
                    else if (result.get("type").toString().equalsIgnoreCase("attachment")) {
                        attachments.add(result);
                    }
                }
                if (result.containsKey("html")) {
                    output.put("html", result.get("html").toString());
                }
                if (result.containsKey("text")) {
                    output.put("text", result.get("text").toString());
                }
                if (result.containsKey("attachments")) {
                    List thisAttachments = (List) result.get("attachments");
                    for (int i2 = 0; i2 < thisAttachments.size(); i2++) {
                        attachments.add(thisAttachments.get(i2));
                    }
                }
            }
        }
        output.put("attachments", attachments);

        return output;
    }

    private static Map processBodyPart(BodyPart bodyPart) throws Exception {
        if(bodyPart.isMimeType("text/html") && bodyPart.getFileName() == null) {
            Map data = new HashMap();
            data.put("type", "html");
            data.put("content", bodyPart.getContent().toString());
            return data;
        }
        else if(bodyPart.isMimeType("text/plain") && bodyPart.getFileName() == null) {
            Map data = new HashMap();
            data.put("type", "text");
            data.put("content", bodyPart.getContent().toString());
            return data;
        }
        else if(Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()) && bodyPart.getFileName() != null) {
            Map map = new HashMap();
            map.put("type", "attachment");
            map.put("fileName", bodyPart.getFileName());
            map.put("fileType", bodyPart.getContentType().substring(0, bodyPart.getContentType().indexOf(";")));
            map.put("mimeBodyPart", bodyPart);
            return map;
        }
        else if(bodyPart.getContentType().contains("multipart")) {
            Map o = processMultipart((Multipart) bodyPart.getContent());
            return o;
        }
        return null;
    }

    private static String toSingleLine(String str) throws Exception {
        return str.replaceAll("\\s+", " ");
    }

    private static void writeToFile(String location, String content) throws Exception {
        BufferedWriter out = new BufferedWriter(new FileWriter(location));
        out.write(content);
        out.close();
    }

    protected static void println(Object o) {
        System.out.println("" + o);
    }
}

Decode Util Class


package com.google_api;

/**
 * Created by pritom on 20/11/2016.
 */
public class Base64Decoder {
    private static final String ENCODING = "UTF-8";
    private static final byte[] CHUNK_SEPARATOR = new byte[]{(byte)13, (byte)10};
    private static final byte[] DECODE_TABLE = new byte[]{
            (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1,
            (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1,
            (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1,
            (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1,
            (byte)-1, (byte)-1, (byte)-1, (byte)62, (byte)-1, (byte)62, (byte)-1, (byte)63, (byte)52, (byte)53,
            (byte)54, (byte)55, (byte)56, (byte)57, (byte)58, (byte)59, (byte)60, (byte)61, (byte)-1, (byte)-1,
            (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)-1, (byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5,
            (byte)6, (byte)7, (byte)8, (byte)9, (byte)10, (byte)11, (byte)12, (byte)13, (byte)14, (byte)15, (byte)16,
            (byte)17, (byte)18, (byte)19, (byte)20, (byte)21, (byte)22, (byte)23, (byte)24, (byte)25, (byte)-1,
            (byte)-1, (byte)-1, (byte)-1, (byte)63, (byte)-1, (byte)26, (byte)27, (byte)28, (byte)29, (byte)30,
            (byte)31, (byte)32, (byte)33, (byte)34, (byte)35, (byte)36, (byte)37, (byte)38, (byte)39, (byte)40,
            (byte)41, (byte)42, (byte)43, (byte)44, (byte)45, (byte)46, (byte)47, (byte)48, (byte)49, (byte)50, (byte)51};
    private final byte[] decodeTable;
    private final int decodeSize;
    private int bitWorkArea;
    private byte[] buffer;
    private int pos;
    private int readPos;
    private boolean eof;
    private int modulus;

    public static String decodeBase64(String raw) throws Exception {
        return new String(new Base64Decoder(0, CHUNK_SEPARATOR).decode(raw), ENCODING);
    }

    private Base64Decoder(int lineLength, byte[] lineSeparator) throws Exception {
        super();
        this.decodeTable = DECODE_TABLE;
        int encodeSize;
        if(lineSeparator != null) {
            if(this.containsAlphabetOrPad(lineSeparator)) {
                String sep = newStringUtf8(lineSeparator);
                throw new Exception("lineSeparator must not contain base64 characters: [" + sep + "]");
            }

            if(lineLength > 0) {
                encodeSize = 4 + lineSeparator.length;
                System.arraycopy(lineSeparator, 0, new byte[lineSeparator.length], 0, lineSeparator.length);
            } else {
                encodeSize = 4;
            }
        } else {
            encodeSize = 4;
        }

        this.decodeSize = encodeSize - 1;
    }

    private void decode(byte[] in, int inPos, int inAvail) {
        if(!this.eof) {
            if(inAvail < 0) {
                this.eof = true;
            }

            for(int i = 0; i < inAvail; ++i) {
                this.ensureBufferSize(this.decodeSize);
                byte b = in[inPos++];
                if(b == 61) {
                    this.eof = true;
                    break;
                }

                if(b >= 0 && b < DECODE_TABLE.length) {
                    byte result = DECODE_TABLE[b];
                    if(result >= 0) {
                        this.modulus = (this.modulus + 1) % 4;
                        this.bitWorkArea = (this.bitWorkArea << 6) + result;
                        if(this.modulus == 0) {
                            this.buffer[this.pos++] = (byte)(this.bitWorkArea >> 16 & 255);
                            this.buffer[this.pos++] = (byte)(this.bitWorkArea >> 8 & 255);
                            this.buffer[this.pos++] = (byte)(this.bitWorkArea & 255);
                        }
                    }
                }
            }

            if(this.eof && this.modulus != 0) {
                this.ensureBufferSize(this.decodeSize);
                switch(this.modulus) {
                    case 2:
                        this.bitWorkArea >>= 4;
                        this.buffer[this.pos++] = (byte)(this.bitWorkArea & 255);
                        break;
                    case 3:
                        this.bitWorkArea >>= 2;
                        this.buffer[this.pos++] = (byte)(this.bitWorkArea >> 8 & 255);
                        this.buffer[this.pos++] = (byte)(this.bitWorkArea & 255);
                }
            }

        }
    }

    private boolean isInAlphabet(byte octet) {
        return octet >= 0 && octet < this.decodeTable.length && this.decodeTable[octet] != -1;
    }

    private int available() {
        return this.buffer != null ? this.pos - this.readPos : 0;
    }

    private int getDefaultBufferSize() {
        return 8192;
    }

    private void resizeBuffer() {
        if(this.buffer == null) {
            this.buffer = new byte[this.getDefaultBufferSize()];
            this.pos = 0;
            this.readPos = 0;
        }
        else {
            byte[] b = new byte[this.buffer.length * 2];
            System.arraycopy(this.buffer, 0, b, 0, this.buffer.length);
            this.buffer = b;
        }
    }

    private void ensureBufferSize(int size) {
        if(this.buffer == null || this.buffer.length < this.pos + size) {
            this.resizeBuffer();
        }

    }

    private int readResults(byte[] b, int bPos, int bAvail) {
        if(this.buffer != null) {
            int len = Math.min(this.available(), bAvail);
            System.arraycopy(this.buffer, this.readPos, b, bPos, len);
            this.readPos += len;
            if(this.readPos >= this.pos) {
                this.buffer = null;
            }
            return len;
        }
        else {
            return this.eof ? -1 : 0;
        }
    }

    private void reset() {
        this.buffer = null;
        this.pos = 0;
        this.readPos = 0;
        this.modulus = 0;
        this.eof = false;
    }

    private byte[] decode(String pArray) throws Exception {
        return this.decode(getBytesUtf8(pArray));
    }

    private byte[] decode(byte[] pArray) {
        this.reset();
        if(pArray != null && pArray.length != 0) {
            this.decode(pArray, 0, pArray.length);
            this.decode(pArray, 0, -1);
            byte[] result = new byte[this.pos];
            this.readResults(result, 0, result.length);
            return result;
        } else {
            return pArray;
        }
    }

    private boolean containsAlphabetOrPad(byte[] arrayOctet) {
        if(arrayOctet == null) {
            return false;
        }
        else {
            for (byte element : arrayOctet) {
                if (61 == element || this.isInAlphabet(element)) {
                    return true;
                }
            }
            return false;
        }
    }

    private static byte[] getBytesUtf8(String string) throws Exception {
        return getBytesUnchecked(string, "UTF-8");
    }

    private static byte[] getBytesUnchecked(String string, String charsetName) throws Exception {
        return string.getBytes(charsetName);
    }

    private static String newString(byte[] bytes, String charsetName) throws Exception {
        return new String(bytes, charsetName);
    }

    private static String newStringUtf8(byte[] bytes) throws Exception {
        return newString(bytes, "UTF-8");
    }
}

Output would be as like if your user id and message id is correct:

Snippet=Hello bro how are you?Some italic mode text
Return-Path == xxx@gmail.com
From == xxx@gmail.com
Reply-To == "Reply To" <some_reply_address@gmails.com>
MIME-Version == 1.0
Date == Mon, 21 Nov 2016 00:31:53 -0500
Subject == Test email on: 21/11/2016 06:31:44
To == "To Address" <xxx@xxx.com>
Content-Type == multipart/mixed; boundary="5258f110dfc605186344f1668864cea5"
Message-Id == <CAD-od7dd=JedEjLxQPLLTMwJ93ZSpWdwZHsWD_eL-Jr1M=iWWA@mail.gmail.com>
Key=<<attachments>> == [
	{fileName=My-pdf.pdf, mimeBodyPart=javax.mail.internet.MimeBodyPart@490ab905, type=attachment, fileType=application/pdf}, 
	{fileName=My-image.png, mimeBodyPart=javax.mail.internet.MimeBodyPart@56ac3a89, type=attachment, fileType=image/png}
]
Key=<<html>> == <b>Hello bro how are you?</b><i style='color:blue;'>Some italic mode text</i>
Key=<<text>> ==