I'd like to send a Message using Google's Gmail API. I've authenticated successfully, and am trying to use GmailService to send a message.
I'd like to use this:
myService.Users.Messages.Send(myMessage, "me").Execute();
where myService is a Google.Apis.Gmail.v1.GmailService
and myMessage is a Google.Apis.Gmail.v1.Data.Message
.
myService
is fine, I've done the OAuth dance. I can get messages from my Inbox and all that. But I don't know how to construct myMessage
. I have a standard .NET MailMessage
, with human-readable Subject, Body, To, From etc.
But the Google Message
class takes fields Payload
or Raw
. What's the easiest way to convert a full MailMessage
to a string which I can set to the Payload
or Raw
properties? Or is this not what I should be doing at all?
The documentation for the Message class.
Gmail API is available for free, but it has certain daily usage limits for API calls. Daily usage: 1 billion API calls per day. Per User Rate Limit: 250 API calls per user per second.
I found a solution. Strangely, .NET doesn't seem to support this natively/easily. There's a nice nuget package though, called AE.Net.Mail, which can write an easy-to-create message object to a stream.
Here's the sample code that pointed me in that direction.
Copy-and-pasted code as site seems to be down, and Google's cache might not last forever:
using System.IO;
using System.Net.Mail;
using Google.Apis.Gmail.v1;
using Google.Apis.Gmail.v1.Data;
public class TestEmail {
public void SendIt() {
var msg = new AE.Net.Mail.MailMessage {
Subject = "Your Subject",
Body = "Hello, World, from Gmail API!",
From = new MailAddress("[you]@gmail.com")
};
msg.To.Add(new MailAddress("[email protected]"));
msg.ReplyTo.Add(msg.From); // Bounces without this!!
var msgStr = new StringWriter();
msg.Save(msgStr);
var gmail = new GmailService(Context.GoogleOAuthInitializer);
var result = gmail.Users.Messages.Send(new Message {
Raw = Base64UrlEncode(msgStr.ToString())
}, "me").Execute();
Console.WriteLine("Message ID {0} sent.", result.Id);
}
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("=", "");
}
}
Here is an alternative version using using MimeKit.
public void SendEmail(MyInternalSystemEmailMessage email)
{
var mailMessage = new System.Net.Mail.MailMessage();
mailMessage.From = new System.Net.Mail.MailAddress(email.FromAddress);
mailMessage.To.Add(email.ToRecipients);
mailMessage.ReplyToList.Add(email.FromAddress);
mailMessage.Subject = email.Subject;
mailMessage.Body = email.Body;
mailMessage.IsBodyHtml = email.IsHtml;
foreach (System.Net.Mail.Attachment attachment in email.Attachments)
{
mailMessage.Attachments.Add(attachment);
}
var mimeMessage = MimeKit.MimeMessage.CreateFromMailMessage(mailMessage);
var gmailMessage = new Google.Apis.Gmail.v1.Data.Message {
Raw = Encode(mimeMessage.ToString())
};
Google.Apis.Gmail.v1.UsersResource.MessagesResource.SendRequest request = service.Users.Messages.Send(gmailMessage, ServiceEmail);
request.Execute();
}
public static string Encode(string text)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(text);
return System.Convert.ToBase64String(bytes)
.Replace('+', '-')
.Replace('/', '_')
.Replace("=", "");
}
Note: If you are getting an email bounce issue, it is likely due to not setting the ReplyToList field. See: GMail API Emails Bouncing
C# Code for Gmail API Message (send email)
namespace GmailAPIApp
{
class SendMail
{
static string[] Scopes = { GmailService.Scope.GmailSend };
static string ApplicationName = "Gmail API .NET Quickstart";
static void Main(string[] args)
{
UserCredential credential;
using (var stream =
new FileStream("credentials_dev.json", FileMode.Open,
FileAccess.Read))
{
string credPath = "token_Send.json";
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
// Create Gmail API service.
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
// Define parameters of request.
string plainText = "To:[email protected]\r\n" +
"Subject: Gmail Send API Test\r\n" +
"Content-Type: text/html; charset=us-ascii\r\n\r\n" +
"<h1>TestGmail API Testing for sending <h1>";
var newMsg = new Google.Apis.Gmail.v1.Data.Message();
newMsg.Raw = SendMail.Base64UrlEncode(plainText.ToString());
service.Users.Messages.Send(newMsg, "me").Execute();
Console.Read();
}
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("=", "");
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With