How to download attachment from email sent to google group mail address
Asked Answered
A

1

1

Let's say my email [email protected] is in the google group which has email address [email protected]. We have a g suite service account which has enabled Google Apps Domain-wide Delegation. We have emails send from [email protected] to our group email [email protected], 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 `[email protected]`
    using(var client = CreateClient())
    {
        UsersResource.MessagesResource.ListRequest request = client.Users.Messages.List("me");

        request.Q = "from:[email protected] 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.

Alys answered 11/12, 2018 at 17:29 Comment(2)
just curious, have you looked at the resful api developers.google.com/gmail/api/v1/reference/users/messages/… Just a thought: perhaps that leads to where it find the same calls in the C# libraryFluorinate
Yes, I have. the code for downloading attachment is from developers.google.com/gmail/api/v1/reference/users/messages/…Alys
A
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

Alys answered 12/12, 2018 at 13:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.