• About Morris Development
  • A Focus for Cloud Efficiency
    • Microsoft Azure
    • Amazon Web Services
  • What our Clients Say
  • Our Products
    • PreschoolDB
    • WebinarDB
  • Contact Us

Morris Development

Custom System Development and Integration

April 22, 2020

Sending Email with a Google Service Account

Sending from a service account isn’t as easy as you’d think. There are a lot of parts to it and configuration issues on the google site of things. I’m going to document the code part, assuming you have a service account with the proper permissions already. Here are the steps:

  1. Set up a service account with permission to send email across the domain.
  2. Configure a ServiceAccountCredential, not a GoogleCredential. They’re different.
  3. Configure the service account credential to impersonate the sender. You have to do this during the creation, as you cannot set the sender address after the credential is set up.
  4. Initialize a new GmailService using the credential you created and the ApplicationName (this is what is in your api settings on google admim)
  5. Create an email using AE.Net.Mail.MailMessage.  (you can do it raw, but seriously…. it’s a super pain in the butt if you start getting complex. Use the plugin)
  6. Convert the AE.Net.Mail.MailMessage to a Google.Apis.Gmail.v1.Data.Message
  7. Send the message, including the sender’s account as a parameter. 

Prepare your Service Account

The first step is to get the private key. If you go to your cloud API management page, you should be able to download the credentials in JSON format. It should look like this:

{
  "type": "service_account",
  "project_id": "myproject-123456",
  "private_key_id": "1005769f7xxxxxxxxxxxxxc7",
  "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEuwIBADA7d85lMp7VG+NgGkPGqCI5lwyxxxxxxxxxxxxYOUR_PRIVATE_KEYxxxxxxxxxxxxxxxxxxxxaSpwY1wXB\nzgHY67TpZevWfBV8RnnX\n-----END PRIVATE KEY-----\n",
  "client_email": "the.email.of@your.gserviceaccount.com",
  "client_id": "1234_your_app_client_id_567",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/the_service_name%40the.email.of@your.gserviceaccount.com"
}

You don’t need the entire thing to set up service creds. You just need the Private Key and your service account email

/* 
note: the string impersonate is the FROM address. You intend to send an email from this 
           person and have it appear in their Sent box.  You are impersonating them and 
           they HAVE TO BE included in the credentials when you make them
*/
private ServiceAccountCredential googleCred(string impersonate) {

   ServiceAccountCredential cred = new ServiceAccountCredential( new ServiceAccountCredential.Initializer("your.service@email.iam.gserviceaccount.com") {
             User = impersonate, Scopes = new[] { GmailService.Scope.MailGoogleCom } }
             .FromPrivateKey("-----BEGIN PRIVATE KEY-----\nMIIXXXX_YOUR__PRIVATE_KEY__XXXXX\n-----END PRIVATE KEY-----\n")); 

   return cred
}

/*
If you have issues with permissions, take a look at your api privileges here.  They move the link around, so I can't promise this link is accurate
https://admin.google.com/[enter your domain here]/AdminHome?chromeless=1#OGX:ManageOauthClients 
*/

Creating an Email in the Proper Format

You’d think this is simple, but Google does not accept Microsoft’s standard format. Luckily, there is AE.Net.Mail. That’s a nice plugin that can be converted directly to a Google Mail Object. Here is a basic email being set up:

Now that you have the AE Message created, you need to convert it to a Google Message.

// this function converts our AE.Mail message to the format gmail uses.     
 public static Message createGmailMessage(AE.Net.Mail.MailMessage mailMessage)
        {
            var messageString = new StringWriter();
            mailMessage.Save(messageString);
            Message gmailMessage = new Message();
            gmailMessage.Raw = Base64UrlEncode(messageString.ToString());
            return gmailMessage;
        }

// this function will make the base64 safe for url by doing some find-replaces
        private static string Base64UrlEncode(string input)
        {
            var inputBytes = System.Text.Encoding.UTF8.GetBytes(input);
            // Special "url-safe" base64 encode.
            return Convert.ToBase64String(inputBytes)
              .Replace('+', '-')
              .Replace('/', '_')
              .Replace("=", "");
        }

Sending the Message

Once you’ve got the message all set up, you need to activate Google and send it!

  public string  SendEmail(Message gmail, string fromAddress)
        {
            
            var credential = this.googleCred(fromAddress);

            var service = new GmailService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = "theNameOfYourApplication",
            }); 

            try
            {
                var retval = service.Users.Messages.Send(gmail, fromAddress).Execute();
                return retval.Id;
            }
            catch (Exception e)
            {
                Debug.Print("An error occurred: " + e.Message);
                return e.Message;
            }

        }

Notes: I used to following usings:

using Google.Apis.Gmail.v1;
using Google.Apis.Gmail.v1.Data;
using AE.Net.Mail;

Article by MacGyver / Angular 2, ASP.net, C#, WebApi

About MacGyver

I've worked with database systems for over 20 years, and started my own company in 2000. Almost all my business consists of internal database systems, either ERP or CRM. My programming is primarily in Angular / Microsoft C# and MS SQL.

About This Site

Morris Development has been specializing in internal database system design and integration since 1999. We provide long-term management and support of secure data systems for many businesses as well as developing the more complex code structures for ERP systems like Intellievent, Apidas, and AVMS.

This site is primarily for our developers to keep track up various technologies and updates that are used by Morris Development.

Training

Integrating Angular Microsite with .Net

Private Data Caching with Google Storage

Continuous Deployment for Production Releases?

Azure Websites – the perfect Angular host

Angular 2

  • Angular 2 Authentication
  • Angular Command Line Interface
  • Material Design for Angular
  • Using Observables in Angular 2

Mentors

  • Ben Nadel
  • Dan Wahlin
  • Deborah Kurata
  • John Papa

Staff

  • Dan Morris

Training

  • Google Development Courses
  • Microsoft Virtual Academy
  • PluralSight
  • Test Deep Links

© 2025 · Morris Development