Gmail Service in Go (Golang) using OAuth2

Abinav Ghimire
readytowork, Inc.
Published in
5 min readApr 5, 2023

The necessity to design an email-sending service will come up for every developer at some point. This article will help you to create a secure email-sending service in Go using OAuth2 and Gmail API. Let us proceed step by step.

Email with Golang

Creating a project and OAuth2 tokens

A project in Google Developer Console (Google Cloud Platform) with the Gmail API enabled and an OAuth authentication token is necessary to send emails using the Gmail API with OAuth2. You can use your existing Google project if you have one.
To create a new project, go to google cloud console via this link. On this page, click on Select a project in the top left side.

Select a project

After clicking, a new model will pop up which will have a New Project button that will take you to the project creation page where you will need to fill in the required information for the project.

Create a new project page

After creating the project, select the newly created project from the Select a Project dropdown and go to Enabled APIs and Services from the navigation bar on the left side.

Navigation bar

On the page, click on +Enable APIs and Services and search for Gmail API, select the first result that appears, and click on Enable to enable that service in your project.

Enable Gmail API service

We have enabled the Gmail API service in our project, now we need OAuth tokens to use this service. To create those tokens, we need OAuth secret keys, we will create these OAuth secret keys by navigating to the Enabled APIs and Services page as we discussed above. On the same page, we can find an OAuth consent screen option where you will need to fill in the Application Name field and hit Save.

OAuth Consent Screen

Now we will navigate to the credentials page and click on the OAuth Client Id option in the dropdown that appears after clicking on the +Create Credentials. On the credentials creation page, choose the Web Application option under the Application type, and in the Authorized redirect URIs section, add https://developers.google.com/oauthplayground and hit Create. After hitting the Create button, you will be able to see your Client ID and Client Secret key. This step is important since these secret keys will enable authorizations from the set URIs.

Create OAuthClientIds

Finally, we will be creating access and refresh tokens that will be required during our Email-service configuration in Go. To create these tokens, go to the URI link that you set in the above section, click on the settings icon on the top right, and click on the Use your own OAuth credentials checkbox. Two new fields will appear where you will need to enter the Client Id and the Client Secret key that you created above. Now, in the left side box, under Step 1, find the Gmail API v1 service and under that service, select all services and click on the Authorize APIs button. Complete the prompts that will appear and you will be redirected to the same screen.

Now in Step 2, click on the Exchange authorization code for tokens and you will be provided with the refresh and access tokens.

Golang Implementation

In our Go application, we need to initialize the Gmail Service in order to use the service when required. To initialize the service, use the code snippet below and make sure to use the OAuth credentials and generated tokens that we previously created.

func NewGmailService(logger Logger, env Env) *gmail.Service {
ctx := context.Background()

config := oauth2.Config{
ClientID: "your_client_id",
ClientSecret: "your_client_secret",
Endpoint: google.Endpoint,
RedirectURL: "http://localhost",
Scopes: []string{"https://www.googleapis.com/auth/gmail.send"},
}
token := oauth2.Token{
AccessToken: "your_access_token",
RefreshToken: "your_refresh_token",
TokenType: "Bearer",
Expiry: time.Now(),
}
var tokenSource = config.TokenSource(ctx, &token)
srv, err := gmail.NewService(ctx, option.WithTokenSource(tokenSource))
if err != nil {
logger.Zap.Fatal("failed to receive gmail client", err.Error())
}
return srv

}

Now, we will use this Gmail service to create a function that can send emails.

import (
"encoding/base64"
"google.golang.org/api/gmail/v1"
)

type GmailService struct {
gmailService *gmail.Service
}

type GmailServiceBody struct{
to string
message *string
SubjectData string
}

func NewGmailService(gmailService *gmail.Service) GmailService {
return GmailService{
gmailService: gmailService,
}
}

func (g GmailService) SendEmail(params GmailServiceBody) (bool, error) {
to := params.To
var msgString string
emailTo := "To: " + to + "\r\n"
msgString = emailTo
subject := "Subject: " + params.SubjectData + "\n"
msgString = msgString + subject
msgString = msgString + "\n" + params.message
var msg []byte
msg = []byte(msgString)

//Stores the entire message
message := gmail.Message{
Raw: base64.URLEncoding.EncodeToString([]byte(msg)),
}

//"me" sets the sender email address, email that was used to create the crendentials
_, err = g.gmailService.Users.Messages.Send("me", &message).Do()
if err != nil {
return false, err
}
return true, nil
}

The above-created function can be used anywhere in your code to send emails. In this way, Gmail service can be implemented in your Go application.
Happy Coding!!

--

--