Skip to content

Instantly share code, notes, and snippets.

@mizzy
Created January 28, 2025 23:33
Show Gist options
  • Save mizzy/9c4c1c1c24eb09d4a30b10f6778419cb to your computer and use it in GitHub Desktop.
Save mizzy/9c4c1c1c24eb09d4a30b10f6778419cb to your computer and use it in GitHub Desktop.
Send mails from a service account via Gmail API
package sendMail
import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"cloud.google.com/go/pubsub"
"google.golang.org/api/gmail/v1"
"google.golang.org/api/impersonate"
"google.golang.org/api/option"
)
type Message struct {
ServiceAccount string `json:"service_account"`
UserEmail string `json:"user_email"`
DestinationEmail string `json:"destination_email"`
}
func SendMail(ctx context.Context, m *pubsub.Message) error {
var message Message
json.Unmarshal(m.Data, &message)
ts, err := impersonate.CredentialsTokenSource(ctx, impersonate.CredentialsConfig{
TargetPrincipal: message.ServiceAccount,
Scopes: []string{gmail.GmailSendScope},
Subject: message.UserEmail,
})
if err != nil {
return fmt.Errorf("failed to create impersonated token source: %v", err)
}
srv, err := gmail.NewService(ctx, option.WithTokenSource(ts))
if err != nil {
return fmt.Errorf("unable to create Gmail client: %v", err)
}
from := message.UserEmail
to := message.DestinationEmail
subject := "Test Mail from Gmail API via Impersonated Credentials (Cloud Functions Event Trigger)"
body := "This is a test mail from Gmail API via Impersonated Credentials (Cloud Functions Event Trigger)."
msg := createMessage(from, to, subject, body)
_, err = srv.Users.Messages.Send("me", msg).Do()
if err != nil {
return fmt.Errorf("unable to send message: %v", err)
}
fmt.Println("Email sent successfully.")
return nil
}
func createMessage(from, to, subject, body string) *gmail.Message {
header := make(map[string]string)
header["From"] = from
header["To"] = to
header["Subject"] = subject
header["Content-Type"] = "text/plain; charset=\"UTF-8\""
var msg bytes.Buffer
for k, v := range header {
msg.WriteString(fmt.Sprintf("%s: %s\r\n", k, v))
}
msg.WriteString("\r\n")
msg.WriteString(body)
return &gmail.Message{
Raw: base64.RawURLEncoding.EncodeToString(msg.Bytes()),
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment