问题
I want read all messages in my gmail account using c# and gmail api.
Can I do this?
I read a lot of articles in Gmail API, but i couldn't read messages.
Also I want to read a body of messages or header.
I will be very glad if someone can help me :)
I use this code snippet:
public static List<Message> ListMessages(GmailService service, String userId)
{
List<Message> result = new List<Message>();
UsersResource.MessagesResource.ListRequest request = service.Users.Messages.List(userId);
do
{
try
{
ListMessagesResponse response = request.Execute();
result.AddRange(response.Messages);
request.PageToken = response.NextPageToken;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
} while (!String.IsNullOrEmpty(request.PageToken));
return result;
}
And this:
foreach (var item in ListMessages(service,"me"))
MessageBox.Show(item.Snippet);
But in a result I have empty message box.
回答1:
Yes you should have no issue doing what you say. I would suggest reading the documentation a bit more.
First you have to authenticate - the following shows how to do this with a service account (more details here https://developers.google.com/gmail/api/auth/web-server)
serviceAccountEmail = primaryLink.serviceEmailAddress;
certificate = new X509Certificate2(AppDomain.CurrentDomain.BaseDirectory + "certs//" + primaryLink.certificate, primaryLink.certificatePassword, X509KeyStorageFlags.Exportable);
try
{
credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
User = z.us.emailAccount,
Scopes = new[] { "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile", "https://mail.google.com/" }
}.FromCertificate(certificate));
if (credential.RequestAccessTokenAsync(CancellationToken.None).Result)
{
gs = new GmailService(
new Google.Apis.Services.BaseClientService.Initializer()
{
ApplicationName = "Example",
HttpClientInitializer = credential
});
}
else
{
throw new Exception("gmail authentication Error.");
}
}
catch (Exception ex)
{
throw ex;
}
ListMessagesResponse respM = reqM.Execute();
if (respM.Messages != null)
{
foreach (Message m in respM.Messages)
{}
}
Once you have the message List you can iterate through the messages and either use a MIME parser or traverse the message structure to get the header, body etc.
There are lots of posts in this forum which go through how to do that.
回答2:
I searched for a full example, without luck, but this is my working example. Based on https://developers.google.com/gmail/api/guides
- Authenticate : https://developers.google.com/gmail/api/auth/web-server
- get ALL emails
- loop through all emails by Id, and request message etc.
here is the code snippet to get the first email's atachments, but you can simply loop over all foundIds to get all emails, and use message.snippet to get body :
List<string> foundIds = new List<string>();
string outputDir = "/EXAMPLE/EXAMPLE/"; // your preferred Dir to save attachments to
List<Google.Apis.Gmail.v1.Data.Thread> resultThread = new List<Google.Apis.Gmail.v1.Data.Thread>();
UsersResource.ThreadsResource.ListRequest requestThread = service.Users.Threads.List("me");
do
{
try
{
ListThreadsResponse responseThread = requestThread.Execute();
resultThread.AddRange(responseThread.Threads);
foreach (var item in responseThread.Threads )
{
foundIds.Add(item.Id);
}
requestThread.PageToken = responseThread.NextPageToken;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
} while (!String.IsNullOrEmpty(requestThread.PageToken));
try
{
Message message = service.Users.Messages.Get("me", foundIds[0]).Execute();
IList<MessagePart> parts = message.Payload.Parts;
foreach (MessagePart part in parts)
{
if (!String.IsNullOrEmpty(part.Filename))
{
String attId = part.Body.AttachmentId;
MessagePartBody attachPart = service.Users.Messages.Attachments.Get("me", foundIds[0], attId).Execute();
// Converting from RFC 4648 base64 to base64url encoding
// see http://en.wikipedia.org/wiki/Base64#Implementations_and_history
String attachData = attachPart.Data.Replace('-', '+');
attachData = attachData.Replace('_', '/');
byte[] data = Convert.FromBase64String(attachData);
File.WriteAllBytes(Path.Combine(outputDir, part.Filename), data);
}
}
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
回答3:
I would suggest taking a look at this article on how to handle the actual response structure. It can be somewhat complex with the way the Gmail API gives the results back to you.
https://sigparser.com/developers/email-parsing/gmail-api/
回答4:
@BlackCat, Your ListMessages looks good. Now, to get the message body, you have to decode MimeType "text/plain" or "text/html". For eg:
public static void GetBody(GmailService service, String userId, String messageId, String outputDir)
{
try
{
Message message = service.Users.Messages.Get(userId, messageId).Execute();
Console.WriteLine(message.InternalDate);
if (message.Payload.MimeType == "text/plain")
{
byte[] data = FromBase64ForUrlString(message.Payload.Body.Data);
string decodedString = Encoding.UTF8.GetString(data);
Console.WriteLine(decodedString);
}
else
{
IList<MessagePart> parts = message.Payload.Parts;
if (parts != null && parts.Count > 0)
{
foreach (MessagePart part in parts)
{
if (part.MimeType == "text/html")
{
byte[] data = FromBase64ForUrlString(part.Body.Data);
string decodedString = Encoding.UTF8.GetString(data);
Console.WriteLine(decodedString);
}
}
}
}
Console.WriteLine("----");
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
}
来源:https://stackoverflow.com/questions/28527711/can-i-read-messages-from-gmail-using-gmail-api-and-c