Posts Tagged ‘Gmail’

Delete email permanently in Gmail

Friday, September 4th, 2015

If you delete a message from your Inbox or one of your custom folders, it will still appear in [Gmail]/All Mail.

Here’s why: in most folders, deleting a message simply removes that folder’s label from the message, including the label identifying the message as being in your Inbox.

[Gmail]/All Mail shows all of your messages, whether or not they have labels attached to them.

If you want to permanently delete a message from all folders:

  1. Move it to the [Gmail]/Trash folder (or [Gmail]/Bin or national version).
  2. Delete it from the [Gmail]/Trash folder (or [Gmail]/Bin or national version).

All emails in [Gmail]/Spam and [Gmail]/Trash are deleted after 30 days.
If you delete a message from [Gmail]/Spam or [Gmail]/Trash, it will be deleted permanently.

Here’s how this looks like using Mail.dll .NET IMAP component:

// C# version:

using(Imap imap = new Imap())
{
	imap.ConnectSSL("imap.gmail.com");
	imap.UseBestLogin("user@gmail.com", "password");

	// Recognize Trash folder
	List<FolderInfo> folders = imap.GetFolders();
 	CommonFolders common = new CommonFolders(folders);
 	FolderInfo trash = common.Trash;

	// Find all emails we want to delete
	imap.SelectInbox();
	List<long> uids = imap.Search(Expression.Subject("email to delete"));

	// Move email to Trash
	List<long> uidsInTrash = new List<long>();
	foreach (long uid in uids)
	{
		long uidInTrash = (long)imap.MoveByUID(uid, trash);
		uidsInTrash.Add(uidInTrash);
	}

	// Delete moved emails from Trash
	imap.Select(trash);
	foreach (long uid in uidsInTrash)
	{
		imap.DeleteMessageByUID(uid);
	}

	imap.Close();
}
' VB.NET version:

Using imap As New Imap()
	imap.ConnectSSL("imap.gmail.com")
	imap.UseBestLogin("user@gmail.com", "password")

	' Recognize Trash folder
	Dim folders As List(Or FolderInfo) = imap.GetFolders()
	Dim common As CommonFolders = new CommonFolders(folders)
	Dim trash As FolderInfo = common.Trash

	' Find all emails we want to delete
	imap.SelectInbox()
	Dim uids As List(Of Long) = imap.Search(_
		Expression.Subject("email to delete"))

	' Move email to Trash
	Dim uidsInTrash As New List(Of Long)
	For Each uid As Long In uids
		Dim uidInTrash As Long = imap.MoveByUID(uid, trash)
		uidsInTrash.Add(uidInTrash)
	Next

	' Delete moved emails from Trash
	imap.[Select](trash)
	For Each uid As Long In uidsInTrash
		imap.DeleteMessageByUID(uid)
	Next

	imap.Close()
End Using

You can also use bulk methods to handle large amount of emails faster:

// C# version:

using(Imap imap = new Imap())
{
	imap.ConnectSSL("imap.gmail.com");
	imap.UseBestLogin("user@gmail.com", "password");

	// Recognize Trash folder
	List<FolderInfo> folders = imap.GetFolders();
 	CommonFolders common = new CommonFolders(folders);
 	FolderInfo trash = common.Trash;

	// Find all emails we want to delete
	imap.SelectInbox();
	List<long> uids = imap.Search(Expression.Subject("email to delete"));

	// Move emails to Trash
	List<long> uidsInTrash = imap.MoveByUID(uids, trash);

	// Delete moved emails from Trash
	imap.Select(trash);
	imap.DeleteMessageByUID(uidsInTrash);

	imap.Close();
}
' VB.NET version:

Using imap As New Imap()
	imap.ConnectSSL("imap.gmail.com")
	imap.UseBestLogin("user@gmail.com", "password")

	' Recognize Trash folder
	Dim folders As List(Or FolderInfo) = imap.GetFolders()
	Dim common As CommonFolders = new CommonFolders(folders)
	Dim trash As FolderInfo = common.Trash

	' Find all emails we want to delete
	imap.SelectInbox()
	Dim uids As List(Of Long) = imap.Search(Expression.Subject("email to delete"))

	' Move email to Trash
	Dim uidsInTrash As List(Of Long) = imap.MoveByUID(uids, trash)

	' Delete moved emails from Trash
	imap.[Select](trash)
	imap.DeleteMessageByUID(uidsInTrash)

	imap.Close()
End Using

Please also note that there are 2 additional sections in the “Gmail settings”/”Forwarding and POP/IMAP” tab:

“When I mark a message in IMAP as deleted:”

  • Auto-Expunge on – Immediately update the server. (default)
  • Expunge off – Wait for the client to update the server.

“When a message is marked as deleted and expunged from the last visible IMAP folder:”

  • Archive the message (default)
  • Move the message to the Trash
  • Immediately delete the message forever

Those settings change the default behavior of the account and modify DeleteMessage* methods behavior.

Enable IMAP in Gmail

Tuesday, June 2nd, 2015
  1. Sign in to Gmail.
  2. Click the gear icon in the upper-right and select Settings.
  3. Click Forwarding and POP/IMAP.
  4. Select Enable IMAP.
  5. Remember that Gmail only allows secure SSL connections so you need to use ConnectSSL method.

Perfectly secure ‘less’ secure apps

For some (newer) Google accounts you may need to enable access for ‘less’ secure apps (for Google Apps this setting is not available – it’s enabled by default).

Please note that contrary to what the label says those applications (such as Thunderbird or Outlook) are secure – they use TLS or SSL to secure the communication.

The term ‘less secure apps’ is used only because such applications need to store the primary account password to be able to access IMAP.

‘Less’ secure apps alternatives

  1. OAuth 2.0 (OAuth 2.0 for installed applications, OAuth 2.0 for web applications, OAuth 2.0 for service accounts) which works despite the disabled ‘less secure apps’ setting.
  2. Application specific passwords (2-Step-Verification must be enabled to access this feature: Create application specific password)

2-step verification

If you use 2-Step-Verification and are seeing a “password incorrect” error when trying to access IMAP, an app password may solve the problem. An application specific password is a 16-digit password that gives an application permission to access your Google Account.

2-Step-Verification must be enabled to access this feature:
Create application specific password.

Simple .NET IMAP access sample

// C# code:

using(Imap imap = new Imap())
{
	imap.ConnectSSL("imap.gmail.com");
	imap.UseBestLogin("pat@gmail.com", "password");

	imap.SelectInbox();

	List<long> uids = imap.Search(Flag.Unseen);
	foreach (long uid in uids)
	{
		var eml = imap.GetMessageByUID(uid);
		IMail mail = new MailBuilder().CreateFromEml(eml);

		Console.WriteLine(mail.Subject);
		Console.WriteLine(mail.Text);
	}
	imap.Close();
}
' VB.NET code:

Using imap As New Imap()
	imap.ConnectSSL("imap.gmail.com")
	imap.UseBestLogin("pat@gmail.com", "password")

	imap.SelectInbox()

	Dim uids As List(Of Long) = imap.Search(Flag.Unseen)
	For Each uid As Long In uids
		Dim eml = imap.GetMessageByUID(uid)
		Dim mail As IMail = New MailBuilder().CreateFromEml(eml)

		Console.WriteLine(mail.Subject)
		Console.WriteLine(mail.Text)
	Next
	imap.Close()
End Using

More .NET IMAP samples. You can download Mail.dll IMAP library for .NET here.

Enable POP3 in Gmail

Tuesday, June 2nd, 2015
  1. Sign in to Gmail.
  2. Click the gear icon in the upper-right and select Mail settings .
  3. Click Forwarding and POP/IMAP.
  4. Select Enable POP for all mail or Enable POP for mail that arrives from now on. Here you can learn more about Gmail’s POP3 behavior
  5. Remember that Gmail only allows secure SSL connections so you need to use ConnectSSL method.

Perfectly secure ‘less’ secure apps

For some (newer) Google accounts you may need to enable access for ‘less’ secure apps.

Please note that contrary to what the label says those applications (such as Thunderbird or Outlook) are secure – they use TLS or SSL to secure the communication.

The term ‘less secure apps’ is used only because such applications need to store the primary account password to be able to access POP3.

‘Less’ secure apps alternatives

  1. IMAP and OAuth 2.0 (OAuth 2.0 for installed applications, OAuth 2.0 for web applications, OAuth 2.0 for service accounts) which works despite the disabled ‘less secure apps’ setting.
  2. Application specific passwords (2-Step-Verification must be enabled to access this feature: Create application specific password)

2-step verification

If you use 2-Step-Verification and are seeing a “password incorrect” error when trying to access POP3, an app password may solve the problem. An application specific password is a 16-digit password that gives an application permission to access your Google Account.

2-Step-Verification must be enabled to access this feature:
Create application specific password.

Simple .NET POP3 access sample

// C# code:

using(Pop3 pop3 = new Pop3())
{
	pop3.ConnectSSL("pop.gmail.com");
	pop3.Login("your_email@gmail.com", "password");

	foreach (string uid in pop3.GetAll())
	{
		var eml = pop3.GetMessageByUID(uid);
		IMail mail= new MailBuilder()
			.CreateFromEml(eml);

		Console.WriteLine(mail.Subject);
		Console.WriteLine(mail.Text);
	}
	pop3.Close();
}

' VB.NET code:

Using pop3 As New Pop3()
    pop3.ConnectSSL("pop.gmail.com")
    pop3.Login("your_email@gmail.com", "password")

    For Each uid As String In pop3.GetAll()
        Dim email As IMail = New MailBuilder() _
            .CreateFromEml(pop3.GetMessageByUID(uid))
        Console.WriteLine(email.Subject)
	Console.WriteLine(mail.Text)
    Next
    pop3.Close()
End Using

More .NET POP3 samples. You can download Mail.dll POP3 library for .NET here.

OAuth 2.0 with Gmail over IMAP for service account

Thursday, September 11th, 2014

In this article I’ll show how to access Gmail account of any domain user, using OAuth 2.0, .NET IMAP component and service accounts. The basic idea is that domain administrator can use this method to access user email without knowing user’s password.

This scenario is very similar to 2-legged OAuth, which uses OAuth 1.0a. Although it still works, it has been deprecated by Google and OAuth 2.0 service accounts were introduced.

The following describes how to use XOAUTH2 and OAuth 2.0 to achieve the equivalent of 2-legged OAuth.

Google APIs console

First you need to visit the Google Developers Console and create a service account:

console_0

console_1

console_2

Download and save this private key (XYZ.p12), you’ll need that later:

console_3

Go to “Service accounts” and click “View Client ID”:

console_4

Make a note of the Client ID and Email address (Service account).

Google Apps Dashboard

Next step is to authorize access for newly created service account.

Visit your domain administration panel:
https://www.google.com/a/cpanel/yourdomain.com/ManageOauthClients

Then click “Advanced tools”, “Authentication” and “Manage third party OAuth Client access”.

On this screen you can authorize service account to access email scope:

cpanel_1

Use previously remembered Client ID and “https://mail.google.com/”, which is IMAP/SMTP API scope:

Client Name: 1234567890
One or More API Scopes: https://mail.google.com/

Google.Apis

Use Nuget to download “Google.Apis.Auth.Mvc” and “Google.Apis.Auth” packages.

Access IMAP/SMTP server

// C#

using System.Security.Cryptography.X509Certificates;
using System;
using System.Threading;
using Limilabs.Client.IMAP;
using Limilabs.Test.Constants;
using Google.Apis.Auth.OAuth2;
using Limilabs.Client.Authentication.Google;


const string serviceAccountEmail = "name@xxxxxxxxxx.gserviceaccount.com";
const string serviceAccountCertPath = @"c:\XYZ.p12";
const string serviceAccountCertPassword = "notasecret";
const string userEmail = "user@your-domain.com";

X509Certificate2 certificate = new X509Certificate2(
    serviceAccountCertPath, 
    serviceAccountCertPassword, 
    X509KeyStorageFlags.Exportable);

ServiceAccountCredential credential = new ServiceAccountCredential(
    new ServiceAccountCredential.Initializer(serviceAccountEmail)
    {
        Scopes = new[] { GoogleScope.ImapAndSmtp.Name },
        User = userEmail
    }.FromCertificate(certificate));

bool success = credential.RequestAccessTokenAsync(CancellationToken.None).Result;
Assert.IsTrue(success);

using (Imap imap = new Imap())
{
    imap.ConnectSSL("imap.gmail.com");
    imap.LoginOAUTH2(userEmail, credential.Token.AccessToken);

    imap.SelectInbox();

    foreach (long uid in uids)
    {
        var eml = client.GetMessageByUID(uid);
        IMail email = new MailBuilder().CreateFromEml(eml);
        Console.WriteLine(email.Subject);
    }

    imap.Close();
}
' VB.NET

Imports System.Security.Cryptography.X509Certificates
Imports System.Threading
Imports Limilabs.Client.IMAP
Imports Limilabs.Test.Constants
Imports Google.Apis.Auth.OAuth2
Imports Limilabs.Client.Authentication.Google


Const  serviceAccountEmail As String = "name@xxxxxxxxxx.gserviceaccount.com"
Const  serviceAccountCertPath As String = "c:\XYZ.p12"
Const  serviceAccountCertPassword As String = "notasecret"
Const  userEmail As String = "user@your-domain.com"

Dim certificate As New X509Certificate2(serviceAccountCertPath, serviceAccountCertPassword, X509KeyStorageFlags.Exportable)

Dim credential As New ServiceAccountCredential(New ServiceAccountCredential.Initializer(serviceAccountEmail) With { _
	Key .Scopes = New () {GoogleScope.ImapAndSmtp.Name}, _
	Key .User = userEmail _
}.FromCertificate(certificate))

Dim success As Boolean = credential.RequestAccessTokenAsync(CancellationToken.None).Result
Assert.IsTrue(success)

Using imap As New Imap()
	imap.ConnectSSL("imap.gmail.com")
	imap.LoginOAUTH2(userEmail, credential.Token.AccessToken)

	imap.SelectInbox()

	For Each uid As Long In uids
		Dim eml = client.GetMessageByUID(uid)
		Dim email As IMail = New MailBuilder().CreateFromEml(eml)
		Console.WriteLine(email.Subject)
	Next

	imap.Close()
End Using

Gmail SMTP authentication and STARTTLS bug

Wednesday, July 23rd, 2014

Most SMTP servers don’t accept not encrypted connections, or require to secure such connection using explicit SSL.
Usually in such case LOGINDISABLED and STARTTLS are send in response to EHLO command. Some servers send STARTTLS and simply don’t send any AUTH responses.

Recently Gmail started to act differently (and incorrect):

S: 220 mx.google.com ESMTP hc4sm6305585wjc.9 - gsmtp
C: EHLO [192.168.0.11]
S: 250-mx.google.com at your service, [89.67.21.113]
S: 250-SIZE 35882577
S: 250-8BITMIME
S: 250-STARTTLS
S: 250-AUTH LOGIN PLAIN XOAUTH XOAUTH2 PLAIN-CLIENTTOKEN
S: 250-ENHANCEDSTATUSCODES
S: 250 CHUNKING
C: AUTH LOGIN
S: 530 5.7.0 Must issue a STARTTLS command first. hc4sm6305585wjc.9 - gsmtp

Server claims that it accepts LOGIN command:
S: 250-AUTH LOGIN
but when it is send, it claims that you must issue STARTTLS first:
S: 530 5.7.0 Must issue a STARTTLS command first. hc4sm6305585wjc.9 - gsmtp

This doesn’t make much sense and Gmail should not send “250-AUTH LOGIN PLAIN”.