问题
Let's say my email a@company.com
is in the google group which has email address group@company.com
. We have a g suite service account which has enabled Google Apps Domain-wide Delegation.
We have emails send from b@companyb.com
to our group email group@company.com
, have subject Report from company b
and attach the report in the email.
The issue is that the gmail api is able to list all messages but not able to list the attachments in each email.
Is there any way to do it?
Here's my code:
// here when I create the client, I use my email address `a@company.com`
using(var client = CreateClient())
{
UsersResource.MessagesResource.ListRequest request = client.Users.Messages.List("me");
request.Q = "from:b@compayb.com AND subject:Report from company b AND has:attachment"
// List messages.
var messageIds = request.Execute().Messages?.Select(m => m.Id) ?? new List<string>();
foreach(var mId in messageIds)
{
// https://developers.google.com/gmail/api/v1/reference/users/messages/attachments/get
Message message = client.Users.Messages.Get("me", messageId).Execute();
IList<MessagePart> parts = message.Payload.Parts;
foreach (MessagePart part in parts)
{
if (!String.IsNullOrEmpty(part.Filename))
{
String attId = part.Body.AttachmentId;
MessagePartBody attachPart = client.Users.Messages.Attachments.Get("me", messageId, 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);
var file = new FileInfo(part.Filename);
File.WriteAllBytes(file.FullName, data);
}
}
}
}
If I forward the mail manually to the same address (so the receiver will be me
), the code downloads the attachment.
I'd appreciate if you can help.
回答1:
I've found the attachments are in the child MessagePart
. So I wrote the recursive method to loop through all Parts to get all attachments.
// List<FileInfo> Files = new List<FileInfo>();
// client is created outside this method
private void GetAttachmentsFromParts(IList<MessagePart> parts, string messageId)
{
if (parts == null) return;
foreach (MessagePart part in parts)
{
if (!String.IsNullOrEmpty(part.Filename))
{
String attId = part.Body?.AttachmentId ?? null;
if(String.IsNullOrWhiteSpace(attId)) continue;
MessagePartBody attachPart = GmailServiceClient.Users.Messages.Attachments.Get("me", messageId, 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);
var file = new FileInfo(part.Filename);
Files.Add(file);
File.WriteAllBytes(file.FullName, data);
}
if((part.Parts?.Count ?? 0) > 0)
GetAttachmentsFromParts(part.Parts, messageId);
}
}
All attachments will be stored in the List<FileInfo> Files
来源:https://stackoverflow.com/questions/53729364/how-to-download-attachment-from-email-sent-to-google-group-mail-address