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>> == 

Php send email using google 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 send mail using google & php using google oauth


<?php
session_start();
init();

if(isset($_POST["send"])) {
    sendEmail();
}
else {
?>
<form method="post" enctype="multipart/form-data" accept-charset="ISO-8859-1">
    <table style="width: 1000px;">
        <tr>
            <td style="width: 150px;">To</td>
            <td style="width: 850px;"><input type="text" name="to" required value="" style="width: 100%;"/></td>
        </tr>
        <tr>
            <td>Subject</td>
            <td><input type="text" name="subject" required value="Some sample subject on <?php echo date("d/m/Y H:i:s"); ?>" style="width: 100%;"/></td>
        </tr>
        <tr>
            <td>Files</td>
            <td>
                <input type="file" name="files[]"/>
                <input type="file" name="files[]"/>
                <input type="file" name="files[]"/>
                <input type="file" name="files[]"/>
                <input type="file" name="files[]"/>
                <input type="file" name="files[]"/>
            </td>
        </tr>
        <tr>
            <td style="vertical-align: top;">Message</td>
            <td><textarea name="message" required style="width: 100%; height: 600px;"></textarea></td>
        </tr>
        <tr>
            <td></td>
            <td><input type="submit" name="send" value="Send"/></td>
        </tr>
    </table>
</form>
<?php
}

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

    /* Permissions need to send email */
    $_SESSION["scope"] = "https://www.googleapis.com/auth/userinfo.profile"; /* User profile */
    $_SESSION["scope"] .= " https://www.googleapis.com/auth/gmail.send"; /* Send email */
}

function sendEmail() {
    $to = trim($_POST["to"]);
    if (strlen($to) == 0) {
        die("Need email address to send email");
    }

    $cc = "";
    $bcc = "";
    $nl = "\r\n";
    $boundary = md5(date('r', time()));

    $html = trim(utf8_encode($_POST["message"]));

    $attachment_body = "";
    for($i = 0; $i < 6; $i++) {
        if(strlen(trim($_FILES["files"]["name"][$i])) > 0) {
            $content = file_get_contents($_FILES["files"]["tmp_name"][$i]);
            $content = base64_encode($content);
            $this_attachment = "--".$boundary.$nl."Content-Type: ".$_FILES["files"]["type"][$i].$nl;
            $this_attachment .= "Content-Transfer-Encoding: base64$nl";
            $this_attachment .= "Content-Disposition: attachment; filename=\"".$_FILES["files"]["name"][$i]."\"$nl$nl";
            $this_attachment .= $content;

            $attachment_body .= $this_attachment.$nl;
        }
    }

    $message = "Return-Path: pritomkucse@gmail.com$nl".
        "From: your_email@gmail.com$nl".
        "Reply-To: \"Reply To\" <some_reply_address@gmails.com>$nl".
        "MIME-Version: 1.0$nl".
        "Date: ".date('d/m/Y H:i:s')."$nl".
        "Subject: Test email on: ".date("d/m/Y H:i:s")."$nl".
        "To: $to$nl".
        //"CC: \"CC Address\" <$cc>$nl".
        //"BCC: \"BCC Address\" <$bcc>$nl".
        "Content-Type: multipart/mixed; boundary=\"$boundary\"$nl$nl".
        "--$boundary$nl".
        "Content-Type: text/html; charset=iso-8859-1".$nl.
        "Content-Transfer-Encoding: 7bit$nl$nl".
        "$html$nl".
        "$attachment_body".
        "--$boundary--";

    echo "<pre>[[";print_r($message);echo "]]</pre>";

    $submit = array();
    $submit["raw"] = encode_content($message);
    $submit = json_encode($submit);

    $headers = array();
    $headers[] = "Content-Type: application/json";
    $headers[] = "Content-Length: " . strlen($submit);

    $apiUrl = "https://www.googleapis.com/gmail/v1/users/";
    $apiUrl .= $_SESSION["google_user_id"]."/messages/send?format=raw";
    $apiUrl .= "&access_token=".$_SESSION["access_token"];

    $result = runCurl($apiUrl, $submit, $headers);
    echo "<pre>"; echo $result; echo "</pre>"; die();
    /*
    $result will print output as below:
    You can get unique Message-ID by read an email from server
    with email id "1588519a5db4ecfe" (as below)

    HTTP/1.1 200 OK
    Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    Pragma: no-cache
    Expires: Mon, 01 Jan 1990 00:00:00 GMT
    Date: Mon, 21 Nov 2016 04:16:40 GMT
    Vary: X-Origin
    Content-Type: application/json; charset=UTF-8
    X-Content-Type-Options: nosniff
    X-Frame-Options: SAMEORIGIN
    X-XSS-Protection: 1; mode=block
    Server: GSE
    Alt-Svc: quic=":443"; ma=2592000; v="36,35,34"
    Accept-Ranges: none
    Vary: Origin,Accept-Encoding
    Transfer-Encoding: chunked

    {
        "id": "1588519a5db4ecfe",
        "threadId": "1588519a5db4ecfe",
        "labelIds": [
            "SENT"
        ]
    }
    */
}

function encode_content($content) {
    $content = base64_encode($content);
    $content = str_replace("+", "-", $content);
    $content = str_replace("/", "_", $content);
    //$content = rawurlencode($content);
    return $content;
}

function runCurl($url, $post = null, $headers = null) {
    $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);
    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();
    }
    return $response;
}
?>

Php parse email body & attachments received from google account by oauth2

Email received from google account using oauth2:


stdClass Object
(
    [id] => 15885340ba6b9ba9
    [threadId] => 15885344ba2b9ba9
    [labelIds] => Array
        (
            [0] => SENT
        )

    [snippet] => Hello bro how are you?Some italic mode text
    [historyId] => 685672
    [internalDate] => 1479703529000
    [payload] => stdClass Object
        (
            [mimeType] => multipart/mixed
            [filename] => 
            [headers] => Array
                (
                    [0] => stdClass Object
                        (
                            [name] => Received
                            [value] => from 48568800665 named unknown by gmailapi.google.com with HTTPREST; Sun, 20 Nov 2016 23:45:29 -0500
                        )

                    [1] => stdClass Object
                        (
                            [name] => Return-Path
                            [value] => pritomkucse@xxx.com
                        )

                    [2] => stdClass Object
                        (
                            [name] => From
                            [value] => xxx.xxx@xxx.com
                        )

                    [3] => stdClass Object
                        (
                            [name] => Reply-To
                            [value] => Reply To <some_reply_address@gmails.com>
                        )

                    [4] => stdClass Object
                        (
                            [name] => MIME-Version
                            [value] => 1.0
                        )

                    [5] => stdClass Object
                        (
                            [name] => Date
                            [value] => Sun, 20 Nov 2016 23:45:29 -0500
                        )

                    [6] => stdClass Object
                        (
                            [name] => Subject
                            [value] => Test email on: 21/11/2016 05:45:23
                        )

                    [7] => stdClass Object
                        (
                            [name] => To
                            [value] => To Address <some_to_address@xxx.com>
                        )

                    [8] => stdClass Object
                        (
                            [name] => CC
                            [value] => CC Address <some_cc_address@xxx.com>
                        )

                    [9] => stdClass Object
                        (
                            [name] => Content-Type
                            [value] => multipart/mixed; boundary="4abf1fca8718965424d6569f69ecf783"
                        )

                    [10] => stdClass Object
                        (
                            [name] => Message-Id
                            [value] => <CAD-od7e+ZAOzrQLU-b4O5ZrLP0x0qEkaYnwNB4gBj60bSbd8DQ@mail.gmail.com>
                        )

                )

            [body] => stdClass Object
                (
                    [size] => 0
                )

            [parts] => Array
                (
                    [0] => stdClass Object
                        (
                            [partId] => 0
                            [mimeType] => text/html
                            [filename] => 
                            [headers] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [name] => Content-Type
                                            [value] => text/html; charset=UTF-8
                                        )

                                    [1] => stdClass Object
                                        (
                                            [name] => Content-Transfer-Encoding
                                            [value] => 7bit
                                        )

                                )

                            [body] => stdClass Object
                                (
                                    [size] => 77
                                    [data] => PGI-SGVsbG8gYnJv.....
                                )

                        )

                    [1] => stdClass Object
                        (
                            [partId] => 1
                            [mimeType] => application/pdf
                            [filename] => My-pdf.pdf
                            [headers] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [name] => Content-Type
                                            [value] => application/pdf; name="My-pdf.pdf"
                                        )

                                    [1] => stdClass Object
                                        (
                                            [name] => Content-Transfer-Encoding
                                            [value] => base64
                                        )

                                    [2] => stdClass Object
                                        (
                                            [name] => Content-Disposition
                                            [value] => attachment; filename="My-pdf.pdf"
                                        )

                                )

                            [body] => stdClass Object
                                (
                                    [attachmentId] => ANGjdJ_iTdTRG38Nwxf8...
                                    [size] => 197132
                                )

                        )

                    [2] => stdClass Object
                        (
                            [partId] => 2
                            [mimeType] => image/png
                            [filename] => My-image.png
                            [headers] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [name] => Content-Type
                                            [value] => image/png; name="My-image.png"
                                        )

                                    [1] => stdClass Object
                                        (
                                            [name] => Content-Transfer-Encoding
                                            [value] => base64
                                        )

                                    [2] => stdClass Object
                                        (
                                            [name] => Content-Disposition
                                            [value] => attachment; filename="My-image.png"
                                        )

                                )

                            [body] => stdClass Object
                                (
                                    [attachmentId] => ANGjdJ9AysXkrs_yEFM0...
                                    [size] => 317154
                                )

                        )

                )

        )

    [sizeEstimate] => 686890
)

Php code to parse email body & attachments:


<?php
function viewEmailById() {
    $id = $_GET["email_by_id"];
    $raw = "";// "format=raw&";
    $fields = "";// "fields=raw&";
    $apiUrl = "https://www.googleapis.com/gmail/v1/users/";
    $apiUrl .= getUserID()."/messages/$id?$raw$fields";
    $apiUrl .= "access_token=".token();
    $result = json_decode(runCurl($apiUrl));

    $message = parseEmail($result->payload->parts);
    if(!file_exists($id)) {
        mkdir($id);
    }
    $link = "";
    foreach($message as $msg) {
        $location = $id."/".$msg["name"];
        $fp = fopen("$location","w");
        fwrite($fp, $msg["body"]);
        fclose($fp);
        $link .= "<a href='".$location."' target='_blank'>".$msg["name"]."</a><br/>";
    }
    echo $link;
}

function parseEmail($email) {
    $id = $_GET["email_by_id"];
    $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;
            $apiUrl = "https://www.googleapis.com/gmail/v1/users/".getUserID();
            $apiUrl .= "/messages/$id/attachments/".$part->body->attachmentId;
            $apiUrl .= "?access_token=".token();
            $remoteFile = json_decode(runCurl($apiUrl));
            $file["body"] = decodeContent($remoteFile->data);
            array_push($result, $file);
        }
        else if($mime === "text/plain") {
            $file = array();
            $file["type"] = "text";
            $file["name"] = "email_body_plain.html";
            $file["body"] = decodeContent($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"] = decodeContent($part->body->data);
            array_push($result, $file);
        }
        else if(substr($mime, 0, 9) === "multipart") {
            foreach(parseEmail($part->parts) as $file) {
                array_push($result, $file);
            }
        }
    }
    return $result;
}

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

function getUserID() {
    $fromSession = valueFromSession("user_id");
    if($fromSession) {
        return $fromSession;
    }
    else {
        $apiUrl = "https://www.googleapis.com/oauth2/v1/userinfo?alt=json";
        $apiUrl .= "&access_token=".token();
        $result = json_decode(runCurl($apiUrl));
        $_SESSION["user_id"] = $result->id;
        return $_SESSION["user_id"];
    }
}

function valueFromSession($name) {
    if(isset($_SESSION[$name])) {
        return $_SESSION[$name];
    }
    return null;
}

function token() {
    return "return your access token from here";
}

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);
    }
    $result = curl_exec($ch);
    $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    $test = json_decode($result);
    if((isset($test->error) && $test->error->code == 401) || $httpcode == 401) {
        if(!valueFromSession("redirected")) {
            $_SESSION["redirected"] = true;
            refreshToken();
            header("Refresh:0");
            die();
        }
        else {
            $_SESSION["redirected"] = null;
            echo "Error getting data from google api, reload page to try again";
            die();
        }
    }
    else {
        $_SESSION["redirected"] = null;
    }
    return $result;
}
?>

Thursday, November 17, 2016

Stylish CSS3 Loader

Example


Html Content

<div class="load-more-option"></div>

CSS Content

<style type="text/css">
    .load-more-option, .load-more-option:before, .load-more-option:after {
        border-radius: 50%;
        width: 2.5em;
        height: 2.5em;
        -webkit-animation-fill-mode: both;
        animation-fill-mode: both;
        -webkit-animation: load_more_options 1.8s infinite ease-in-out;
        animation: load_more_options 1.8s infinite ease-in-out;
    }
    .load-more-option {
        color: #37829e;
        font-size: 10px;
        margin: 80px auto;
        position: relative;
        text-indent: -9999em;
        -webkit-transform: translateZ(0);
        -ms-transform: translateZ(0);
        transform: translateZ(0);
        -webkit-animation-delay: -0.16s;
        animation-delay: -0.16s;
    }
    .load-more-option:before, .load-more-option:after {
        content: '';
        position: absolute;
        top: 0;
    }
    .load-more-option:before {
        left: -3.5em;
        -webkit-animation-delay: -0.32s;
        animation-delay: -0.32s;
    }
    .load-more-option:after {
        left: 3.5em;
    }
    @-webkit-keyframes load_more_options {
        0%,
        80%,
        100% {
            box-shadow: 0 2.5em 0 -1.3em;
        }
        40% {
            box-shadow: 0 2.5em 0 0;
        }
    }
    @keyframes load_more_options {
        0%,
        80%,
        100% {
            box-shadow: 0 2.5em 0 -1.3em;
        }
        40% {
            box-shadow: 0 2.5em 0 0;
        }
    }
</style>


Another Example Given Below



Example



HTML Content

<div class="loader"></div>
<div class="loader2"></div>

CSS Content

.loader {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  border: 4px solid lightgray;
  border-top: 4px solid #3498db;
  border-bottom: 4px solid #3498db;
  animation: spinxxx 2s linear infinite;
  -webkit-animation: spinxxx 2s linear infinite;
}
.loader2{
  width: 80px;
  height: 80px;
  margin: 16px;
  margin-top: -107px;
  margin-left: 20px;
  border-radius: 50%;
  border: 4px solid lightgray;
  border-top: 4px solid #3498db;
  animation: spinxxx2 2s linear infinite;
  -webkit-animation: spinxxx2 2s linear infinite;
}

@-webkit-keyframes spinxxx {
  0% { -webkit-transform: rotate(0deg); }
  100% { -webkit-transform: rotate(360deg); }
}

@keyframes spinxxx {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

@-webkit-keyframes spinxxx2 {
  0% { -webkit-transform: rotate(360deg); }
  100% { -webkit-transform: rotate(0deg); }
}

@keyframes spinxxx2 {
  0% { transform: rotate(360deg); }
  100% { transform: rotate(0deg); }
}




Wednesday, November 16, 2016

Angular-js infinity scroll to load more data on window or other element scrolling


<!DOCTYPE html>
<html>
    <head>
        <title>Infinite scrolling to load more data using angular-js</title>
        <style type="text/css">
            div.scroll-test {
                height: 100%;
                background: #123213;
                color: #fff;
                overflow: auto;
                margin: 0 auto;
                padding: 0.5em;
            }
        </style>
        
        <script src="http://code.angularjs.org/1.2.12/angular.js"></script>
        <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
        
        <script type="text/javascript">
            var app = angular.module("myApp", []);
           
            app.controller("ScrollController", function($scope, $http) {
                $scope.items = ["You have to scroll down to load more items..."];
                $scope.loading = false;
                $scope.counter = 0;
                $scope.rows = 1;
                
                var s = "----------------------------------------------------";
                s += "-------------------------------------------------------";
                s += "-------------------------------------------------------";
                
                $scope.loadMore = function() {
                    if(!$scope.loading) {
                        $scope.loading = true;
                        $http({
                            method: "GET",
                            url: "http://localhost/scroll/data.html?counter=" + ($scope.counter++)
                        }).success(function(data, status, header, config) {
                            $scope.loading = false;
                            data = data.split("\n");
                            for(i = 0; i < data.length - 1; i++) {
                                $scope.items.push(($scope.rows++) + "=" + data[i]);
                            }
                            $scope.items.push(($scope.rows++) + s);
                        });
                    }
                };
                
                var params = {};
                window.location.search.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(str, key, value) {
                    params[key] = decodeURIComponent(value.replace(/\+/g, ' '));
                });
                var type = params.type === undefined ? '' : params.type;
                
                $scope.window = true;
                if(type == 'window') {
                    //Initializing the list
                    $scope.loadMore();
                }
                else if(type == 'div') {
                    $scope.window = false;
                    $("div.scroll-test").height(window.innerHeight - 130);
                    //Initializing the list
                    $scope.loadMore();
                }
                else {
                    $scope.items.push("You have to define 'type' parameter in url & value would be 'window' or 'div' as ?type=window");
                }
            });
            
            app.directive("windowScroll", function ($window) {
                return function(scope, element, attrs) {
                    angular.element($window).bind("scroll", function() {
                        if(scope.window && $window.pageYOffset + $(window).height() + 50 >= $(document).height()) {
                            scope.$apply(attrs.windowScroll);
                        }
                    });
                };
            });
           
            app.directive("divScroll", function() {
                return {    
                    restrict: 'A',
                    link: function(scope, element, attrs) {
                        var raw = element[0];
                        element.bind("scroll", function() {
                            if(!scope.window && raw.scrollTop + raw.offsetHeight + 50 >= raw.scrollHeight) {
                                scope.$apply(attrs.divScroll);
                            }
                        });
                    }
                }
            });
        </script>
    </head>

    <body>
         <div data-ng-app="myApp" data-window-scroll="loadMore()" data-ng-controller="ScrollController">
             <div>
                 <div class="scroll-test" data-div-scroll="loadMore()">
                     <p data-ng-repeat="item in items">
                         {{item}}
                     </p>
                 </div>
                <h1><i>INFINITE SCROLLING IN ANGULAR-JS<span data-ng-show="loading"> (Loading items...)</span></i></h1>              
             </div>       
         </div>
    </body>
</html>

jQuery get params from url

var params = {};
window.location.search.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(str, key, value) {
    params[key] = decodeURIComponent(value.replace(/\+/g, ' '));
});
console.log(params);